PSA: IPv6 browser privacy leaks are caused by the host yet there's a simple fix

Jul 20, 2026 Last reply: 2 months ago 45 Replies

Yeah, if you're in a context where IPv4 is NATed at your premises because the ISP hands you one address, and you also get IPv6 prefix delegation, then... it's the same thing, your IPv4 address identifies the connection, as does the prefix present in the RAs.

The part that is "rotated" or otherwise randomized in such privacy-centered SLAAC configurations is the one that'd allow tracking the *device*, not the connection.

That's not meant to stop tracking your e.g. residential connection, it's meant to stop tracking the device based on the device-specific portion of the address, which without this may e.g. contain the MAC address.

formatting link

But for e.g. MAFIAA this only matters if you're not using your own connection, because otherwise you've already been identified by the delegated prefix, they'd pester you the same.

Do note: the prefix used in SLAAC isn't (or shouldn't be...) something a residential ISP uses for several costumers, it's meant to be one prefix for each contract/ISP connection/modem.

Nuno Silva

Thank you all for this very useful information about IPv6 privacy issues.

Since Usenet is for learning from people like Nuno Silva & Brian Gregory, who know far more about this IPv6-privacy stuff than I will ever know...

Looking up the terms they're using is helpful to understand the network.

When Brian says "dual stack", he's meaning both the IPv4 & IPv6 stacks. They're two parallel protocol stacks, where his devices can use either protocol depending on what the remote service supports. If a site has IPv6, his device may prefer it; if not, it falls back to IPv4, which provides Brian benefit from IPv6's performance and routing improvements without losing any IPv4 compatibility.

When Nuno says SLAAC, he's using the acronym for Stateless Address Autoconfiguration, which is the IPv6 mechanism that lets a device automatically generate its own IPv6 address without needing a DHCP server.

The ISP gives us the network prefix (the first 64 bits) IPv6 address and each device builds the second half (the Interface Identifier) IID address on its own. It used to be derived from the MAC address, but not in modern systems anymore, the point being if the IID half is stable, websites can track specific devices across sessions. RFC 8981 destabilizes that, but only after a set time period (generally defaulting to 24 hours).

An example is if you go to Starbucks in the morning and afternoon, and visit the same web site in two different sessions, they know it's you in both sessions.

Note that the web site knows it's starbucks too, which is why the first half of IPV6 is no worse in terms of privacy than IPv4 is; but it's that festugenah second half of the IPv5 prefix that we have to keep in mind.

His MAFIAA terminology is a play on the mafia-like behavior of copyright trolls, combining RIAA (Recording Industry Association of America) with MPAA (Motion Picture Association of America), where I would stress that many people pay up but nobody who ever fought them in the USA ever lost.

With respect to VPN, I just found out that OpenVPN 2.5+ added a directive specifically meant to prevent the very IPv6 leaks we've been discussing! block-ipv6 ; block IPv6 traffic by adding firewall rules to prevent leaks Apparently it magically installs firewall rules on our devices that somehow know to drop all IPv6 traffic unless it is going through the VPN tunnel.

It forces all IPv6 traffic to go through the VPN, or be blocked entirely. .

If running older OpenVPN on linux, we can add firewall rules manually: ip6tables -P OUTPUT DROP ip6tables -P INPUT DROP

In short, I thank Nuno & Brian for bringing this up at a level far above my pay grade since I just learned the simplest solution of all to the problem.

Apparently block-ivp6 blocks IPv6 only when the tunnel doesn't support it. Which is perfect because understanding networking is what this is about.

BTW, while looking this up, I learned these potentially useful directives: block-outside-dns ; force DNS queries to stay inside the VPN interface This says, if a program tries to resolve DNS through wlan0, eth0, or anything other than the TAP adapter, then block it (to prevent leaks).

Then, inside the VPN tunnel, we can explicitly set the DNS servers. dhcp-option DNS 1.1.1.1 ; set primary DNS to Cloudflare inside the tunnel dhcp-option DNS 9.9.9.9 ; set secondary DNS to Quad9 for secure fallback

