How to Automatically Add SSH Host Keys to known_hosts Without Manual Verification Prompt


2 views

When automating remote operations via SSH (like rsync scripts), the initial host key verification prompt breaks automation workflows. The standard message looks like:

The authenticity of host '[hostname] ([IP address])' can't be established.
RSA key fingerprint is SHA256:AbCdEfGh...123456.
Are you sure you want to continue connecting (yes/no)?

While ssh-keyscan is the go-to solution, several factors can cause it to fail:

  • DNS resolution differences between client and server
  • Host key algorithms mismatch (RSA vs ECDSA vs Ed25519)
  • Hash-based hostname storage in known_hosts (-H flag behavior)
  • Port/protocol variations (non-standard SSH ports)

1. Comprehensive Host Key Collection

Try capturing all possible key types and representations:

ssh-keyscan -t rsa,ecdsa,ed25519 hostname,ip_address >> ~/.ssh/known_hosts
ssh-keyscan -t rsa,ecdsa,ed25519 hostname >> ~/.ssh/known_hosts
ssh-keyscan -t rsa,ecdsa,ed25519 ip_address >> ~/.ssh/known_hosts

2. Strict Host Key Checking Override

For temporary automation (not recommended for production):

ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@hostname true

3. Manual Key Injection with Verification

When security is critical, pre-verify and inject keys:

# Get fingerprint from trusted source
REMOTE_FINGERPRINT="SHA256:AbCdEfGh...123456"

# Verify before adding
if ssh-keyscan hostname | ssh-keygen -lf - | grep -q "$REMOTE_FINGERPRINT"; then
   ssh-keyscan hostname >> ~/.ssh/known_hosts
fi

When troubleshooting:

# Check what SSH client sees
ssh -vvv user@hostname

# Compare key hashes
diff <(ssh-keyscan -H hostname | cut -d' ' -f2-) <(grep hostname ~/.ssh/known_hosts | cut -d' ' -f2-)

For enterprise environments, consider:

#!/bin/bash
set -eo pipefail

HOST="example.com"
IP="192.0.2.1"
KNOWN_HOSTS="$HOME/.ssh/known_hosts"
TMP_FILE=$(mktemp)

# Collect all possible keys
{
  ssh-keyscan -t rsa,ecdsa,ed25519 "$HOST"
  ssh-keyscan -t rsa,ecdsa,ed25519 "$IP"
  ssh-keyscan -t rsa,ecdsa,ed25519 "$HOST,$IP"
} > "$TMP_FILE"

# Verify at least one key was captured
if [ ! -s "$TMP_FILE" ]; then
  echo "ERROR: No keys collected from $HOST"
  exit 1
fi

# Append to known_hosts only if verification succeeds
if ssh-keygen -lf "$TMP_FILE"; then
  cat "$TMP_FILE" >> "$KNOWN_HOSTS"
  echo "Successfully added keys for $HOST"
fi

rm "$TMP_FILE"

Remember to always verify host keys in security-sensitive environments, and consider using SSH certificates for large-scale deployments.


When automating SSH connections in scripts (like rsync setups), the host key verification prompt becomes a major roadblock:

The authenticity of host '[hostname] ([IP address])' can't be established.
RSA key fingerprint is [key fingerprint].
Are you sure you want to continue connecting (yes/no)?

The standard approach using ssh-keyscan can fail for several technical reasons:

  • Hash format mismatch (-H flag vs non-hashed entries)
  • DNS resolution differences between manual and automated runs
  • Multiple key types (RSA/ECDSA/Ed25519) not being captured

Method 1: Comprehensive Keyscan Approach

ssh-keyscan -t rsa,ecdsa,ed25519 [hostname] [ip_address] >> ~/.ssh/known_hosts

Key differences from basic approach:

  • Explicitly specifies all key types
  • Captures both hostname and IP entries
  • Omits -H to match typical known_hosts format

Method 2: Strict Host Checking Alternative

For environments where host keys change frequently:

echo "Host [hostname]
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null" >> ~/.ssh/config

Warning: Only use this in trusted networks as it disables security verification.

Method 3: Complete Automation Script

Here's a robust Bash implementation:

#!/bin/bash
HOST="example.com"
IP="192.0.2.1"

# Remove any existing entries
ssh-keygen -R "$HOST"
ssh-keygen -R "$IP"

# Add new entries with all key types
{
    ssh-keyscan -t rsa "$HOST","$IP"
    ssh-keyscan -t rsa "$IP"
    ssh-keyscan -t rsa "$HOST"
    ssh-keyscan -t ecdsa "$HOST","$IP"
    ssh-keyscan -t ed25519 "$HOST","$IP"
} >> ~/.ssh/known_hosts 2>/dev/null

# Verify entry exists
if grep -q "$HOST" ~/.ssh/known_hosts; then
    echo "Host key successfully added"
else
    echo "Failed to add host key" >&2
    exit 1
fi

When troubleshooting:

  1. Check file permissions: chmod 600 ~/.ssh/known_hosts
  2. Compare manual vs automated output formats
  3. Test with ssh -v to see exact verification process

Remember that automating host key verification reduces security. Best practices include:

  • Pre-loading known host keys in your CI/CD pipeline
  • Using certificate-based authentication where possible
  • Regularly auditing your known_hosts file