Routing ipv6 private addreses outside the lan

Hi!

I have a x86_64 box running the latest snapshot, and I installed tailscale as the documentation said : https://openwrt.org/docs/guide-user/services/vpn/tailscale/start#initial_setup
I configured the unmanaged interface and I created the same firewall rule as the documentation.

All is working well except using ipv6. I can ping any device from my tailnet via ipv4 or ipv6 directly from the router, so it seems that there is no problem with tailscale or openwrt.

I have no problem connecting with other tailscale devices from my lan but only via ivp4.
It seems like the firewall rule only applied to ipv4? I'm a bit lost, as I thought that any traffic coming going to the tailscale interface (ipv4/6) should be redirected to that zone.

It's probably some configuration that I missing, because I'm not so familiar with ipv6, so if anyone knows what may be happening I would appreciate your help.

Thanks!

Here is my firewall config:

 cat /etc/config/firewall 

config defaults
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option synflood_protect '1'

config zone
        option name 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        list network 'lan'

config zone
        option name 'wan'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'
        list network 'wan'
        list network 'wan_6'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone
        option name 'tailscale'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        option masq '1'
        option mtu_fix '1'
        list network 'tailscale'

config forwarding
        option src 'lan'
        option dest 'tailscale'

Do you mean IPv6 doesn’t work while using the exit node?

You need to share some of your IPv6 details like what prefix you get, using relay mode or not, etc.

Post the output of ifstatus wan6

I mean that I can not even ping my other tailscale devices from my lan, but I can from the router.

In my router:

# ping ipv6_of_device
PING ipv6_of_device (ipv6_of_device): 56 data bytes
64 bytes from ipv6_of_device: seq=0 ttl=64 time=27.540 ms
64 bytes from ipv6_of_device: seq=1 ttl=64 time=18.366 ms
64 bytes from ipv6_of_device: seq=2 ttl=64 time=18.210 ms
64 bytes from ipv6_of_device: seq=3 ttl=64 time=19.189 ms
^C
--- ipv6_of_device ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 18.210/20.826/27.540 ms

# ping ipv4_of_device
PING ipv4_of_device (ipv4_of_device): 56 data bytes
64 bytes from ipv4_of_device: seq=0 ttl=64 time=18.659 ms
64 bytes from ipv4_of_device: seq=1 ttl=64 time=17.548 ms
64 bytes from ipv4_of_device: seq=2 ttl=64 time=17.967 ms
64 bytes from ipv4_of_device: seq=3 ttl=64 time=18.043 ms
^C
--- ipv4_of_device ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 17.548/18.054/18.659 ms


In my pc:

$ ping ipv6_of_device
PING ipv6_of_device (ipv6_of_device) 56 data bytes
^C
--- ipv6_of_device ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3040ms


$ ping ipv4_of_device
PING ipv4_of_device (ipv4_of_device) 56(84) bytes of data.
64 bytes from ipv4_of_device: icmp_seq=1 ttl=63 time=18.2 ms
64 bytes from ipv4_of_device: icmp_seq=2 ttl=63 time=20.0 ms
64 bytes from ipv4_of_device: icmp_seq=3 ttl=63 time=18.9 ms
64 bytes from ipv4_of_device: icmp_seq=4 ttl=63 time=18.0 ms
^C
--- ipv4_of_device ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 18.019/18.808/20.047/0.792 ms

Configuration:

The same pattern of letters means that that part of the ipv6 was the same in different fields

# ifstatus wan_6
{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "dynamic": false,
        "uptime": 32999,
        "l3_device": "pppoe-wan",
        "proto": "dhcpv6",
        "device": "pppoe-wan",
        "metric": 0,
        "dns_metric": 0,
        "delegation": true,
        "ipv4-address": [

        ],
        "ipv6-address": [
                {
                        "address": "aaaabbbb",
                        "mask": 128
                }
        ],
        "ipv6-prefix": [
                {
                        "address": "aaaacccc",
                        "mask": 56,
                        "class": "wan_6",
                        "assigned": {
                                "lan": {
                                        "address": "aaaacccc:",
                                        "mask": 60
                                }
                        }
                }
        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "fe80::1",
                        "metric": 512,
                        "valid": 1548,
                        "source": "aaaacccc::/56"
                },
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "fe80::1",
                        "metric": 512,
                        "valid": 1548,
                        "source": "aaaabbbb/128"
                }
        ],
        "dns-server": [
                "2620:119:35::35",
                "2620:119:53::53",
                "2606:4700:4700::64",
                "2606:4700:4700::6400"
        ],
        "dns-search": [

        ],
        "neighbors": [

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

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [
                        "2a0c:5a80:0:2::1",
                        "2a0c:5a84:0:2::1"
                ],
                "dns-search": [

                ],
                "neighbors": [

                ]
        },
        "data": {
                "passthru": "redacted_just_in_case"
        }
}