I just tested them; now I see a full, healthy DNS stack inside the tunnel. NETSH: ... set dns 19 static 1.1.1.1 NETSH: ... add dns 19 9.9.9.9 NETSH: ... add dns 19 8.8.8.8

I knew absolutely nothing about IPv6 before this thread, so I thank everyone for quickly correcting my newbie mistakes without pulling punches!

I still have work to do because apparently curl leaks outside of the VPN.

I learn best from helpful people who know a hellova lot more than I do. .

Thanks Brian for checking me as I never even looked at IPv6 until I started modifying the LiquidVPN killswitch (which simply removed the gateway) because when I changed from a USB dongle Wi-Fi on my Ethernet-only desktop, the Wi-Fi card I added was so much more complex, that Windows "fixed itself" every time I wiped out the gateway, so the killswitch didn't work.

When I started writing that killswitch, I ran into IPv6 considerations for the first time, which I never thought about since I didn't use IPv6.

What I didn't know was that EVERYTHING uses IPv6 if it can, nowadays.

So, for example, in the IPv4-only days, if I take a device (phone or laptop) to a local hotspot, and visit a website twice within the same day, then they only know that "something" connected from that particular site.

But, in these dual-stack IPv4+IPv6 days, all our device operating systems and browsers prefer IPv6 over IPv4 so we connect using the IPv6 IP address.

Now, if I take a device (phone or laptop) to a local hotspot, and visit a website twice within the same day, now they know that the "same device" connected from that particular site, which is a recent elevation to me.

That "oh s*it!" moment is the same as when I realized that the pixel imperfections in two camera photos uniquely identifies that same camera, such that if I post two photos to two websites, anyone scraping those two web sites can tell both pictures were taken from the same camera.

Only after those "oh s*it!" moments can I begin to implement ameliorations.

Hence, I thank you for correcting all my false statements about IPv6 privacy, as I love it when someone sets me straight on my assumptions.

Of the million things we need to know about privacy, most know 3.

As a related aside, if your network ever does go to hell in a handbasket, the following manual commands seem to surgically fix mine in a flash. a. This sequence touches every networking layer that commonly breaks. b. Renaming interfaces removes whitespace headaches & makes scripting sane. c. Toggling up/down forces driver rebinding and flushes stale states. d. Setting static IP + DNS eliminates DHCP weirdness e. The connectivity validation is in the proper escalation order i. Local gateway ii. Public IP iii. DNS resolution iv. HTTP throughput v. Full speed test f. route print -4 confirms the metrics and/or stale routes g. Resetting Winsock is the nuclear option for corrupt proxies.

One-time commands to simplify the networking scripts: netsh interface set interface name="Ethernet 2" newname="eth0" netsh interface set interface name="Wi-Fi 2" newname="wlan0" One-time commands to set a networking metric baseline: netsh interface ipv4 set interface "eth0" metric=10 netsh interface ipv4 set interface "wlan0" metric=20

Set your network for Ethernet (in my case, via a wireless router): netsh interface set interface "wlan0" admin=disabled netsh interface set interface "eth0" admin=enabled netsh interface ipv4 set address name="eth0" static 192.168.1.15 255.255.255.0 192.168.1.1 netsh interface ipv4 set dns name="eth0" static 1.1.1.1 netsh interface ipv4 add dns name="eth0" 1.0.0.1 netsh interface ipv4 show dnsservers netsh interface ipv4 show config name="eth0" netsh interface ipv4 show config netsh interface ipv4 show dnsservers ping -n 1 192.168.1.1 ping -n 1 1.1.1.1 ping -n 1

formatting link
wmic nic where (NetEnabled=true) get Name, Speed curl -o NUL
formatting link
curl -o NUL
formatting link
curl -o NUL
formatting link
speedtest.exe (from
formatting link
) route print -4 ipconfig /all At this point you can now run psiphon.bat or vpn.bat

