get_fqdn 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/python3
  2. #
  3. # Maximilian Wilhelm <max@rfc2324.org>
  4. # -- Sat, 15 Apr 2023 01:52:36 +0200
  5. #
  6. import argparse
  7. import netifaces
  8. import os
  9. import os.path
  10. import requests
  11. import sys
  12. def get_active_interface() -> str:
  13. try:
  14. # netifaces.gateway() will return a dict with multiple keys:
  15. # 'default' -> dict with default route information (AF -> (ip, iface))
  16. # netifaces.AF_INET -> list of IPv4 next-hop tuples (IP, iface, default yes/no)
  17. # netifaces.AF_INET6 -> list of IPv6 next-hop tuples (see above)
  18. def_gw = netifaces.gateways()['default']
  19. # The 'default' dict should contain an IPv6 default gw (we need IPv6 to reach NACL),
  20. # and if so we care about the interface name
  21. return def_gw[netifaces.AF_INET6][1]
  22. except KeyError:
  23. return None
  24. def get_interface_mac(ifname: str) -> str:
  25. iface_addrs = netifaces.ifaddresses(ifname)
  26. try:
  27. # We care about the MAC of the 1st entry in the AF_LINK addresses (from right to left)
  28. return iface_addrs[netifaces.AF_LINK][0]['addr']
  29. except KeyError:
  30. return None
  31. except IndexError:
  32. return None
  33. def get_fqdn(nacl_url: str, mac: str):
  34. params = {}
  35. if mac:
  36. params['mac'] = mac
  37. try:
  38. res = requests.get (f"{nacl_url}/node/whoami", params = params)
  39. if res.status_code == 200:
  40. return res.json()
  41. else:
  42. print(f"Failed to get FQDN: {res.text}", file=sys.stderr)
  43. sys.exit(3)
  44. except Exception as e:
  45. print(f"Failed to get FQDN: {str(e)}", file=sys.stderr)
  46. sys.exit(4)
  47. parser = argparse.ArgumentParser(description = 'NACL SSH key registration tool')
  48. parser.add_argument('--mac', '-m', help = 'Use MAC address from gateway interface rather than IP address to identify ourselves', action = 'store_true', default = False)
  49. parser.add_argument('--url', help = "URL to reach NACL service, e.g http://nacl:2342", default = os.environ.get('NACL_URL', 'http://nacl'))
  50. args = parser.parse_args()
  51. mac = None
  52. if args.mac:
  53. uplink_ifname = get_active_interface()
  54. if uplink_ifname is None:
  55. print("Failed to identify uplink interface!", file=sys.stderr)
  56. sys.exit(1)
  57. mac = get_interface_mac(uplink_ifname)
  58. if mac is None:
  59. print(f"Failed to get MAC address of uplink interface {uplink_ifname}!", file=sys.stderr)
  60. sys.exit(2)
  61. print(get_fqdn(args.url, mac))