IPv6 IP address leak using policy-based routing

I guess this could be. Can you ping from the OpenWrt an IPv6 address using the mullvad vpn?
ping6 -I mullvad ipv6.google.com
If yes, then add the following:

uci set dhcp.lan.ra_default='1'
uci commit dhcp
service dnsmasq restart

Thanks. Yes, ping6 from the router works (but fails on a client with "No route to host"). Have added ra_default='1' so that the stanza now looks as follows; but still no IPv6 Connectivity. I also see:

Thu Jun  4 11:02:39 2020 daemon.err dnsmasq[6556]: failed to send packet: Host is unreachable

and the 'default route / no lan prefix' warning from odhcpd

/etc/config/dhcp
config dhcp 'lan'
	option instance 'main'
	option interface 'lan'
	option start '100'
	option limit '150'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option leasetime '168h'
	option ra_default '1'

Check the ipv6 routing table of the client . Does it have a default route? With the latest addition it should, so maybe you need to restart the networking on the client?

One more thing:
the mullvad IP overlaps with the lan network, so change the lan address to something else. For example fc00:bbbb:bbbb:bba1::1/60
You can use IPv6 assignment hint for that bba1

OK, so changes made:

added to /etc/config/network:

config globals 'globals'
	option ula_prefix 'fc00:bbbb:bbbb:bba1::1/60'

config route6
	option target '::/0'
	option interface 'mullvad'

config interface 'lan'
    ...
	list ip6class 'local'
    ...

added to /etc/config/dhcp:

config dhcp 'lan'
	...
	option ra_default '1'
    ...

modified vpn-pbr rule:

config policy
	option chain 'PREROUTING'
	option name 'Private'
	option proto 'tcp udp'
	option interface 'mullvad'
	option src_addr '192.168.10.1/24 fc00:bbbb:bbbb:bb01::1/60'

rebooted router, restarted network on client.

This works on the router

 ping -I mullvad ipv6.google.com

but on the client, I now get:

PING6(56=40+8+8 bytes) fc00:bbbb:bbbb:bba0:6402:67dc:227f:8194 --> 2404:6800:4003:c04::8b

Routing table shows a site local address as default:

Destination                             Gateway                         Flags         Netif Expire
default                                 fe80::20d:b9ff:fe51:2639%en0    UGc             en0       
default                                 fe80::%utun0                    UGcI          utun0       
default                                 fe80::%utun1                    UGcI          utun1       
default                                 fe80::%utun2                    UGcI          utun2       
default                                 fe80::%utun3                    UGcI          utun3       
::1                                     ::1                             UHL             lo0 

utterly stumped. IPv6 connectivity through my ISP is fine; it's just getting out through Mullvad that's problematic)

traceroute6 ipv6.google.com

from the router shows a route through Mullvad...

Here you can have the whole prefix that mullvad has assigned to you.
Then you can fine tune the interface prefixes either statically or with hints.

That is correct, as this is the link local of the br-lan interface.
Do a tcpdump and verify that ping packet is leaving from the router:
tcpdump -i mullvad -vn icmp6

I think I follow:

config globals 'globals'
	option ula_prefix 'fc00:bbbb:bbbb:bb01::/40'

and then add: option ip6prefix fc00:bbbb:bbbb:bba1::1/60 to the config interface lan stanza.

Careful there, you must use the prefix that has been assigned to you.

oh, good catch. /48'. Will give it a whirl and let you know.

sorry, I'm making a fudge of this.

Mullvad has given me fc00:bbbb:bbbb:bb01::39a6/128

I've got:

config globals 'globals'
	option ula_prefix 'fc00:bbbb:bbbb:bb01::/48'

and

config interface 'lan'
	...
	option ip6prefix 'fc00:bbbb:bbbb:bb01::1/60'

with a VPN-PBR rule of:

config policy
	option chain 'PREROUTING'
	option name 'Private'
	option proto 'tcp udp'
	option interface 'mullvad'
	option src_addr '192.168.10.1/24 fc00:bbbb:bbbb:bb01::1/60

When I ping6 from a client, it looks like the prefix is incorrect:

PING6(56=40+8+8 bytes) fc00:bbbb:bbbb:bb00:c866:d21b:85de:d638 --> 2404:6800:4003:c04::8b

