Tailscale not working when openwrt router connected to vpn

My setup is,

I have openwrt 24.10.3 running on a Raspberry Pi 1 Model B with wireguard client setup to do always connect to remote VPN server (wireguard server running on oracle cloud VPS)

I also have a headscale server setup on this oracle cloud VPS
I did tailscale up --login-server=https://xxxx.ddns.net:xxx" on openwrt router and it joined headscale network and I could see it being online on headscale node list command.

But after I restarted openwrt, tailscale not connected. If I bring down wg0 interface then tailscale connects.

Any thoughts?

root@OpenWrtVPN:~# ip route show
default dev wg0 proto static scope link metric 10
default via 192.168.1.1 dev eth1 proto static src 192.168.1.103 metric 100
10.148.170.0/24 dev wg0 proto static scope link metric 10
192.168.1.0/24 dev br-lan proto kernel scope link src 192.168.1.10
192.168.1.0/24 dev eth1 proto static scope link metric 100
root@OpenWrtVPN:~# telnet google.com 443
Trying 2404:6800:4007:800::200e...
Connected to google.com.
Escape character is '^]'.

root@OpenWrtVPN:~# telnet 8.8.8.8 443
Trying 8.8.8.8...
Connected to 8.8.8.8.
Escape character is '^]'.

root@OpenWrtVPN:~# telnet xxxxx.ddns.net xxxx
Trying xx.xx.xxx.xx...
Connected to xxx.ddns.net.
Escape character is '^]'.
^]

But no response on,

root@OpenWrtVPN:~# tailscale up --login-server=https://xxxx.ddns.net:xxx

it will work if I bring down wg0 interface,

root@OpenWrtVPN:~# tailscale up --login-server=https://xxxx.ddns.net:xxxx

To authenticate, visit:

        https://xxxx.ddns.net:xxx/register/xxxx

Some thoughts on the main routing table:

  1. The lan and wan interfaces are on the same ip subnet. You need to fix this.
  2. There is no explicit route for the remote wireguard endpoint via the wan interface. Is there a nohostroute '1' option in the wireguard interface section?
1 Like

I have changed lan to 192.168.10.1
Below is full network config, I could not find a nohostroute in that.

root@OpenWrtVPN:~# cat /etc/config/network

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

config globals 'globals'
        option ula_prefix 'fdf8:c549:681f::/48'
        option packet_steering '1'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'eth0'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.10.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option proto 'dhcp'
        option device 'eth1'
        option metric '100'

config interface 'wan6'
        option proto 'dhcpv6'
        option reqprefix 'auto'
        option device '@wan'

config interface 'wg0'
        option proto 'wireguard'
        option private_key 'xxxx'
        list addresses '10.148.170.3/24'
        list addresses 'fd11:5ee:bad:c0de::a94:aa03/64'
        option metric '10'

config wireguard_wg0
        option public_key 'xxx'
        option preshared_key 'xxx'
        option endpoint_host 'xxx.xxx.freeddns.org'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '0.0.0.0/0'
        list allowed_ips '::/0'

config route
        option interface 'wg0'
        option target '0.0.0.0'
        option netmask '0.0.0.0'
        option metric '10'

When all traffic is routed over the wireguard interface, the presence of a route for the remote endpoint through the wan interface is crucial.

Since the remote endpoint is defined by a domain name and you say it doesn't work after a reboot, it's likely that the name couldn't be resolved initially and the static route couldn't be created automatically.

Run ifup wg0 after reboot and check the routing table again. If there is no change, run these commands, first correcting the redacted domain name.

vpsip=$(nslookup -type=a xxx.ddns.net | awk -F': ' 'NR==6 { print $2 } ')
ip route add $vpsip via 192.168.1.1

Also, you could optimize the configuration.

Remove this :backhand_index_pointing_up:and add option route_allowed_ips '1' to the wireguard_wg0 section.

1 Like

Maybe not related (althoug it migh be) but you already set a metric of 10 on the WG interface so if you enable Route Allowed IPs on the WG peer you should be able to remove the following rule:

Note that your WG interface and router support IPv6 but the default metric for IPv6 is 1024 so if you are using IPv6 check the IPv6 metrics

Edit: sorry did not see that it was already taken care of by @pavelgl

1 Like

@pavelgl @egc
I removed

config route
        option interface 'wg0'
        option target '0.0.0.0'
        option netmask '0.0.0.0'
        option metric '10'

Added option route_allowed_ips '1' to the wireguard_wg0
Rebooted router.
And tried, tailscale up --login-server=https://xxx.xxx.net:xxx This time it worked. Tested rebooting again, and tailscale become online.

