2020-07-28 16:21:34 +10:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import subprocess
|
|
|
|
|
2020-08-05 14:36:15 +10:00
|
|
|
def generate_sshfp_records(hostname, ip, local):
|
2020-07-28 16:21:34 +10:00
|
|
|
'''Given a hostname and and IP address, scan the IP address (hostname
|
|
|
|
not in dns yet) and return a bind string with sshfp records'''
|
|
|
|
|
2020-08-05 14:36:15 +10:00
|
|
|
if local:
|
|
|
|
p = ['ssh-keyscan', '-D', ip]
|
|
|
|
else:
|
|
|
|
# Handle being run via sudo which is the usual way
|
|
|
|
# this is run.
|
|
|
|
p = ['ssh', '-o', 'StrictHostKeyChecking=no',
|
|
|
|
'-i', '/root/.ssh/id_rsa',
|
|
|
|
'root@%s' % ip, 'ssh-keygen', '-r', ip]
|
|
|
|
|
|
|
|
s = subprocess.run(p,
|
2020-07-28 16:21:34 +10:00
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE).stdout.decode('utf-8')
|
|
|
|
fingerprints = []
|
|
|
|
for line in s.split('\n'):
|
|
|
|
if not line:
|
|
|
|
continue
|
|
|
|
_, _, _, algo, key_type, fingerprint = line.split(' ')
|
2020-08-05 14:36:15 +10:00
|
|
|
# ssh-keygen on the host seems to return DSS/DSA keys, which
|
|
|
|
# aren't valid to log in and not shown by ssh-keyscan -D
|
|
|
|
# ... prune it.
|
|
|
|
if algo == '2':
|
|
|
|
continue
|
2020-07-28 16:21:34 +10:00
|
|
|
fingerprints.append(
|
|
|
|
(algo, key_type, fingerprint))
|
|
|
|
|
|
|
|
# sort by algo and key_type to keep it consistent
|
|
|
|
fingerprints = sorted(fingerprints,
|
|
|
|
key=lambda x: (x[0], x[1]))
|
|
|
|
|
|
|
|
ret = ''
|
|
|
|
first = True
|
2021-03-05 12:18:13 -08:00
|
|
|
dns_hostname = hostname.split('.')[0]
|
2020-07-28 16:21:34 +10:00
|
|
|
for f in fingerprints:
|
|
|
|
ret += '%s%s\t\tIN\tSSHFP\t%s %s %s' % \
|
2021-03-05 12:18:13 -08:00
|
|
|
("\n" if not first else '', dns_hostname, f[0], f[1], f[2])
|
2020-07-28 16:21:34 +10:00
|
|
|
first = False
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
2020-08-05 14:36:15 +10:00
|
|
|
def sshfp_print_records(hostname, ip, local=False):
|
|
|
|
print(generate_sshfp_records(hostname, ip, local))
|
2020-07-28 16:21:34 +10:00
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument("hostname", help="hostname")
|
|
|
|
parser.add_argument("ip", help="address to scan")
|
2020-08-05 14:36:15 +10:00
|
|
|
parser.add_argument("--local", action='store_true',
|
|
|
|
help="Run keyscan locally, rather than via ssh")
|
2020-07-28 16:21:34 +10:00
|
|
|
args = parser.parse_args()
|
|
|
|
|
2020-08-05 14:36:15 +10:00
|
|
|
sshfp_print_records(args.hostname, args.ip, args.local)
|
2020-07-28 16:21:34 +10:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|