Host-based authentication allows hosts to authenticate on behalf of all or some of the system's users. It can apply to all users on a system or a subset using the Match directive. This type of authentication can be useful for managing computing clusters and other fairly homogenous pools of machines.
In all, three files on the server and one on the client must be modified to prepare for host-based authentication.
Server Configuration for host-based authentication
Three files on the server or target host must be modified to get host-based authentication working:
- /etc/ssh/shosts.equiv - same syntax as old rhosts.equiv, can point to netgroups
- /etc/ssh/ssh_known_hosts - hold the identities of the clients
- /etc/ssh/sshd_config - turn on host-based authentication
The /etc/ssh/shosts.equiv identifies which addresses are allowed to try authenticating. The file can contain hostnames, IP addresses, or netgroups.
Best to keep this file simple and oriented to just the list of hosts, either by name or IP number. It provides only the first cut, anyway. For fine tuning, use sshd_config(5) to set or revoke access for specific users and groups.
client1.example.org 192.0.2.102 client8.example.org -bull @statcluster
Two more files may optionally be modified, if they are referred to from within shosts.equiv. Each line in the netgroup file consists of a net group name followed by a list of the members of the net group, specifically host, user, and domain.
/etc/netgroup default netgroup list /etc/netgroup.db netgroup database, build from netgroup
However, these are mostly legacy from the old rhosts and can be avoided.
Those hosts listed in the server's shosts.equiv must also have their public keys in /etc/ssh/ssh_known_hosts on the server to be acknowledged. There are three required data fields per line. First is the host name or IP address or comma separated list of them, corresponding to those from shosts.equiv. Next is the key type, either ssh-rsa for RSA keys or ssh-dss for DSA keys. Third is the public key itself. Last, and optionally, can be a comment about the key.
desktop,192.0.2.102 ssh-rsa AAAAB3NzaC1yc2EAAAABIw ... qqU24CcgzmM=
There are many ways of collecting the public key information. It can be copied using sftp(1), copied from ~/.ssh/known_hosts or it can be grabbed using ssh-keyscan(1). Though the latter two only work if the client host also has an SSH server running.
$ ssh-keyscan -t rsa client.example.org >> /etc/ssh/ssh_known_hosts
If it is not possible for there to be a valid DNS entry resolving the hostname and address of the client, then it might be necessary to use a work-around to make up for that lack. One choice is to use or set up a local name service using dnsmasq or some other easy option. Or another choice is to set sshd(8) to accept the hostname information provided in the connection itself as being what it claims to be. See the HostbasedUsesNameFromPacketOnly directive for sshd_config below.
The third file that must be changed on the server is sshd_config. It must be told to allow host-based authentication. That is done using the HostbasedAuthentication directive, either for all users or just some users or groups.
Host-based authentication can be limited to specific users or groups. Here is an example excerpt from sshd_config allowing allow any user in the group turtles to let the hosts authenticate on their behalf:
Match Group turtles HostbasedAuthentication yes
If the client machine is not listed in DNS, then the server might have trouble recognising it. In that case you might have to tell sshd(8) not to do reverse lookups in DNS for connecting hosts. Excerpt from /etc/ssh/sshd_config to work around lack of DNS records for the client using the HostbasedUsesNameFromPacketOnly directive.
HostbasedAuthentication yes HostbasedUsesNameFromPacketOnly yes
Sometimes the host connecting gets identified to the target host as something other than what was expected. So make sure that the configuration files match what the host is actually calling itself.
Local user host-based authentication
The list of allowed hosts can be either local for the user or global. Individual users can have a local .shosts containing a list of trusted remote machines, or user-machine pairs, which are allowed to try host-based authentication.
.shosts must not writable by any group or any other users. Permissions set to 0644 should do it. The usage and format of .shosts is exactly the same as .rhosts, but allows host-based authentication without permitting login by insecure, legacy tools rlogin and rsh. The list is one line per host. The first column is obligatory and contains the name or address of the host permitted to attempt host-based authentication.
The second column is optional contains either a user name or netgroup name. But the user name checks using this method are not secure and restricting which specific users or groups may authenticate should be configured in sshd_config instead by using the Match Group directive.
See the manual page hosts.equiv(5) for more details on .shosts.
Client Configuration for Host-based Authentication
On the client or source host, a single file must be configured:
- /etc/ssh/ssh_config - allow clients to request host-based authentication
There two changes are needed. The OpenSSH client's configuration must request host-based authentication when connecting, either for all hosts or for specific ones. Also, the global OpenSSH client configuration file must be set to enable ssh-keysign(8). It is a helper application to access the local host keys and generate the digital signature required for host-based authentication. The EnableSSHKeysign configuration must be done globally in /etc/ssh/ssh_config. The program ssh-keysign(8) itself must be SUID root, but that was probably set when it was installed and no changes there are needed.
Here is an excerpt from /etc/ssh/ssh_config on the client trying host-based authentication to all machines:
Host * HostbasedAuthentication yes EnableSSHKeysign yes
Note that the Host directive in ssh_config(5) can be used to further constrain access, and other configuration specifics, to a particular server or group of servers.
Host *.pool.example.org HostbasedAuthentication yes EnableSSHKeysign yes
If the home directory of the client host is one that is shared with other machines, say using NFS or AFS, then it may be useful to look at the NoHostAuthenticationForLocalhost directive, too.
Further, at least one of the following files must exist and contain the appropriate private key. The private key used should match the public key stored in the server or target host's ssh_known_hosts file. Any of the three types can be used, RSA, DSA or ECDSA.
The program ssh-keysign(8) needs to read the client host's private keys in /etc/ssh/. It is enough to have the keys by themselves, or at least one key. If the client host's private key does not exist, it will be necessary to add one manually before host-based authentication will work. The easy way to add the key is to install the OpenSSH server. These keys are then created automatically when the package containing sshd(8) is installed. Note that the client's machine does not have to have an SSH server actually running in order to use host-based authentication. So it is entirely feasible to install but then disable or uninstall the SSH server on the client's machine just to get the host keys in place.
Configuration should be quite straight forward, with small changes in only three files, plus a key, to manage. If there are difficulties, be prepared to run sshd(8) standalone at debug level 1 (-d) to 3 (-ddd) and ssh(1) at debug level 3 (-vvv) a few times to see what you missed. The mistakes have to be cleared up in the right order, so take it one step at a time.
Here is a sample excerpt from a successful host-based authentication for user fred from the host at 192.0.2.102, also known as desktop1, using an RSA key.
# /usr/sbin/sshd -ddd debug2: load_server_config: filename /etc/ssh/sshd_config ... debug3: /etc/ssh/sshd_config:39 setting HostbasedAuthentication yes ... debug1: sshd version OpenSSH_6.2, OpenSSL 1.0.1e 11 Feb 2013 ... debug1: userauth-request for user fred service ssh-connection method hostbased [preauth] debug1: attempt 1 failures 0 [preauth] debug2: input_userauth_request: try method hostbased [preauth] debug1: userauth_hostbased: cuser fred chost desktop1. pkalg ssh-dss slen 55 [preauth] ... debug2: userauth_hostbased: chost desktop1. resolvedname 192.0.2.102 ipaddr 192.0.2.102 debug2: stripping trailing dot from chost desktop1. userauth_hostbased mismatch: client sends desktop1, but we resolve 192.0.2.102 to 192.0.2.102 debug2: auth_rhosts2: clientuser fred hostname 192.0.2.102 ipaddr 192.0.2.102 ... debug1: Checking blacklist file /usr/share/ssh/blacklist.RSA-2048 debug1: Checking blacklist file /etc/ssh/blacklist.RSA-2048 debug2: userauth_hostbased: chost desktop1. resolvedname 192.0.2.102 ipaddr 192.0.2.102 debug2: stripping trailing dot from chost desktop1. userauth_hostbased mismatch: client sends desktop1, but we resolve 192.0.2.102 to 192.0.2.102 debug2: auth_rhosts2: clientuser fred hostname 192.0.2.102 ipaddr 192.0.2.102 ... debug2: userauth_hostbased: access allowed by auth_rhosts2 debug3: load_hostkeys: loading entries for host "192.0.2.102" from file "/etc/ssh/ssh_known_hosts" debug3: load_hostkeys: found key type RSA in file /etc/ssh/ssh_known_hosts:1 debug3: load_hostkeys: loaded 1 keys ... debug1: check_key_in_hostfiles: key for 192.0.2.102 found at /etc/ssh/ssh_known_hosts:1 Accepted RSA public key 62:25:94:57:22:e3:91:de:68:c9:a5:6f:1a:eb:e0:7a from email@example.com debug3: mm_answer_keyallowed: key 0x7f778fbce2d0 is allowed ... debug1: ssh_rsa_verify: signature correct debug3: mm_answer_keyverify: key 0x7f778fbce2d0 signature verified ... Accepted hostbased for fred from 192.0.2.102 port 41148 ssh2 ...
Note any warnings or error messages and read them carefully.