Please help: domain-based bypass of Wireguard VPN

I have a GL-AR750S-Ext running OpenWrt 22.03.2. I've set up Mullvad VPN over Wireguard following Mullvad's own help guide, and ZeroTier for easy "local" access to a couple of remote systems that are otherwise hard to connect with (behind CG-NAT, etc).

It will be used as a "travel router" for the most part -- something I can connect to any other internet source through and automatically have no-configuration-needed Mullvad VPN and access to my ZeroTier. In other words, it will almost always be behind a primary router of some kind so I'll end up with double-NAT, but for my purposes that really doesn't matter. Both Mullvad and ZeroTier seem to work perfectly at present.

However, there is ONE essential website that I need access to but I cannot use a VPN while doing so. The site is behind CloudFlare so the IP address changes frequently and the same IPs serve other sites as well (in other words, I can't use an ipsets solution that I've seen guides for).

I need a way to bypass Wireguard for that one domain in a browser (actually, two domains so I can use something like ipleak.net to verify) and nothing else. This is a guide for almost exactly what I need:

But it is not specific to OpenWrt and the assumed arrangment of devices is slightly different from mine. Plus, it brushes over the filtering aspect completely. I don't know the fundamentals well enough to adapt it to my use case (after bashing my head against it for a while).

Would anyone be willing to modify that guide specifically for OpenWrt, with slightly more detail on aspects like the new routing table and domain filtering? If there's an alternative, lighter HTTP(S) proxy that could do the same thing rather than Squid, that would be ideal as well (I played around with TinyProxy but it doesn't look like it can mark the packets?).

Thank you in advance for any help.

You need policy based routing for this.

But doesn't that use the ipsets solution under the hood? Building an ipset of IPs resolved from the domain which then ALL end up whitelisted for some duration? That could inadvertently allow traffic to other CloudFlare-gatewayed sites, couldn't it?

EDIT: When I say "whitelisted", I mean bypassing the VPN.

EDIT 2: I read through the documentation for PBR (https://docs.openwrt.melmac.net/pbr/) and it really doesn't look like the ideal method for my purpose. With the proxy method, I use a different browser (technically just a different Firefox profile) for visiting that one site. I keep the bookmark only in that profile so I'll never go there from the normal (VPN'd) profile, and the proxy filter means I can't forget and accidentally visit other sites from the proxy (non-VPN) profile. And it all works strictly on the domain name before any name resolution (if I understand that correctly) so the actual IP address(es) are irrelevant (my concern about overlap in CloudFlare IPs).

Tinyproxy uses by default user nobody to run the service.
This makes it possible to create an ip rule based on uid.

Enable the service and allow access from the local network.

uci set tinyproxy.@tinyproxy[0].enabled='1'
uci add_list tinyproxy.@tinyproxy[0].Allow='192.168.0.0/16' # Change it if your LAN subnet starts with 172. or 10.
uci commit tinyproxy
/etc/init.d/tinyproxy restart

Add the following to /etc/config/network:

config route
        option table '101'
        option interface 'wan'
        option gateway '192.168.101.1' # The correct wan gw here
        option target '0.0.0.0/0'

config rule
        option lookup '101'
        option uidrange '65534'

The annoying part is that the gateway option is required and you have to update its address every time you connect to a new network.

1 Like

Thank you. Can I be confident that nothing else (among the standard components of OpenWrt, Wireguard, and ZeroTier) will run as nobody?

Having to specify/change the gateway address is annoying, but it's an inconvenience I can live with.

Is there anything special about the '101' name/ID for the routing table (not that I have any reason to change it, just out of curiosity)?

EDIT: The above questions aside, this appears to be working correctly. Thank you very much for your help!

Most of the OpenWrt services run as root and the exceptions use a dedicated user.

It is highly unlikely that you will come across another (important) service running as nobody, but you can always check using ps w | grep -v root.

Nothing special.
My custom routing table numbers start from 100 and when I tested the config, 100 was already taken.
You should be able to use any number between 1 and 2^32-1 except 0, 253, 254 and 255.
Also, be careful not to overlap custom routing tables created by other applications (if any), like StrongSwan - 220, Tailscale - 52...

2 Likes

Great, thank you!

1 Like

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