|
| 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.
Checklist
- 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:
AllowedAuthentications hostbased,publickey,password
- 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 |
/etc/ssh_host_key.pub |
/etc/ssh_known_hosts |
~/.ssh/known_hosts |
| SSH2 |
/etc/ssh2/hostkey.pub |
/etc/ssh2/knownhosts/<client FQDN>.ssh-dss.pub |
~/.ssh2/knownhosts/<client FQDN>.ssh-dss.pub |
| OpenSSH/2 |
/etc/ssh_host_dsa_key.pub /etc/ssh_host_rsa_key.pub |
/etc/ssh_known_hosts2 |
~/.ssh/known_hosts2 |
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 gethostbyname can
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 yes in 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 fred@betty.rubble.net 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.
Common Problems
- 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
yes to allow it.
|