Global unicast IPv6 assigned to LAN but websites report public IP from bridge?

I have configured my LAN IPv6 range to be a public unicast IPv6 segment, then configured wireguard to bring the traffic over from a datacenter not far away.

This seems to be working; clients get SLAAC addresses from the IPv6 /64 segment and are pingable (icmp allow is default firewall rule).

root@5gpocket:~# iptables --table nat --list
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
prerouting_rule  all  --  anywhere             anywhere             /* !fw3: Custom prerouting rule chain */
zone_lan_prerouting  all  --  anywhere             anywhere             /* !fw3 */
zone_wan_prerouting  all  --  anywhere             anywhere             /* !fw3 */
zone_wan_prerouting  all  --  anywhere             anywhere             /* !fw3 */
zone_wan_prerouting  all  --  anywhere             anywhere             /* !fw3 */

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
postrouting_rule  all  --  anywhere             anywhere             /* !fw3: Custom postrouting rule chain */
zone_lan_postrouting  all  --  anywhere             anywhere             /* !fw3 */
zone_wan_postrouting  all  --  anywhere             anywhere             /* !fw3 */
zone_wan_postrouting  all  --  anywhere             anywhere             /* !fw3 */
zone_wan_postrouting  all  --  anywhere             anywhere             /* !fw3 */

Chain postrouting_lan_rule (1 references)
target     prot opt source               destination

Chain postrouting_rule (1 references)
target     prot opt source               destination

Chain postrouting_wan_rule (1 references)
target     prot opt source               destination

Chain prerouting_lan_rule (1 references)
target     prot opt source               destination

Chain prerouting_rule (1 references)
target     prot opt source               destination

Chain prerouting_wan_rule (1 references)
target     prot opt source               destination

Chain zone_lan_postrouting (1 references)
target     prot opt source               destination
postrouting_lan_rule  all  --  anywhere             anywhere             /* !fw3: Custom lan postrouting rule chain */

Chain zone_lan_prerouting (1 references)
target     prot opt source               destination
prerouting_lan_rule  all  --  anywhere             anywhere             /* !fw3: Custom lan prerouting rule chain */

Chain zone_wan_postrouting (3 references)
target     prot opt source               destination
postrouting_wan_rule  all  --  anywhere             anywhere             /* !fw3: Custom wan postrouting rule chain */
MASQUERADE  all  --  anywhere             anywhere             /* !fw3 */

Chain zone_wan_prerouting (3 references)
target     prot opt source               destination
prerouting_wan_rule  all  --  anywhere             anywhere             /* !fw3: Custom wan prerouting rule chain */
root@5gpocket:~# ip6tables --table nat --list
ip6tables v1.8.3 (legacy): can't initialize ip6tables table `nat': Table does not exist (do you need to insmod?)
Perhaps ip6tables or your kernel needs to be upgraded.

The curious question for me is that it looks like websites see my IPv6 address as the openwrt router interface IPv6 and not the device itself (similar to as if openwrt was doing NAT66). Did I miss any configuration or setting somewhere?

I want my IPv6 incoming traffic to be filtered except for established connections - the default WAN zone should suffice for this I thought, so my wireguard interface is assigned to that zone. My Windows 10 client connected to openwrt obtained public IPv6 from the segment it seems, traffic going towards the internet seems to be getting masquerated though. Screenshot attached "::1" is the WAN ipv6 of openwrt.

Here's ifstatus of my wireguard interface:

