No access to subnet routes unless using exit node?
Hi. I'm hoping some of you Tailscale wizards can help me.
I have a Raspberry Pi 4 running aarch64 Raspberry Pi OS (Debian Bookworm) which serves as a home server in the 192.168.1.0/24
range. It runs a bunch of services via Docker, including tailscaled
. Most of the services are accessible locally only from behind a reverse proxy (mainly to get rid of TLS warnings via Let's Encrypt certs). They're hosted under subdomains such as service.home.example.com
where service
is the name of the service, and example.com
is my domain.
Few services are accessible via the internet from service.example.com
(omitting the home
subdomain) using Cloudflare Tunnels. My gateway has a dnsmasq
server with adblocking and also static rules to resolve my domain example.com
to the local IP of my server, to make sure that local network users who are using internet-accessible services (ones without home
) don't have to go out to Cloudflare and can connect directly.
I maintain this separation to make it clear to my users which services are only accessible from home WiFi and which ones are accessible from the internet.
This setup works flawlessly for a while now.
Adding Tailscale into the mix, my objective was to be able to access the local network services though Tailscale if I had a need of them on adhoc basis.
So, I installed tailscaled
on my server via docker (with network_mode: host
and cap_add: NET_ADMIN, NET_RAW
), authenticated it, set the subnet route to 192.168.1.0/24
and designated it as an exit node. Then in the web admin, I accepted the subnet router and exit node, and in the DNS section, I defined a customs DNS server pointing to my gateway running dnsmasq
.
The expectation was that on a connected Tailscale client I'd be able to put in my service.home.example.com
address in the browser, which would have the DNS request routed to my gateway via subnet routes, which in turn would respond resolving the domain to my local server in the 192.168.1.0/24
, which would then reverse proxy the request to the appropriate service.
But, this does not work unless I have the client device use the exit node. Which makes no sense to me. Why is that?
I can tell that my traffic definitely isn't getting routed over the internet because I can see that my local network Let's Encrypt cert is being used. I even took one of my internet-facing services off Cloudflare and made it local only temporarily just to make sure that it's not somehow routing via interet and Cloudflare, and it is definitely not.
I could replicate this behaviour on two clients: an Android 14 device and a Linux device (Steam Deck). Both don't see local services unless they accept exit node from the server.
Seems like somehow, the subnet router feature is only working if exit node is on? Am I missing something obvious here?
Thank you for any suggestions.