Set your network for Wi-Fi (in my case, via a Wi-Fi NIC card): netsh interface set interface "eth0" admin=disabled netsh interface set interface "wlan0" admin=enabled netsh interface ipv4 set address name="wlan0" static 192.168.1.16 255.255.255.0 192.168.1.1 netsh interface ipv4 set dns name="wlan0" static 1.1.1.1 netsh interface ipv4 add dns name="wlan0" 1.0.0.1 netsh wlan connect name="my.ssid_nomap" (note that the SSID should always be hidden broadcast!) netsh interface ipv4 show config netsh interface ipv4 show config name="wlan0" netsh interface ipv4 show dnsservers ping -n 1 192.168.1.1 ping -n 1 1.1.1.1 ping -n 1

formatting link
wmic nic where (NetEnabled=true) get Name, Speed curl -o NUL
formatting link
curl -o NUL
formatting link
curl -o NUL
formatting link
speedtest.exe (from
formatting link
) route print -4 ipconfig /all At this point you can now run psiphon.bat or vpn.bat ============================================================ Here's a networking cheat sheet if anyone needs the commands. ============================================================ Layer 1: link & adapter state check NIC driver + link status wmic nic get Name,NetEnabled,Speed show adapter statistics (errors/drops) netstat -e show interface statistics netsh interface ipv4 show interfaces ============================================================ Layer 2: arp & neighbor discovery show arp table arp -a show ipv4 neighbor cache netsh interface ipv4 show neighbors clearing arp can fix phantom MAC mappings arp -d * ============================================================ Layer 3: ip configuration & routing show ipv4 global settings netsh interface ipv4 show global show ipv4 addresses netsh interface ipv4 show address show routing table (ipv4 only) route print -4 show active tcp/udp endpoints netstat -an check for leftover VPN static routes route print -4 route delete <network>

============================================================ Layer 4: dhcp check dhcp server discovery netsh dhcp show server show dhcp-assigned addresses netsh interface ip show addresses force dhcp renew ipconfig /release && ipconfig /renew ============================================================ Layer 5: dns test dns resolution nslookup example.com show dns cache ipconfig /displaydns flush dns cache ipconfig /flushdns check browser DNS-over-HTTPS interference Chrome: chrome://settings/security Firefox: about:preferences#privacy ============================================================ Layer 6: firewall show firewall rules netsh advfirewall firewall show rule name=all show firewall profile state netsh advfirewall show allprofiles ============================================================ Layer 7: winsock show winsock providers netsh winsock show catalog reset winsock (fixes corruption) netsh winsock reset reset tcp/ip stack (deeper than winsock) netsh int ip reset ============================================================ Layer 8: connectivity tests ping gateway ping <gateway>

ping ipv4-only target ping -4 8.8.8.8 trace ipv4 route tracert 8.8.8.8 test ipv4 http curl -4

formatting link
============================================================ Layer 9: system logs open event viewer eventvwr.msc check dhcp logs (event viewer > microsoft > windows > dhcp-client) check tcp/ip logs (event viewer > system > tcpip) check ndis driver logs (event viewer > system > ndis) ============================================================ Layer 10: advanced routing & bindings show interface metrics netsh interface ipv4 show interfaces show binding joins netsh interface ip show joins show tcp global parameters netsh interface tcp show global ============================================================ Layer 11: proxy cleanup show winhttp proxy netsh winhttp show proxy reset winhttp proxy netsh winhttp reset proxy ============================================================ Layer 12: NIC driver rebinding disable NIC driver wmic path win32_networkadapter where NetEnabled=true call disable enable NIC driver wmic path win32_networkadapter where NetEnabled=false call enable ============================================================ Verify no leftover VPN routes route print -4 route delete eth0 Some browsers override system DNS: about:preferences#privacy chrome://settings/security

On Usenet, friendly kind-hearted people help each other out daily.

NSA-coded post right here lol.

Oregonian Haruspex wrote:

To ensure DNS is working right, I explicitly set it in the openvpn config.

