Routing traffic to specific domain via VPN

Hi,
RPi4 with OpenWRT and additional USB3 adapter. What I want to achieve is to route outbound traffic that goes to specific domain (let's say *.cnn.com) from lan zone via VPN channel, allowing rest of the traffic to go directly to WAN.
I installed ip set packages and followed this tutorial: https://openwrt.org/docs/guide-user/firewall/fw3_configurations/dns_ipset.

  1. I don't understand what should be the content of /etc/firewall.ipsetdns file ?
  2. I don't understand the "uci add_list dhcp.@dnsmasq[0].server="/example.com/127.0.0.1#53001"" command. According to another examples "dhcp.@dnsmasq[0].server" setting controls DNS queries forwarding (see https://openwrt.org/docs/guide-user/base-system/dhcp_configuration). I don't need to modify DNS resolution.
  3. Is it possible to capture *.cnn.com, or I'll have to add all relevant specific subdomains to the set ?
  4. How should I configure the routing-to-vpn part ? via firewall rule in /etc/firewall.user using match to ip set by name and redirecting traffic to the VPN tunnel? How this tunnel should be identified in the rule?

It will be easier to use pbr package.

3 Likes

Thanks, yes, looks like this is the wheel I was trying to reinvent :slight_smile:

1 Like

Almost there :slight_smile: One question:
When I use VPN as a default gateway, and via policy redirects traffic from rest of the network to WAN - it works.

When I invert the setting (VPN is not default gateway, and only specific nodes are redirected to VPN), I see that traffic itself is redirected, but not DNS queries from the router (i.e. when I play youtube on VPN-ed device I see significant traffic on tun0).

If I set those "to-be-vpned nodes" to use upstream DNS server directly, and bypass dnsmask instance on OpenWRT - it works (as their queries go through VPN channel), but if I use a default configuration, when dnsmask gives itself as a DNS, it doesn't work (queries are resolved, but via wrong channel).

I tried to set a policy for lan address of OpenWRT, wan address of OpenWRT and for 127.0.0.1 as local addresses, and got errors when activating the policy.

I tried to set a policy for DNS server as a remote address, it doesn't raise an error but still doesn't work.

So - what should I do to redirect DNS queries from the router itself ?

Marking outgoing traffic from the router is problematic, specifically UDP which includes DNS.
A possible workaround is to set up a public DNS provider with DHCP.

Do you mean propagate upstream DNS server directly down to dhcp clients? Yes, obviously this works, this is what I use meanwhile.

1 Like

Yep, you can apply this globally or selectively only to clients that need VPN.
Another option is to route all outgoing DNS traffic from the router to the VPN with PBR.

1 Like

This rule works fine for me to direct traffic towards a dns via the vpn.

config policy
        option name 'gdns'
        option dest_addr '8.8.4.4'
        option proto 'all'
        option chain 'OUTPUT'
        option interface 'proton'

Keep in mind that for router generated traffic you need to use the output chain, not prerouting.

1 Like

Slowly advancing toward fully working solution.
OpenWRT is configured as simple gateway (no DNSMASQ is running). There is another DNSMASQ server on the network.
I can get OpenWRT to route traffic via VPN (which is a default gateway for it), or via WAN, based on destination host names. What I can't do is to define a policy for, for instance youtube.com, which will capture also all subdomains of youtube.com (api.youtube.com, video.youtube.com and so on).
I got an impression that it is supported by ipsets, but can't get it working.
Any ideas ?

Thanks, I found a workaround but will try your suggestion later.

Populating IP sets relies on the selective DNS forwarding provided by locally running Dnsmasq.

1 Like

I would understand if domain based rules wouldn't work at all, but they work for specific domains.

Actually, after I manually mapped all specific domains (I just run tcpdump and analyzed pcap with Wireshark to see all dns requests) I got everything working, but I don't like it.

OK, so would it be enough to just run dnsmask on the Openwrt (with dhcp disabled as I have another dhcp server) , or I must actually use it as a dns for relevant lan nodes, and instead of passing public dns via dhcp option down to nodes specify this dns as an upstream DNS resolver for dnsmask?

DNS requests originated by dnsmask will be routed via VPN as it has to be, so it should work.

You can use a similar method on your main DNS server to forward those domains and their subdomains to OpenWrt where you run ipset-dns to populate IP sets, but this may require DNAT/SNAT since ipset-dns binds to IPv4 localhost only.

I'll try to run dnsmasq on OpenWRT for nodes that should go via VPN, and use my existing dnsmasq for the rest. OpenWRT has VPN as a default gateway, so all queries that it sends to upstream servers will go via VPN (now they are sent directly by nodes to upstream DNS, bypassing OpenWRT). For "normal" nodes nothing will change.

Another question about dnsmasq (just curious) - is it possible to make it use different upstreams servers based on the node who sends the query ? I know that it is possible for different queried domains (server=/facebook.com/8.8.8.8), but is it possible specify different upstream servers based on the query source mac/ip/subnet ?

It could be done using running multiple instances listening on multiple ports, and putting some routing between dnsmasq instances and querying nodes, but it sounds ridiculous.

1 Like

Yep, this is possible, but cumbersome:

Then setting up custom DNS forwarders/resolvers for each instance, intercepting DNS traffic with firewall from specific hosts and redirecting it to specific ports.

The other way is to bypass Dnsmasq by offering specific upstream DNS with individual DHCP options.

2 Likes

The other way is to bypass Dnsmasq by offering specific upstream DNS with individual DHCP options.

This is what I have now, but then ipsets are not populated, and VPN routing policies work only for toplevel domains.

So I have to pass everything via dnsmasq (in my case - everything that comes from nodes that have to be vpn-ed ), including DNS queries which will populate ipsets, then use polices to route some traffic via WAN, as you suggested yesterday. Will try it tonight.

1 Like

Ok, got it working.
The problem was related to my missing the statement that only "domain-only" policies are resolved via ipset. I tried to define policies that capture specific nodes in addition to specific top level domains, and that is not supported.
So policiy "192.168.1.0/24, youtube.com, WAN" captures only youtube.com, but policy ", youtube.com, WAN" captures *.youtube.com

Thanks everyone for your help and patience :slight_smile:

2 Likes

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

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