When I check the IPv6 addresses assigned to the client, there are 5:

  • Two beginning fc00:bbbb:bbbb:bb00
  • One beginning fc00:bbbb:bbbb:bb01
  • Two beginning fd...

This is for delegation to downstream routers.

Verify the IPv6 of the lan interface with ip -6 addr most likely it is using a different one since you reserved the bb01 for delegation.

Ah, I see. I misunderstood the docs, then. That being the case; how to I ensure the lan network doesn't overlap with the Mullvad IP? Can I set option ip6prefix on the wan interface?

UPDATE: or option ip6addr on the lan interface

You can assign the ip with ip6addr directly.
Or you can use the ip6hint to let it take a chunk from the whole /48 and use the hint suffix for network. Check here.

thanks. I'm going to reset all the changes so far so I'm back in the initial state (IPv4 obeying the vpn-pbr and IPv6 through my ISP), and then make changes one-by-one.

no luck, I'm afraid. Same situation: ping6 from the router over the mullvad interface is fine; but nothing from clients.

I'm going to 'sleep on it' and see if a fresh pair of eyes on it helps.

Thanks for all your assistance.

One last thing, you didn't try the tcpdump. I am curious where the packets are dropped.

23:17:58.263380 IP6 (flowlabel 0xf1c5f, hlim 64, next-header ICMPv6 (58) payload length: 88) fc00:bbbb:bbbb:bb01::39a6 > 2a03:2880:f05c:112:face:b00c:0:2: [icmp6 sum ok] ICMP6, destination unreachable, unreachable route 2a02:xxxx:xxxx:0:xxxx:xxxx:xxx:xxxx
23:17:58.478506 IP6 (flowlabel 0x06669, hlim 63, next-header ICMPv6 (58) payload length: 16) fc00:bbbb:bbbb:bb00:7431:928b:31ab:70e3 > 2a00:1450:400e:807::200e: [icmp6 sum ok] ICMP6, echo request, seq 4
23:17:58.932881 IP6 (flowlabel 0x5c2bf, hlim 64, next-header ICMPv6 (58) payload length: 88) fc00:bbbb:bbbb:bb01::39a6 > 2a00:1450:400e:808::200a: [icmp6 sum ok] ICMP6, destination unreachable, unreachable route 2a02:xxxx:xxxx:0:xxxx:xxxx:xxx:xxxx
23:17:59.478687 IP6 (flowlabel 0x06669, hlim 63, next-header ICMPv6 (58) payload length: 16) fc00:bbbb:bbbb:bb00:7431:928b:31ab:70e3 > 2a00:1450:400e:807::200e: [icmp6 sum ok] ICMP6, echo request, seq 5
23:18:00.482485 IP6 (flowlabel 0x06669, hlim 63, next-header ICMPv6 (58) payload length: 16) fc00:bbbb:bbbb:bb00:7431:928b:31ab:70e3 > 2a00:1450:400e:807::200e: [icmp6 sum ok] ICMP6, echo request, seq 6

where:

  • fc00:bbbb:bbbb:bb00:7431:928b:31ab:70e3 is my client 2a00:1450:400e:807::200e and 2a00:1450:400e:808::200a are google
  • fc00:bbbb:bbbb:bb01::39a6 is the mullvad interface
    *2a03:2880:f05c:112:face:b00c:0:2 is Facebook, I think (face:b00c)
  • The 'unreachable route' is my ISP

Since you are using /60 mask in lan, then the mullvad interface and lan clients are in the same subnet.
Change the lan to ip6assign /64 and try it again.
Or leave it /60 and change the network prefix to fc00:bbbb:bbbb:bb10::1

Sorry, my IPv6 network calculations are awful. Just so I'm clear:

Mullvad have given me: fc00:bbbb:bbbb:bb01::39a6/128

So, I need to set

config globals 'globals'
	option ula_prefix 'fc00:bbbb:bbbb:bb01::/48'
config interface 'lan'
        ...
        list ip6class 'local'                       
        option ip6addr 'fc00:bbbb:bbbb:bb01::1/60'
        option ip6assign '64'

And then add fc00:bbbb:bbbb:bb01::1/60 to the VPN-PBR

Have I got that right, or am I mistaken?

The best I've come across.

No, all of them are in the same network.
You know, if it is too complicated just remove the ula_prefix and assign under lan ip6addr fc00:bbbb:bbbb:bb02::1/64 without ip6assign.