Are you seeing the same issue in any other device like your smartphone?

Yep, same behavior.
If I connect to tailscale directly with the app (wifi and 5g) I can ping the devices. If I am behind the router I can not.
It's something probably related to the configuration of ipv6.
My service provider gives me aaaacccc ipv6 and my tailscale has a totaly different ipv6.
This is the ip that tailscale gave to my device.

fd7a:xx:xx:xx:xx:xx:xx:xx/128 scope global

Its probably a ipv6 in the private space (?) I'm not sure, the ipv4 is 100% private as it is 100.xx.xx.xx.

Maybe it has something to do with that (?) being a private address the router decides not to route it outside the lan (?).

Thanks.

Edit:

I tailscale0 also gets a link-local address (or I least I think it is) because it also reports:

fe80::xx:xx:xx:xx/64 scope link flags 800

Post the output of tailscale netcheck and
cat /etc/config/dhcp

Also on your devices verify that you are receiving IPv6 address from the router by visiting a website like this
https://ipquail.com/

The output is :

# tailscale netcheck

Report:
        * UDP: true
        * IPv4: yes, 86.xx.xx.xx:port
        * IPv6: yes, [2a0c:xx:xx:xx::1]:port2
        * MappingVariesByDestIP: false
        * PortMapping: 
        * Nearest DERP: Madrid
        * DERP latency:
                - mad: 5.8ms   (Madrid)
                - par: 23.8ms  (Paris)
                - ams: 30.7ms  (Amsterdam)
                - lhr: 31.3ms  (London)
                - fra: 32.5ms  (Frankfurt)
                - waw: 53.5ms  (Warsaw)
                - nyc: 90ms    (New York City)
                - ord: 103.9ms (Chicago)
                - tor: 110ms   (Toronto)
                - dbi: 114.1ms (Dubai)
                - mia: 117.2ms (Miami)
                - dfw: 119.7ms (Dallas)
                - den: 122.7ms (Denver)
                - sfo: 145.9ms (San Francisco)
                - sea: 150.5ms (Seattle)
                - lax: 155.2ms (Los Angeles)
                - sin: 160.4ms (Singapore)
                - blr: 175.1ms (Bangalore)
                - hkg: 182.1ms (Hong Kong)
                - hnl: 192.5ms (Honolulu)
                - jnb: 193ms   (Johannesburg)
                - nai: 202.4ms (Nairobi)
                - sao: 214.1ms (São Paulo)
                - tok: 239ms   (Tokyo)
                - syd:         (Sydney)

# cat /etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'
        list rebind_domain 'mydomain.mydomain'


config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option dhcpv6 'server'
        option ra 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

And yep I got ipv6 in the devices. ipquail shows all fields except IPv6 PTR.

Also my computer gets:

enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether [mac] brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.80/24 brd 192.168.1.255 scope global noprefixroute enp4s0
       valid_lft forever preferred_lft forever
    inet6 fd00:xx:xx::xx/128 scope global dynamic noprefixroute 
       valid_lft 40996sec preferred_lft 40996sec
    inet6 2a0c:xx:xx:xx::xxx8/128 scope global dynamic noprefixroute 
       valid_lft 40996sec preferred_lft 40996sec
    inet6 2a0c:xx:xx:xx:xx:xx:xx:xxxb/64 scope global noprefixroute 
       valid_lft forever preferred_lft 604776sec
    inet6 fd00:xx:xxx:xx:xx:xx:xx:xxxc/64 scope global noprefixroute 
       valid_lft forever preferred_lft 604776sec
    inet6 fe80::xx:xx:xx:xxx0/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

Okay I think I know what the problem is:

Tailscale can communicate via ivp4 because the router it is doing some kind of nat.

When I use ipv6, tailscale has a private network address outside the lan, and because the router does not do any nat, I can not connet to outside devices.

Is there any way that I can can try to route ipv6 private addresses via the tailscale interface?

1 Like

I have encountered the same problem. If the trouble is solved, please tell me how you solved it.

The masq6 option on a firewall zone will cause IPv6 packets to be NATd to the interface's IP the same as v4 works.

If you don't masquerade, the router at the other end of the tunnel needs to have a route back to your local LAN. When using ULAs for inter-site links, all the site lans should be in the same /48. The first 48 bits are a random number (but the same for all of your sites) then the next 16 bits define /60s /64s etc for each site.

In fact, using the masq6 options works as expected!

I don't know if is the right way to do it as ipv6 is supposed to eliminate nat but yeah it works.

https://openwrt.org/docs/guide-user/network/ipv6/ipv6.nat6#firewall