When connecting to a server via SSH, you might encounter this security warning:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
This occurs when the stored host key in your ~/.ssh/known_hosts
doesn't match what the server presents. While this can happen legitimately (like when reinstalling a server), it could also indicate a man-in-the-middle attack.
The fingerprint shown in the warning is not a hash of the hostname or IP address. Instead, it's a cryptographic hash of the server's public key. For ECDSA keys, SSH uses SHA-256 by default.
When you initially connect to a server, SSH stores three pieces of information in known_hosts
:
- The hostname/IP
- The key type (ECDSA, RSA, ED25519)
- The public key itself
To manually verify an ECDSA host key fingerprint, you have several options:
Method 1: Using ssh-keyscan
ssh-keyscan -t ecdsa yourserver.com | ssh-keygen -lf -
This will output something like:
256 SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz0123456789+ yourserver.com (ECDSA)
Method 2: Checking with OpenSSL
If you have the public key file (e.g., /etc/ssh/ssh_host_ecdsa_key.pub
on the server):
ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub
Method 3: Server-side Verification
On the server itself, you can check fingerprints of all host keys:
for key in /etc/ssh/ssh_host_*_key; do ssh-keygen -lf $key; done
Your attempt with echo -n ipofthehost | sha256sum
didn't match because:
- The fingerprint is of the public key, not the hostname/IP
- SSH uses a special format for the key fingerprint
- The base64 encoding is applied differently than raw SHA-256
For scripting purposes, you can extract the fingerprint programmatically:
REMOTE_FINGERPRINT=$(ssh-keyscan -t ecdsa yourserver.com 2>/dev/null | \
ssh-keygen -E sha256 -lf - | awk '{print $2}')
KNOWN_FINGERPRINT="SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz0123456789+"
if [ "$REMOTE_FINGERPRINT" != "$KNOWN_FINGERPRINT" ]; then
echo "WARNING: Fingerprint mismatch!"
exit 1
fi
When you know a host key has legitimately changed (like after server reinstallation), you can remove the old entry:
ssh-keygen -R yourserver.com
Or for a specific IP:
ssh-keygen -R 192.168.1.100
- Always verify new host key fingerprints through a secondary channel
- Consider using SSH certificate-based authentication for better host verification
- For critical systems, pre-distribute host keys to clients
- Use
StrictHostKeyChecking yes
in your SSH config for production environments
When you encounter the "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED" message during SSH connection, it's crucial to verify the host key fingerprint before proceeding. This warning appears when the stored host key in your ~/.ssh/known_hosts
doesn't match what the server presents.
The fingerprint shown in the warning message is a SHA-256 hash of the server's public key, not the hostname or IP address. The format is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx/xxxxxxx
Here are reliable methods to check the server's ECDSA key fingerprint:
Method 1: Using ssh-keyscan
This command retrieves the host key directly:
ssh-keyscan -t ecdsa yourhost.com | ssh-keygen -lf -
Example output:
256 SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx/xxxxxxx yourhost.com (ECDSA)
Method 2: Manual Verification on Server
If you have console access to the server, check the key file directly:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub
Method 3: Compare with Known Good Fingerprint
For cloud providers like AWS, you can often find the expected fingerprint in your cloud console or API:
aws ec2 get-console-output --instance-id i-xxxxxxxx --output text | grep 'ECDSA'
If you've intentionally changed the server's host key (like after OS reinstall), you can remove the old entry:
ssh-keygen -R hostname_or_ip
Or edit ~/.ssh/known_hosts
manually to remove the specific line mentioned in the error.
- Always verify fingerprints when connecting to a server for the first time
- Consider using SSH certificate-based authentication for better security
- For critical systems, maintain a record of expected fingerprints
For scripts or CI/CD pipelines, you can use this approach:
#!/bin/bash
KNOWN_FINGERPRINT="SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxx/xxxxxxx"
CURRENT_FINGERPRINT=$(ssh-keyscan -t ecdsa yourhost.com 2>/dev/null | ssh-keygen -lf - | awk '{print $2}')
if [ "$KNOWN_FINGERPRINT" != "$CURRENT_FINGERPRINT" ]; then
echo "Fingerprint verification failed!"
exit 1
fi