import socket import random import os import subprocess import ipaddress # Google subnets to route through the random IP SUBNETS = [ "2001:4860:4000::/36", "2404:6800:4000::/36", "2607:f8b0:4000::/36", "2800:3f0:4000::/36", "2a00:1450:4000::/36", "2c0f:fb50:4000::/36", ] TEST_IP_EXTERNAL = "2a0d:f302:111:38cc::1" # A public IPv6 NOT in the subnet # 1) Get the machine's current primary IPv6 address def get_current_ipv6(): s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s.connect((TEST_IP_EXTERNAL, 80)) current_ip = s.getsockname()[0] return current_ip # 2) Generate a random IP address within the /64 subnet of the current primary IPv6 def generate_random_ipv6(ipv6): # Parse the original IP address and network original = ipaddress.ip_interface(ipv6) # Generate a random interface identifier random_int = random.randint(1, 2**64 - 1) new_ip = ipaddress.IPv6Interface((int(original.network.network_address) | random_int, original.network.prefixlen)) return str(new_ip.ip) def main(): current_ipv6 = get_current_ipv6() # Get network interface and gateway default_route = subprocess.check_output("ip -6 route show default", shell=True).decode('utf-8') iface = default_route.split("dev ")[1].split()[0] current_gateway = default_route.split("via ")[1].split()[0] random_ipv6 = generate_random_ipv6(current_ipv6) # 2.5) Remove any existing non-given IPv6 addresses from previous runs of the scripts prev_ips_raw_output = subprocess.check_output(f"ip -6 addr show {iface} scope global", shell=True).decode('utf-8') prev_ips = [line.strip().split(" ")[1].split("/")[0] for line in prev_ips_raw_output.split("\n") if "inet6" in line] for ip in prev_ips: if ip != current_ipv6: os.popen(f"sudo ip -6 addr del {ip} dev {iface}") # 3) Add new IP to the interface os.popen(f"sudo ip -6 addr add {random_ipv6} dev {iface}") # 4) Set up routes such that the random IP address is now used as the source address for requests to given IPv6 subnets for subnet in SUBNETS: os.popen(f"sudo ip -6 route add {subnet} from {random_ipv6} dev {iface} via {current_gateway}") if __name__ == "__main__": main()