Though it is online, I cant seem to reach the vpn router using its tailscale ip (http://100.64.0.17/) from another machine that is also on same tailscale network.

I have full dual stack at all my locations so no need to use a commercial third party like tailscale, I use WireGuard to connect from outside so cannot help you with tailscale.
But usually traffic which comes in via an interface e.g. tailscale has to go out via that same interface.

As you have it now you have your default route via the WireGuard client, so tailscale traffic might be going out via the "wrong" WG interface.
What is it you want to route via the WireGuard client?

Why are you using metrics and keep the default route via the WAN (although) with a higher metric?

I am prepping this vpn router for my brother to use at his place in Qatar. Where whenever he and his family connect their phones to this router, those devices internet traffic will go via vpn. Also those devices public ip will be same as vpn servers public ip.

I want to setup tailscale on this vpn router, so that from my place (India), I can access this router for maintenance (even if vpn is not connected on the router).

I honestly don't know why I use metrics, I did so after some searching and apparently it seems to made the vpn router work.
If it helps, below are full list of commands I run to set it up.

create wan6 (because my VPN server only got IPv6 public ip)

uci set network.wan6=interface
uci set network.wan6.ifname='@wan'
uci set network.wan6.proto='dhcpv6'
uci set network.wan6.reqprefix='auto'
uci commit network
/etc/init.d/network restart

Configure WireGuard interface

uci set network.wg0='interface'
uci set network.wg0.proto='wireguard'
uci set network.wg0.private_key='xx/xx+xx='
uci add_list network.wg0.addresses='10.148.170.3/24'
uci add_list network.wg0.addresses='fd11:5ee:bad:c0de::a94:aa03/64'
uci set network.wg0.metric='10'

Configure WireGuard peer

uci add network wireguard_wg0
uci set network.@wireguard_wg0[-1].public_key='xxx+xx+xx='
uci set network.@wireguard_wg0[-1].preshared_key='xx/A='
uci set network.@wireguard_wg0[-1].endpoint_host='xx.xxx.freeddns.org'
uci set network.@wireguard_wg0[-1].endpoint_port='51820'
uci set network.@wireguard_wg0[-1].persistent_keepalive='25'
uci add_list network.@wireguard_wg0[-1].allowed_ips='0.0.0.0/0'
uci add_list network.@wireguard_wg0[-1].allowed_ips='::/0'

Lower WAN priority so VPN wins

uci set network.wan.metric='100'

Configure firewall zone for VPN

uci add firewall zone
uci set firewall.@zone[-1].name='vpn'
uci set firewall.@zone[-1].input='ACCEPT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='ACCEPT'
uci set firewall.@zone[-1].masq='1'
uci add_list firewall.@zone[-1].network='wg0'

Allow LAN → VPN forwarding

uci add firewall forwarding
uci set firewall.@forwarding[-1].src='lan'
uci set firewall.@forwarding[-1].dest='vpn'

Save & apply

uci commit network
uci commit firewall
/etc/init.d/network restart

Restart Firewall

/etc/init.d/firewall restart

To which firewall zone is device tailscale0 assigned?
Can you ping this address?

This?

So from vpn router itself, I can ping the ip,

But from another machine which is also part of the same tailscale network and is online. I cannot ping it. From this machine I am to ping/access other tailscale clients.

So the device is not assigned to any zone and the default firewall input policy is set to reject.

Considering the tailscale network as trusted:

uci add_list firewall.@zone[0].device='tailscale0'
uci commit firewall
fw4 restart
1 Like

That worked.
Based on what we did here. I rewrote the instructions. Could you please review once?

create wan6

uci set network.wan6=interface
uci set network.wan6.ifname='@wan'
uci set network.wan6.proto='dhcpv6'
uci set network.wan6.reqprefix='auto'
uci commit network
/etc/init.d/network restart

Configure WireGuard interface

uci set network.wg0='interface'
uci set network.wg0.proto='wireguard'
uci set network.wg0.private_key='xx/xx+xx='
uci add_list network.wg0.addresses='10.148.170.3/24'
uci add_list network.wg0.addresses='fd11:5ee:bad:c0de::a94:aa03/64'
uci set network.wg0.metric='10'

Configure WireGuard peer

uci add network wireguard_wg0
uci set network.@wireguard_wg0[-1].public_key='xxx+xx+xx='
uci set network.@wireguard_wg0[-1].preshared_key='xx/A='
uci set network.@wireguard_wg0[-1].endpoint_host='xx.xxx.freeddns.org'
uci set network.@wireguard_wg0[-1].endpoint_port='51820'
uci set network.@wireguard_wg0[-1].route_allowed_ips='1'
uci set network.@wireguard_wg0[-1].persistent_keepalive='25'
uci add_list network.@wireguard_wg0[-1].allowed_ips='0.0.0.0/0'
uci add_list network.@wireguard_wg0[-1].allowed_ips='::/0'

Lower WAN priority so VPN wins

uci set network.wan.metric='100'

Configure firewall zone for VPN

uci add firewall zone
uci set firewall.@zone[-1].name='vpn'
uci set firewall.@zone[-1].input='ACCEPT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='ACCEPT'
uci set firewall.@zone[-1].masq='1'
uci add_list firewall.@zone[-1].network='wg0'

Allow LAN → VPN forwarding

uci add firewall forwarding
uci set firewall.@forwarding[-1].src='lan'
uci set firewall.@forwarding[-1].dest='vpn'

Save & apply

uci commit network
uci commit firewall
/etc/init.d/network restart

Restart Firewall

/etc/init.d/firewall restart

join headscale

tailscale up --login-server=https://xx.xx.net:xx

Add tailscale to firewall zone.

uci add_list firewall.@zone[0].device='tailscale0'
uci commit firewall
fw4 restart

This will generate the configuration you currently have.

1 Like

@pavelgl

thank you this worked for me

@pavelgl

Occasionally ,

Even when tailscale is active on OpenWrt vpn router (headscale nodes list shows the OpenWrt vpn is online),
From other tailscale clients, I cannot ping 100.64.0.17 successfully.
From my headscale server, I can ping 100.64.0.17 successfully

Here is tailscale status output from one of the tailscale client, 100.64.0.17 status shows different than others.

pi@tcrpi:~ $ tailscale status
100.64.0.20     tcrpi                simon        linux   -
100.64.0.23     cmf                  simon        android offline
100.64.0.7      dell                 simon        windows offline
100.64.0.18     dual-stack           simon        linux   -
100.64.0.19     headscale            simon        linux   -
100.64.0.11     hisense              simon        android offline
100.64.0.9      ipadnew              simon        iOS     offline
100.64.0.15     ipadold              ipad         iOS     offline
100.64.0.16     iphone               iphone       iOS     offline
100.64.0.28     jthinkpad            simon        windows offline
100.64.0.4      jtv                  simon        android offline
100.64.0.12     m31                  simon        android offline
100.64.0.1      mypc                 mypcblr      windows offline
100.64.0.17     openwrtvpn           simon        linux   active; relay "blr", tx 19344 rx 0
100.64.0.10     pi5server            simon        linux   offline
100.64.0.2      pinas                simon        linux   offline
100.64.0.25     pitv                 simon        android offline
100.64.0.26     tcr-pc               simon        windows -
100.64.0.5      tcrtv                simon        android offline
100.64.0.8      ubuntu-server        simon        linux   offline

I stopped wg interface on OpenWrt vpn and 100.64.0.17 become ping success from all tailscale clients.

Then I start wg interface again, and still 100.64.0.17 become ping success from all tailscale clients.

I think 100.64.0.17 ip will go unresponsive again after some time. And a restart of wg interface will get it reachable again. I thought tailscale is not going through wg but directly via wan?

I am not able to figure out this behaviour.

If I understand correctly, headscale and the wireguard "server" are running on the same machine. If the discussed static route exists, both connections should be established through the wan interface.

Well, this is your network, it's up to you to debug it.

Since you are using ddns, I assume the VPS does not have a static IP. Does the address change often?

Check the routing table when it happens again. Run the suggested commands without restarting the wireguard interface to see if that makes a difference.

yes headscale and wireguiard server run on same vps machine.

VPS does have static public ip and does not change at all.

Right now, ping is successful to 100.64.0.17 from other tailscale clients, but still posting here,

root@OpenWrtVPN:~# vpsip=$(nslookup -type=a xxx.ddns.net | awk -F': ' 'NR==6 { print $2 } ')
root@OpenWrtVPN:~# echo $vpsip
xx9.1x9.2xx.x9
root@OpenWrtVPN:~# ip route add $vpsip via 192.168.1.1
RTNETLINK answers: File exists

When I observe the issue again, I will try the command again.

In that case replace the domain name with the IP address.

ipv6.xxxxxxx.freeddns.org is pointed to a static public IPv6 address. Does it make difference by specifying that IPv6 address instead of host?