When automating SSH connections or scripting deployments, you often need to verify server identities without interactive prompts or pre-populated known_hosts
files. While tools like WinSCP offer -hostkey
parameters, OpenSSH's native client requires a different approach.
OpenSSH doesn't provide direct command-line fingerprint specification like some GUI clients. Instead, we use these methods:
# Method 1: Pre-populate known_hosts
ssh-keyscan -H your.server.com >> ~/.ssh/known_hosts
# Method 2: Strict hostkey checking with fingerprint verification
ssh -o "StrictHostKeyChecking=accept-new" \
-o "HostKeyAlias=server-alias" \
user@host
For strict production environments, consider these patterns:
#!/bin/bash
EXPECTED_FINGERPRINT="SHA256:AbCdEf123..."
ACTUAL_FINGERPRINT=$(ssh-keyscan -p 22 host.example.com 2>/dev/null | ssh-keygen -lf -)
if [ "$EXPECTED_FINGERPRINT" = "$ACTUAL_FINGERPRINT" ]; then
ssh -o "StrictHostKeyChecking=yes" user@host.example.com
else
echo "Fingerprint verification failed!" >&2
exit 1
fi
When direct fingerprint verification isn't possible:
- Use SSH certificates instead of host keys
- Deploy via configuration management tools (Ansible/Puppet)
- Create temporary known_hosts files for batch operations
When connecting to a remote server via SSH, OpenSSH automatically checks the server's host key against the ~/.ssh/known_hosts
file. This security feature prevents man-in-the-middle attacks, but presents challenges in automation scenarios where:
- You can't modify the user's
known_hosts
file - You don't want to blindly accept new keys (
StrictHostKeyChecking=no
) - You need to specify the expected fingerprint programmatically
While OpenSSH doesn't offer a direct command-line parameter like WinSCP's -hostkey
, you can achieve similar security through these methods:
Method 1: Using SSH-keyscan with Verification
# First, get the actual fingerprint
ACTUAL_FP=$(ssh-keyscan -t rsa HOSTNAME 2>/dev/null | ssh-keygen -lf -)
# Compare with expected fingerprint
EXPECTED_FP="SHA256:ABC123...xyz"
if [ "$ACTUAL_FP" != "$EXPECTED_FP" ]; then
echo "Host key verification failed!"
exit 1
fi
# Proceed with connection
ssh user@HOSTNAME
Method 2: Temporary known_hosts File
# Create temporary known_hosts with your fingerprint
echo "HOSTNAME ssh-rsa AAAAB3NzaC1yc2E..." > /tmp/known_hosts
# Connect with custom known_hosts
ssh -o UserKnownHostsFile=/tmp/known_hosts \
-o StrictHostKeyChecking=yes \
user@HOSTNAME
For complex scenarios, create an SSH config entry:
Host myserver
HostName server.example.com
User myuser
Match exec "grep -q '^server.example.com' ~/approved_hosts"
StrictHostKeyChecking yes
UserKnownHostsFile ~/approved_hosts
When implementing these solutions:
- Always use SHA256 fingerprints (more secure than MD5)
- Store expected fingerprints securely (not in scripts)
- Consider certificate-based authentication for large deployments
- Never disable host key checking completely