ipv6rotator/rotator.py

64 lines
No EOL
2.2 KiB
Python

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()