diff --git a/scripts/wg-peer-to-ipv6 b/scripts/wg-peer-to-ipv6 new file mode 100755 index 0000000..e0fc355 --- /dev/null +++ b/scripts/wg-peer-to-ipv6 @@ -0,0 +1,52 @@ +#! /usr/bin/env python3 +import argparse +import sys +import logging +import ipaddress +import hashlib +import base64 + +logger = logging.getLogger(__name__) + + +def main() -> int: + # Handle program arguments + ap = argparse.ArgumentParser( + prog="wg-peer-to-ipv6", + description="Deterministically generate IPv6 addresses from WireGuard public keys", + ) + ap.add_argument("prefix", help="IPv6 prefix", type=ipaddress.IPv6Network) + ap.add_argument("public_key", help="WireGuard public key") + ap.add_argument( + "-v", "--verbose", help="Enable verbose logging", action="store_true" + ) + args = ap.parse_args() + + # Configure logging + logging.basicConfig( + level=logging.DEBUG if args.verbose else logging.INFO, + format="%(levelname)s: %(message)s", + ) + + # Decode the public key + public_key = base64.b64decode(args.public_key) + + # Hash the public key + hash = hashlib.sha256(public_key).digest() + + # Figure out how many bits we have for the host part + host_bits = args.prefix.max_prefixlen - args.prefix.prefixlen + + # Take that many bits from the hash + host = int.from_bytes(hash, "big") >> (256 - host_bits) + + # Create the IPv6 address + ipv6 = args.prefix.network_address + host + + print(ipv6) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/wg-reload b/scripts/wg-reload old mode 100644 new mode 100755