Host-based authentication allows one server to authenticate to another based on the client machine’s host key, rather than user keys. This is particularly useful in enterprise environments where you have trusted servers that need automated, passwordless communication.
Warning
Important: Host-based authentication should only be used in controlled environments where you trust the client machines completely. It’s not a replacement for user key authentication, but a complement for specific use cases.
When to Use Host-Based Authentication
I use host-based authentication in these scenarios:
- Automated backup systems pulling data from multiple servers
- Configuration management systems (Ansible, Puppet)
- Monitoring systems that need to execute remote commands
- Database replication between trusted servers
- CI/CD pipelines deploying to production
Architecture Overview
Host-based authentication works like this:
- Client machine has a host key pair in
/etc/ssh/ - Server trusts specific client hostnames
- During connection, client proves its identity using the host key
- Server verifies the hostname and host key match
Prerequisites
- Root access on both client and server
- Proper DNS or
/etc/hostsentries for hostname resolution - Network trust between machines
Step 1: Enable Host-Based Authentication on Server
Edit /etc/ssh/sshd_config on the server (the machine being connected to):
sudo nano /etc/ssh/sshd_configAdd or modify these settings:
# Enable host-based authenticationHostbasedAuthentication yes
# Trust user@host combinations (more secure)HostbasedUsesNameFromPacketOnly yes
# Require both user key and host-based auth (optional, very secure)# AuthenticationMethods publickey,hostbased
# Accept these key types for host authenticationHostbasedAcceptedKeyTypes ssh-ed25519,rsa-sha2-512,rsa-sha2-256
# Don't ignore rhosts (needed for host-based auth)IgnoreRhosts no
# Still require proper user mappingIgnoreUserKnownHosts noRestart SSH:
sudo systemctl restart sshdStep 2: Configure Trusted Hosts on Server
Create or edit /etc/ssh/shosts.equiv on the server:
sudo nano /etc/ssh/shosts.equivAdd trusted hostnames (one per line):
# Format: hostname [username]backup-server.example.com deployermonitoring.example.com monitorci-runner-01.example.com jenkinsSet proper permissions:
sudo chmod 600 /etc/ssh/shosts.equivsudo chown root:root /etc/ssh/shosts.equivAlternative per-user configuration:
# User-specific trusted hostsnano ~/.shosts
# Add trusted hostsbackup-server.example.commonitoring.example.comStep 3: Configure Client Machine
On the client machine (the one initiating connections), edit /etc/ssh/ssh_config or ~/.ssh/config:
sudo nano /etc/ssh/ssh_configAdd these settings:
# Enable host-based authenticationHostbasedAuthentication yes
# Send local hostnameEnableSSHKeysign yes
# Prefer host-based authPreferredAuthentications hostbased,publickey,passwordStep 4: Configure SSH Keysign
The ssh-keysign program must be setuid root to access host keys:
# Verify ssh-keysign locationwhich ssh-keysign# Usually: /usr/lib/openssh/ssh-keysign or /usr/libexec/openssh/ssh-keysign
# Set proper permissionssudo chmod 4711 /usr/lib/openssh/ssh-keysign# orsudo chmod 4711 /usr/libexec/openssh/ssh-keysignStep 5: Distribute Host Public Keys
On the client machine, find the host public key:
# Usually ssh_host_ed25519_key.pub or ssh_host_rsa_key.pubsudo cat /etc/ssh/ssh_host_ed25519_key.pubCopy this key to the server’s known hosts file:
# On the serversudo nano /etc/ssh/ssh_known_hostsAdd an entry in this format:
# Format: hostname,ip key-type public-keybackup-server.example.com,192.168.1.10 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILo...monitoring.example.com,192.168.1.20 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIXy...Set proper permissions:
sudo chmod 644 /etc/ssh/ssh_known_hostssudo chown root:root /etc/ssh/ssh_known_hostsStep 6: Test Host-Based Authentication
From the client machine, test the connection:
# Test with verbose output
# Look for this in the output:# "Offering public key: /etc/ssh/ssh_host_ed25519_key"# "Server accepts key: /etc/ssh/ssh_host_ed25519_key"# "Authentication succeeded (hostbased)"Automation Script for Multiple Clients
I use this script to distribute host keys from multiple clients to a central server:
Save as /usr/local/bin/distribute-host-keys.sh on the server:
#!/bin/bash# Collect and distribute host keys for host-based authentication
KNOWN_HOSTS="/etc/ssh/ssh_known_hosts"TEMP_KEYS="/tmp/host_keys_collection.txt"
# List of client machinesCLIENTS=( "backup-server.example.com" "monitoring.example.com" "ci-runner-01.example.com")
echo "Collecting host keys from client machines..."> $TEMP_KEYS
for client in "${CLIENTS[@]}"; do echo "Fetching key from $client..."
# Get hostname and IP IP=$(dig +short $client | tail -1)
# Fetch the host key KEY=$(ssh-keyscan -t ed25519 $client 2>/dev/null)
if [ -n "$KEY" ]; then # Format: hostname,ip key-type key echo "$client,$IP $(echo $KEY | awk '{print $2, $3}')" >> $TEMP_KEYS echo " ✓ Key collected from $client" else echo " ✗ Failed to get key from $client" fidone
# Backup existing known_hostsif [ -f $KNOWN_HOSTS ]; then cp $KNOWN_HOSTS ${KNOWN_HOSTS}.backup.$(date +%F)fi
# Add new keyscat $TEMP_KEYS >> $KNOWN_HOSTS
# Remove duplicates and sortsort -u $KNOWN_HOSTS -o $KNOWN_HOSTS
# Set permissionschmod 644 $KNOWN_HOSTS
echo "Host keys distributed successfully!"echo "Backup saved to ${KNOWN_HOSTS}.backup.$(date +%F)"Make it executable:
sudo chmod +x /usr/local/bin/distribute-host-keys.shsudo /usr/local/bin/distribute-host-keys.shSecurity Considerations
Pros:
- No credential management for automated processes
- Host identity verification
- Useful for trusted server-to-server communication
Cons:
- If client machine is compromised, attacker gains access
- Harder to audit than user-based authentication
- Requires careful hostname management
Best Practices I Follow:
- Use with User Keys: Combine with publickey authentication:
AuthenticationMethods publickey,hostbased-
Limit to Specific Commands: Use
command=in authorized_keys for restriction -
Network Segmentation: Only allow host-based auth from trusted network segments
-
Regular Audits: Review
/etc/ssh/shosts.equivmonthly -
Logging: Ensure verbose logging to track host-based authentications:
LogLevel VERBOSE- Firewall Rules: Restrict SSH access to only trusted client IPs
Monitoring Host-Based Authentications
Add to your monitoring script:
# Check for host-based authentication attemptsecho "Host-Based Authentications:" >> $REPORT_FILEgrep "hostbased" /var/log/auth.log | tail -20 >> $REPORT_FILEecho "" >> $REPORT_FILETroubleshooting
Connection fails with “Permission denied”:
- Check server logs:
sudo journalctl -u sshd -n 50 | grep hostbased- Verify hostname resolution:
# On server hostname -f # Should match what's in shosts.equiv- Check ssh-keysign permissions:
ls -l /usr/lib/openssh/ssh-keysign # Should be: -rws--x--x (4711)- Verify host key on server:
sudo grep "$(hostname)" /etc/ssh/ssh_known_hostsDebug mode:
# On client, test with maximum verbosityssh -vvv -o PreferredAuthentications=hostbased user@serverRevoking Host Access
To revoke a client’s access:
- Remove from
/etc/ssh/shosts.equiv:
sudo nano /etc/ssh/shosts.equiv # Delete the line with the hostname- Remove from
/etc/ssh/ssh_known_hosts:
sudo ssh-keygen -R hostname.example.com -f /etc/ssh/ssh_known_hosts- Restart SSH:
sudo systemctl restart sshdReal-World Example: Backup Server Setup
Here’s how I configure a backup server to pull data from multiple production servers:
On production servers (/etc/ssh/sshd_config):
HostbasedAuthentication yesMatch User backup HostbasedAuthentication yes PasswordAuthentication no AllowUsers backupOn production servers (/etc/ssh/shosts.equiv):
backup-server.example.com backupOn backup server (/etc/ssh/ssh_config):
Host prod-* HostbasedAuthentication yes PreferredAuthentications hostbased User backupNow the backup server can automatically connect:
rsync -avz prod-web-01:/var/www/ /backup/web-01/Next Steps
Proceed to the Security Monitoring guide to implement fail2ban, connection management, and comprehensive log analysis for your hardened SSH setup.