64 lines
No EOL
2.2 KiB
Python
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() |