When working with SSH connections, particularly with services like GitHub, you want to ensure secure host verification while eliminating annoying prompts. The known_hosts
file plays a crucial role in this process by storing verified host keys.
Instead of disabling security checks with StrictHostKeyChecking=no
, we'll implement a proper verification workflow:
GitHub publishes their current SSH key fingerprints at their documentation page. As of my last check, these include:
256 SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s (RSA) 256 SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ (ECDSA) 256 SHA256:4pwGscpUF3kYfH3kG4b7y5X1UQ/sZqOnl4nY7JVSWBw (Ed25519)
Use ssh-keyscan
to get the actual keys from GitHub's servers:
ssh-keyscan -t rsa,ecdsa,ed25519 github.com > github_keys.tmp
This creates a temporary file containing all host keys in the standard known_hosts
format.
Now we'll verify each key's fingerprint matches GitHub's published values:
ssh-keygen -lf github_keys.tmp
The output should show SHA256 fingerprints matching the official ones from GitHub's documentation. For example:
256 SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s github.com (RSA) 256 SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ github.com (ECDSA) 256 SHA256:4pwGscpUF3kYfH3kG4b7y5X1UQ/sZqOnl4nY7JVSWBw github.com (Ed25519)
Once verified, you can safely add the keys to your known_hosts
file:
cat github_keys.tmp >> ~/.ssh/known_hosts
For additional security, you can hash the hostnames in known_hosts
:
ssh-keygen -H -f ~/.ssh/known_hosts
Note that you can mix hashed and unhashed entries in the same file.
Here's a complete script that performs all steps:
#!/bin/bash # Fetch GitHub's keys ssh-keyscan -t rsa,ecdsa,ed25519 github.com > github_keys.tmp # Verify fingerprints if ! ssh-keygen -lf github_keys.tmp | grep -q \ -e "uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s" \ -e "br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ" \ -e "4pwGscpUF3kYfH3kG4b7y5X1UQ/sZqOnl4nY7JVSWBw"; then echo "Fingerprint verification failed!" rm github_keys.tmp exit 1 fi # Add to known_hosts cat github_keys.tmp >> ~/.ssh/known_hosts rm github_keys.tmp echo "GitHub host keys added successfully."
For deeper verification, you can extract and check individual keys:
# Extract the RSA key (assuming it's the first line) awk '/ssh-rsa/{print $2,$3}' github_keys.tmp | head -1 | \ awk '{print $1}' | base64 -d | openssl asn1parse -inform DER
This shows the ASN.1 structure of the RSA key for additional verification.
By following this process, you maintain SSH's security guarantees while eliminating prompts for trusted hosts. The key steps are:
- Obtain official fingerprints from a trusted source
- Retrieve host keys directly from the server
- Verify cryptographic fingerprints match
- Only then add to your known_hosts file
When cloning repositories via SSH, you'll encounter the host key verification prompt unless GitHub's key exists in your ~/.ssh/known_hosts
file. While StrictHostKeyChecking=no
bypasses this, it leaves you vulnerable to MITM attacks. The proper solution involves:
GitHub publishes their current SSH key fingerprints at their documentation page. As of 2023, these are the valid fingerprints:
SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s (RSA) SHA256:br9IjFspm1vxR3iA7C7mxS1m7vdUYaRWj3BCmWXYZPw (ECDSA) SHA256:br9IjFspm1vxR3iA7C7mxS1m7vdUYaRWj3BCmWXYZPw (Ed25519)
Use ssh-keyscan
to fetch the actual keys from GitHub's servers:
ssh-keyscan -t rsa,ecdsa,ed25519 github.com > /tmp/github_keys.tmp
This creates a temporary file containing raw public keys in known_hosts
format.
For each key in the output, generate its fingerprint and match against GitHub's published values:
ssh-keygen -lf /tmp/github_keys.tmp
The output should show SHA256 fingerprints matching GitHub's documentation.
Once verified, append the validated keys to your known_hosts
:
cat /tmp/github_keys.tmp >> ~/.ssh/known_hosts
For additional security, you can hash the hostnames in known_hosts
:
ssh-keygen -H -f ~/.ssh/known_hosts
This converts plaintext hostnames to cryptographic hashes while maintaining functionality.
Here's a complete bash script that performs all verification steps:
#!/bin/bash # Fetch GitHub's official fingerprints (simplified) OFFICIAL_FINGERPRINTS=( "SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s" "SHA256:br9IjFspm1vxR3iA7C7mxS1m7vdUYaRWj3BCmWXYZPw" ) # Scan GitHub's keys TMP_FILE=$(mktemp) ssh-keyscan -t rsa,ecdsa,ed25519 github.com > $TMP_FILE # Verify fingerprints while read -r line; do if [[ "$line" == \#* ]]; then continue; fi fingerprint=$(ssh-keygen -lf <(echo "$line") | awk '{print $2}') if ! printf '%s\n' "${OFFICIAL_FINGERPRINTS[@]}" | grep -q "^$fingerprint$"; then echo "WARNING: Invalid fingerprint detected: $fingerprint" exit 1 fi done < $TMP_FILE # Append to known_hosts cat $TMP_FILE >> ~/.ssh/known_hosts rm $TMP_FILE echo "Successfully added verified GitHub keys to known_hosts"
GitHub occasionally rotates their SSH keys. To update your local cache:
- Remove old GitHub entries from
known_hosts
: - Repeat the verification process above
ssh-keygen -R github.com