These are the commands I add to every one of hundreds of free config files. Notice the DNS-related commands are brand new, to keep DNS inside the tunnel.

auth-nocache ; prevent caching of auth credentials in memory auth-retry nointeract ; retry silently using stored username/password auth-user-pass C:\\tmp\\vpn\\0\\require\\userpass.txt ; login file path block-ipv6 ; block IPv6 traffic to prevent IPv6 leaks block-outside-dns ; force DNS queries to stay inside the VPN TAP interface ; NB block-outside-dns breaks OS DNS if the VPN's DNS server is dead ; dhcp-option DNS 1.1.1.1 ; set primary DNS to Cloudflare inside the tunnel ; dhcp-option DNS 9.9.9.9 ; set secondary DNS to Quad9 for secure fallback connect-retry-max 20 ; increase max reconnect attempts (default=8) connect-retry 5 ; shorten delay between reconnect attempts connect-timeout 30 ; time before initial connect attempt times out data-ciphers AES-256-GCM:AES-128-GCM:AES-128-CBC ; required by vpngate.net explicit-exit-notify 2 ; send disconnect notice to UDP servers float ; accept server IP changes during session hand-window 180 ; extend TLS handshake window (default=60) inactive 3600 ; allow long idle periods before timeout (default=off) ip-win32 adaptive ; choose best Windows IP/DNS routing method keepalive 10 60 ; ping every 10s, restart after 60s silence mssfix 1400 ; adjust TCP MSS to reduce fragmentation tun-mtu 1400 ; set tunnel MTU to avoid packet fragmentation ; pull-filter ignore "redirect-gateway" ; prevent server from setting gateway pull-filter accept "redirect-gateway" ; accept the vpn server routing changes pull ; accept configuration pushed by the VPN server replay-window 128 ; enlarge replay protection packet window route-delay 10 ; delay route setup to avoid race conditions server-poll-timeout 120 ; wait longer for server PUSH reply (default=2) tls-timeout 180 ; extend TLS negotiation timeout (default=60) verb 4 ; moderate verbosity, show key events without packet spam

During testing, on Windows, I made use of the old curlit shortcut: Win+R > curlit Which calls curlit.exe which is defined only in the Windows Registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\curlit.exe Default=C:\path-to\curlit.lnk Where the TARGET of that curlit.lnk shortcut does the IP check. Target=%comspec% /k echo "C:\data\sys\pgm\lnk\curlit.lnk $MYIP" & %Windir%\System32\curl.exe icanhazip.com NB: There is no command called "curlit.exe"; that's a unique reg keyword.

I tried to make it fancier with curlvpn but that errored out on Windows: TARGET=%comspec% /k echo "curlvpn: forcing curl through VPN TAP adapter" & %Windir%\System32\curl.exe --interface Ethernet --dns-servers 1.1.1.1,9.9.9.9 icanhazip.com I'm sure that curl syntax would work if curl were compiled differently. "curlvpn: forcing curl through VPN TAP adapter" curl: option --dns-servers: the installed libcurl version does not support this curl: try 'curl --help' for more information But I like my commands to work universally so I changed it to Win+R > curldns Which calls curldns.exe which is defined only in the Windows Registry HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\curldns.exe Default=C:\path-to\curldns.lnk Where the TARGET of that curldns.lnk shortcut does the IP check. %comspec% /k echo "C:\data\sys\pgm\lnk\curldns.lnk $MYIP" & echo curldns & nslookup icanhazip.com & powershell -Command "Resolve-DnsName icanhazip.com" & curl icanhazip.com NB: There is no command called "curldns.exe"; that's just a reg keyword.

I post it here so that others, at least on Windows, can instantly replicate this shortcut efficiency to make sure their VPN DNS remains in the tunnel.

I strive to add technical value, if possible, with every post to Usenet.

It's 100% feasible in Windows if you look it up or ask an AI instead of just guessing.

reg add "HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" /v "DisabledComponents" /t REG_DWORD /d 1 /f

then reboot.

Brian Gregory (in England).

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required