53 lines
1.3 KiB
Python
Executable File
53 lines
1.3 KiB
Python
Executable File
#! /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())
|