Can You Add Comments to SSH known_hosts File? A Technical Guide for Developers


1 views

Working with SSH connections means regularly interacting with the ~/.ssh/known_hosts file, which stores fingerprints of all hosts you've connected to. For developers managing multiple servers and services, this file can become:

  • Difficult to read with long entries
  • Hard to maintain without context
  • Challenging to debug when entries conflict

The OpenSSH known_hosts format (RFC 4253) defines the file structure as:

[hostname_or_ip] ssh-keytype base64-encoded-key

Example entry:

github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==

While the specification doesn't mention comments, some developers report partial success with:

# This is a test comment
github.com ssh-rsa AAAAB3NzaC...[rest of key]

However, this behavior is inconsistent across SSH implementations and versions. Some clients might:

  • Ignore the comment line completely
  • Fail to parse the file
  • Strip comments during automatic updates

For better known_hosts management:

1. External Documentation

# Maintain a separate hosts-documentation.md file with:
- github.com - Primary code hosting
- 192.168.1.100 - Jenkins build server
- deploy.prod - Production deployment target

2. Hashed Hostnames with Context

When using hashed hostnames (HashKnownHosts yes in ssh_config), maintain a separate mapping:

# ~/ssh_hosts_mapping
|1|JfKT6hHt7s6L7vCvJQ3J2VqZYE=|oNQHSo5XbG7VxHwu0X3xZJdR0= github.com
|1|b7qZl5JtZ5pWkHZ5XkJtZ5pWk=|d5XkJtZ5pWkHZ5XkJtZ5pWk= jenkins.internal

3. Custom Management Script

Create a wrapper script for known_hosts management:

#!/bin/bash
# ssh-host-manager

case "$1" in
    add)
        echo "# Added $(date): $2" >> ~/.ssh/known_hosts.context
        ssh-keyscan $2 >> ~/.ssh/known_hosts
        ;;
    list)
        paste ~/.ssh/known_hosts.context ~/.ssh/known_hosts
        ;;
    *)
        echo "Usage: $0 {add|list} [host]"
        ;;
esac
  • Use ssh-keyscan to bulk add hosts
  • Regularly clean stale entries with ssh-keygen -R hostname
  • Consider version controlling your known_hosts file
  • Implement host aliases in ~/.ssh/config for readability

For large teams:

# Puppet manifest example:
file { '/etc/ssh/ssh_known_hosts':
  ensure  => present,
  content => template('module/ssh_known_hosts.erb'),
  mode    => '0644',
}

Where the ERB template can include structured comments in a way that doesn't interfere with SSH operations.


The ~/.ssh/known_hosts file follows a strict format where each line represents a known host entry with this structure:

[hostname_or_ip] ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFJZ...

While the SSH protocol specification (RFC 4251) doesn't explicitly mention comment support in known_hosts, most OpenSSH implementations allow comments using the hash symbol (#) at the beginning of lines:

# Personal development servers
dev1.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ...

# Production cluster
192.168.1.100 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...

When you need inline comments (within host entries), consider these approaches:

1. Using host aliases:

# Jenkins_CI_server
jenkins.ci.example.com ssh-rsa AAAAB3Nz...

2. Creating a separate mapping file:

# ~/.ssh/host_comments.map
host1=Primary database server
host2=Staging environment

For large environments, you might want to structure your known_hosts like this:

################################
# AWS US-EAST-1 REGION SERVERS #
################################
ec2-54-123-45-67.compute-1.amazonaws.com ssh-rsa AAAAB...

#############################
# LOCAL DEVELOPMENT SERVERS #
#############################
dev-vm1 ssh-ed25519 AAAAC3Nza...

Here's a Python script to parse and display annotated known_hosts:

import re

def parse_known_hosts(path):
    with open(path, 'r') as f:
        for line in f:
            line = line.strip()
            if line.startswith('#'):
                print(f"COMMENT: {line[1:]}")
            elif line:
                host, keytype, key = line.split()[:3]
                print(f"HOST: {host} ({keytype})")

parse_known_hosts('/home/user/.ssh/known_hosts')

Combine comments with SSH config for maximum readability:

# ~/.ssh/config
Host dev-server  # Primary development box
    HostName 192.168.1.50
    User devuser

Host prod-db  # MySQL production primary
    HostName db1.prod.example.com
    User admin