diff --git a/launch/dns.py b/launch/dns.py index 01d6931ed7..67be16bfc6 100755 --- a/launch/dns.py +++ b/launch/dns.py @@ -19,7 +19,7 @@ # limitations under the License. import argparse - +from sshfp import sshfp_print_records def get_href(server): if not hasattr(server, 'links'): @@ -50,7 +50,7 @@ def print_dns_opendev(name, ip4, ip6): print("{name} IN A {ip4}".format(name=name, ip4=ip4)) if ip6: print("{name} IN AAAA {ip6}".format(name=name, ip6=ip6)) - + sshfp_print_records(name, ip4) def print_reverse_dns(cloud, server, ip4, ip6): # Get the server object from the sdk layer so that we can pull the diff --git a/launch/sshfp.py b/launch/sshfp.py new file mode 100755 index 0000000000..7c7d3f0450 --- /dev/null +++ b/launch/sshfp.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 + +import argparse +import subprocess + +def generate_sshfp_records(hostname, ip): + '''Given a hostname and and IP address, scan the IP address (hostname + not in dns yet) and return a bind string with sshfp records''' + + s = subprocess.run(['ssh-keyscan', '-D', ip], + 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(' ') + 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 + for f in fingerprints: + ret += '%s%s\t\tIN\tSSHFP\t%s %s %s' % \ + ("\n" if not first else '', hostname, f[0], f[1], f[2]) + first = False + return ret + + +def sshfp_print_records(hostname, ip): + print(generate_sshfp_records(hostname, ip)) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("hostname", help="hostname") + parser.add_argument("ip", help="address to scan") + args = parser.parse_args() + + sshfp_print_records(args.hostname, args.ip) + +if __name__ == '__main__': + main()