# ifstatus vpsgw
{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "dynamic": false,
        "uptime": 4368,
        "l3_device": "vpsgw",
        "proto": "wireguard",
        "updated": [
                "addresses",
                "routes"
        ],
        "metric": 0,
        "dns_metric": 0,
        "delegation": true,
        "ipv4-address": [
                {
                        "address": "10.100.100.10",
                        "mask": 24
                }
        ],
        "ipv6-address": [
                {
                        "address": "2602:n00t:yours::106:8888::10",
                        "mask": 112
                }
        ],
        "ipv6-prefix": [

        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "::",
                        "mask": 128,
                        "nexthop": "2602:n00t:yours::106:8888::1",
                        "source": "::/0"
                },
                {
                        "target": "2602:n00t:yours::8f::1",
                        "mask": 64,
                        "nexthop": "::",
                        "source": "::/0"
                },
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "::",
                        "source": "::/0"
                },
                {
                        "target": "0.0.0.0",
                        "mask": 0,
                        "nexthop": "0.0.0.0",
                        "source": "0.0.0.0/0"
                }
        ],
        "dns-server": [

        ],
        "dns-search": [

        ],
        "neighbors": [

        ],
        "inactive": {
                "ipv4-address": [

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [

                ],
                "dns-search": [

                ],
                "neighbors": [

                ]
        },
        "data": {

        }
}

Are using wireguard as default gateway? It seems that way. Is the vps configured to do NAT66?

1 Like

Are using wireguard as default gateway? It seems that way. Is the vps configured to do NAT66?

I am trying to route all my traffic on LAN to the wireguard VPS- I am trying to avoid NAT66 at all costs. The only thing I would like openwrt to do is to filter incoming traffic on the tunnel unless explicitly established so my devices on LAN aren't wide open.

On my VPS wireguard gateway I checked and I don't have any ip6tables NAT rules at all. However the address being seen is actually the VPS eth0 interface address - but there is no mangle rule that would change the ip6.src_addr in the packets so I am a bit confused where else to look.

Deleting the first assigned IPv6 address from the /64 from the VPS eth0 interface breaks ip6 traffic routing from internet to the wireguard clients.

  • Request a /56 GUA or a routable /64 GUA prefix on the WG server.
  • Disable the WAN prefix delegation on the router.
  • Delegate a /64 GUA prefix over the WG tunnel to the router.
  • The WG tunnel itself can use a ULA prefix.
uci set network.vpn.ip6prefix="64_GUA_PREFIX"
uci set network.lan.ip6class="local vpn"
uci commit network
/etc/init.d/network restart
1 Like

Thanks - I found the issue it was a configuration at VPS side. Unfortunately VPS provider does not give a "routed IPv6 /64" block - so I have do tricks to circumvent neighbor discovery protocol.

Anyways - the original problem was that I missed an old ip6tables rule on the VPS causing all this headache - removed it and now IP works properly.

I do have an issue in OpenWRT after rebooting - the openwrt does not know where to send packets to the LAN segment which has the public IPv6 /64 - there is this mysterious loopback route (unreachable 2602::xx:xx:8f::/64 dev lo proto static metric 2147483647 error 4294967148 pref medium) but I don't know how this route is being created at boot?

64 bytes from 2607:f8b0:4008:812::200e: seq=33 ttl=121 time=56.834 ms
64 bytes from 2607:f8b0:4008:812::200e: seq=34 ttl=121 time=45.729 ms
^C
--- google.com ping statistics ---
35 packets transmitted, 35 packets received, 0% packet loss
round-trip min/avg/max = 34.267/61.223/199.603 ms
root@5gpocket:~# ping 2602::xx:xx:8f:e192:18a2:d720:8ae1
PING 2602:xx:xx:8f:e192:18a2:d720:8ae1 (2602::xx:xx:8f:e192:18a2:d720:8ae1): 56 data bytes
^C

2 packets transmitted, 0 packets received, 100% packet loss
root@5gpocket:~# ip route get 2602::xx:xx:8f:e192:18a2:d720:8ae1
2602:xx:xx:8f:e192:18a2:d720:8ae1 from :: dev vpsgw proto static src 2602::xx:xx:106:8888::10 metric 1024 pref medium
root@5gpocket:~# ip -6 r
:: via 2602::xx:xx:106:8888::1 dev vpsgw proto static metric 1024 pref medium
2602::xx:xx:8f::/64 dev vpsgw proto static metric 1024 pref medium
unreachable 2602::xx:xx:8f::/64 dev lo proto static metric 2147483647 error 4294967148 pref medium
2602::xx:xx:106:8888::/112 dev vpsgw proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0.2 proto kernel metric 256 pref medium
fe80::/64 dev br-lan proto kernel metric 256 pref medium
fe80::/64 dev wlan0 proto kernel metric 256 pref medium
fe80::/64 dev wlan1 proto kernel metric 256 pref medium
default dev vpsgw proto static metric 1024 pref medium

