system-config/launch/sshfp.py
Clark Boylan 5f4b5000c8 Fix sshfp record printing
Previously if you ran `sshfp.py foo.opendev.org x.y.z.a` it would spit
out records that look like:

  foo.opendev.org IN SSHFP 1 1 stuffstuffstuff

The problem with this is when you copy this output into the zone file
the lack of a terminating '.' means the record will actually be for
foo.opendev.org.opendev.org.

We address this by splitting on '.' and taking the first element. This
will still be broken for hosts named foo.bar.opendev.org but for now is
a decent improvement.

Change-Id: Ib12f66c30e20a62d14d0d0ddd485e28f7f7ab518
2021-03-05 12:18:13 -08:00

65 lines
2.0 KiB
Python
Executable File

#!/usr/bin/env python3
import argparse
import subprocess
def generate_sshfp_records(hostname, ip, local):
'''Given a hostname and and IP address, scan the IP address (hostname
not in dns yet) and return a bind string with sshfp records'''
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,
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(' ')
# 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
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
dns_hostname = hostname.split('.')[0]
for f in fingerprints:
ret += '%s%s\t\tIN\tSSHFP\t%s %s %s' % \
("\n" if not first else '', dns_hostname, f[0], f[1], f[2])
first = False
return ret
def sshfp_print_records(hostname, ip, local=False):
print(generate_sshfp_records(hostname, ip, local))
def main():
parser = argparse.ArgumentParser()
parser.add_argument("hostname", help="hostname")
parser.add_argument("ip", help="address to scan")
parser.add_argument("--local", action='store_true',
help="Run keyscan locally, rather than via ssh")
args = parser.parse_args()
sshfp_print_records(args.hostname, args.ip, args.local)
if __name__ == '__main__':
main()