SSH Frequently Asked Questions
How do I get trusted-host (SSH-2 "hostbased", SSH-1 "RhostsRSA") authentication working?
Note that OpenSSH support for hostbased authentication in protocol 2 did not appear until version 2.9.
In trusted-host authentication, the SSH server does not directly authenticate a user based on something he knows or has (e.g. password or private key). Rather, it authenticates the client host, and then trusts that host to say who the user is (i.e., which client-side account he has already been authenticated to use). It then consults server-side configuration (e.g. /etc/shosts.equiv or ~/.shosts) to determine which account names on the client host are allowed access to which server accounts. So, this mechanism actually delegates responsibility for user authentication to the client host — and hence, compromise of a client means immediate transitive compromise of corresponding accounts on the server.
Since the client software is being specially trusted, for Unix implementations this generally means that some part of it needs to be setuid/setgid, in order to read the client's private host key. Most installations make the host private key readable only by root, and thus the software must be setuid root. However, this is not an requirement; a configuration could also work using a non-privileged user or group to gate access to the private key. This would actually be preferable, since there is no need to give the SSH client software any of root's special privileges.
An exception to this occurs in some older SSH software. The original SSH1 trusted-host method ("RhostsRSA") mimicked its namesake rhosts method in using a "trusted source port:" it required the source TCP port of the client's network connection to be in the range [1,1023]. By convention, only privileged Unix processes are allowed to bind these ports, and so this was used as a test of the trustworthiness of the client software. In SSH, however, this test is both unnecessary and harmful: access to the client host key is a sufficient (and superior) way to verify client trust, and requiring root privilege is a danger best avoided if possible. The trusted source port requirement was never present in SSH2, and was dropped in OpenSSH with version 2.5.1. It is still present in SSH1, since that code now receives only bugfix maintenance.
- In SSH1 and OpenSSH(<3.4), the ssh program must be setuid
root. SSH2 and OpenSSH(>=3.4) follow better security engineering practice
and factor the trusted functionality out into a separate small
program ssh-signer2 or ssh-keysign. In SSH2, this
program is always used for hostbased authentication and must be setuid.
OpenSSH can use either the older method of a setuid ssh program,
or ssh-keysign; this is controlled by the
EnableSSHKeysign variable. If ssh-keysign is used, it
must be setuid. As noted above, "setuid root" might be replaced with
setuid/setgid to a different user/group.
- Turn on strong trusted-host authentication in the server and client.
- (SSH1, OpenSSH/1) "RhostsRSAAuthentication yes"
- (OpenSSH/2) "HostbasedAuthentication yes"
- (SSH2) "AllowedAuthentications hostbased"
Note that we said server and client. Hostbased authentication is turned off by default in SSH2 and OpenSSH/2, meaning that the client will not try that method even if the server offers it. (The OpenSSH-2.9 ssh man page incorrectly states that HostbasedAuthentication is on by default.)
Also note that order is significant for the client-side setting of
AllowedAuthentications; the client will try the listed methods in the listed order. Usually, you want this order:
- The client's public host key must be in the server's known-hosts
list. The known-hosts list is a combination of a global list, plus any
entries present in the per-user known-hosts list of the target account
(unless per-user known-hosts lists have been turned off in the server).
In SSH2, the public keys of the known hosts are in separate files in a
directory, as opposed to being entries in a single file.
public host key(s) global known-hosts per-user known-hosts (target account) SSH1, OpenSSH/1
Take care that you use the canonical name of the client host from the server's point of view, when adding the client host's public key to the server's known-hosts list. That is, if the SSH connection is coming from the address 192.168.10.1, then you want the result of doing
gethostbyname(192.168.10.1)on the server. Note that this can involve multiple naming services, since
gethostbynamecan be configured to consult multiple sources to determine a translation (e.g. DNS, NIS, /etc/hosts). See /etc/nsswitch.conf.
With OpenSSH/2, you can relax this restriction somewhat by setting
HostbasedUsesNameFromPacketOnly yesin the server. This means that sshd uses the self-identifying hostname supplied by the client in its hostbased authentication request, to look up the client's public host key for verification. Otherwise (and by default), sshd will use the result of a reverse name lookup on the client's IP address instead (and in addition log a warning if this does not match the client-supplied name).
SSH2, on the other hand, is more restrictive. The client-supplied and network-derived client host names must match, or the server will refuse hostbased authentication. This means that SSH2 hostbased authentication will often not work in through a proxy, or in situations with roaming hosts with changing IP addresses, incorrect or absent reverse DNS names, etc.
See some further discussion of this issue.
- Authorize server accounts for trusted-host logins. For instance, placing the hostname betty.rubble.net in /etc/shosts.equiv would allow all users on betty access to accounts with the same username on the server. Placing it instead in in ~barney/.shosts would allow barney@betty access to this one account. And placing firstname.lastname@example.org in this .shosts file would allow the user fred@betty access to the barney account.
- If you are using per-user .shosts files, check the permissions on the home directory and the file itself: with default SSH server settings, they must both be writable only by the owner.
- Some firewalls do not allow outbound connections from privileged ports. This prevents RhostsRSA authentication from working, since it relies on using privileged source ports; the symptom is that the client cannot even connect to the SSH server. It's confusing, because if you test it via "telnet server 22", that will work because telnet is not originating the connection from a privileged port. If ssh -P connects, then that's the problem.
- Trusted-host authentication will not work through a proxy (e.g. if
you're using SOCKS). This problem is inherent in SSH-1. In the SSH-2
design it can work, but the ssh.com SSH2 implementation specifically
prevents it. In OpenSSH/2, set
HostbasedUsesNameFromPacketOnly yesto allow it.