I can manually fix the routing issue and have working IPv6 on the public /64 space if I do this:

ip -6 route del 2602::xx:xx::8f::/64
ip -6 route add 2602::xx:xx::8f::/64 dev br-lan

but i rather find the root cause why these routes aren't coming up automatically and the mystery of the loopback /64 route?

Note that using multiple :: in a single IPv6 address/prefix is not allowed.
Did you try the ip6prefix option as mentioned above?
Check the updated status:

ifstatus vpsgw
1 Like

I think "::" may only be used at the last part of the address only (I did lazy copy paste to obfuscate my real ipv6 segment) but let me know if you spotted this somewhere I missed?

here is the status

root@5gpocket:~# ifstatus vpsgw
{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "dynamic": false,
        "uptime": 3326,
        "l3_device": "vpsgw",
        "proto": "wireguard",
        "updated": [
                "addresses",
                "routes"
        ],
        "metric": 0,
        "dns_metric": 0,
        "delegation": true,
        "ipv4-address": [
                {
                        "address": "10.100.100.10",
                        "mask": 24
                }
        ],
        "ipv6-address": [
                {
                        "address": "2602:x:x:106:8888::10",
                        "mask": 112
                }
        ],
        "ipv6-prefix": [

        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "::",
                        "source": "::/0"
                },
                {
                        "target": "0.0.0.0",
                        "mask": 0,
                        "nexthop": "0.0.0.0",
                        "source": "0.0.0.0/0"
                }
        ],
        "dns-server": [

        ],
        "dns-search": [

        ],
        "neighbors": [

        ],
        "inactive": {
                "ipv4-address": [

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [

                ],
                "dns-search": [

                ],
                "neighbors": [

                ]
        },
        "data": {

        }
}

and /etc/config/network

# cat /etc/config/network

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix '2602:x:x:8f::/64'

config interface 'lan'
        option type 'bridge'
        option ifname 'eth0.1'
        option proto 'static'
        option netmask '255.255.255.0'
        option ipaddr '192.168.8.1'
        option ip6assign '64'

config interface 'wan'
        option ifname 'eth0.2'
        option proto 'dhcp'

config interface 'wan6'
        option ifname 'eth0.2'
        option proto 'dhcpv6'

config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '2 3 0t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '1 0t'

config interface 'wwan'
        option proto 'dhcp'

config interface 'vpsgw'
        option proto 'wireguard'
        option private_key 'derp'
        list addresses '10.100.100.10/24'
        list addresses '2602:x:x:106:8888::10/112'
        option mtu '1300'

config wireguard_vpsgw
        option public_key 'derp'
        option description 'VPS'
        option persistent_keepalive '19'
        option endpoint_port '88'
        option preshared_key 'derp'
        option endpoint_host '158.x.x.x'
        option route_allowed_ips '1'
        list allowed_ips '::/0'
        list allowed_ips '0.0.0.0/0'
1 Like

I think I may have found the root cause - did a few reboots and now my openwrt router comes up and my LAN clients get IPv6 from the wireguard tunnel and are able to communicate.

I think my mistake was that in luci > wireguard > peers config I had set allowed IPs the IPv6 /64 block that is supposed to be on LAN. I removed it leaving only "::0" and "0.0.0.0/0"

Now my openwrt routing table seems to be normal by itself. The only culprit I seem to have is that at boot time - my default route becomes vpsgw (wireguard client) and there is no routing to the destination server. This may be because I am using WWAN and there's a delay :confused:

1 Like

You can try to mitigate the issue using custom metric and/or hotplug:

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.