Last active
April 3, 2023 00:42
-
-
Save joneskoo/1306614 to your computer and use it in GitHub Desktop.
SSH known hosts cleanup script. Combines same fingerprints to one line.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# encoding: utf-8 | |
# By Joonas Kuorilehto 2011, MIT license | |
# | |
# The script combines .ssh/known_hosts so that each fingerprint is only | |
# listed once. | |
import re | |
import sys | |
import os | |
import shutil | |
def main(): | |
if len(sys.argv) != 2: | |
print("Usage: {} $HOME/.ssh/known_hosts".format(sys.argv[0])) | |
sys.exit(1) | |
clean_known_hosts(sys.argv[1]) | |
def clean_known_hosts(known_hosts_file): | |
# Backup known hosts file | |
shutil.copyfile(known_hosts_file, known_hosts_file+".old") | |
# Read known hosts to memory | |
with open(known_hosts_file) as f: | |
knownhosts = dict() | |
oldlines = 0 | |
for line in f: | |
if line.strip() == "" or line.strip().startswith("#"): | |
continue | |
oldlines += 1 | |
hosts, keytype, fingerprint = line.strip().split(" ")[:3] | |
dictkey = keytype + fingerprint | |
hosts = hosts.split(",") | |
if knownhosts.get(dictkey) == None: | |
knownhosts[dictkey] = dict(hosts=set(), keytype=keytype, | |
fingerprint=fingerprint) | |
knownhosts[dictkey]['hosts'].update(hosts) | |
# Replace known hosts with a cleaned version | |
with open(known_hosts_file, 'w') as f: | |
for key, host in knownhosts.items(): | |
host['hosts_joined'] = ",".join(host['hosts']) | |
f.write("%(hosts_joined)s %(keytype)s %(fingerprint)s\n" % host) | |
print("OK. Cleaned up", known_hosts_file) | |
print("Change: from %d lines to %d lines." % (oldlines, len(knownhosts))) | |
print("List of host names in the file (aliases on the same line):") | |
i = 0 | |
for key, host in knownhosts.items(): | |
i += 1 | |
def ipv6(x): | |
if ':' in x: | |
return True | |
def hostname(x): | |
if not ipv6(x) and re.match("[a-z]", x, re.I): | |
return True | |
hosts = list(filter(hostname, host['hosts'])) | |
if len(hosts): | |
print("%-4d"%i + " ".join(sorted(hosts))) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://gist.github.com/joneskoo/1306614/96dd6d75a086bebbfa34def081867447850b616c KNOWN_HOSTS is now unknown (had to revert to your last commit).
Thanks for the script (so much tidier now).