How to Verify SSH Host Key Fingerprints via Command Line in OpenSSH


2 views

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