Names resolve to addresses, and those addresses can land in a firewall set that later influences routing, which makes name-based steering possible without a proxy. The catch is that four components have to hand off correctly: the resolver, the set, the classifier that marks a new flow, and the peer that carries it. Each handoff fails differently and each one keeps its own time.

Treat the design as a chain rather than a configuration. The question at every step is which component owns the decision and what happens when its input is missing.

What the DNS Answer Can and Cannot Do

dnsmasq can copy addresses out of answers into an nftables set, which is a feed rather than a routing decision. That option, documented in the dnsmasq manual, names the family, the table and the set, and its leading 4# selects A records only, so v6 destinations need their own arrangement. The set must already exist, because the resolver adds elements to something the firewall owner created. Nothing in that step chooses an interface, a table or a peer.

The client also has to use that resolver for the name. An application with its own encrypted DNS, or a cached answer from before the policy existed, connects without creating any set entry at all.

The Set Is an Input, Not a Route

An element in a set is a matching condition. Something has to look at it, decide that this packet starts a new flow, and apply the policy that sends the flow through the tunnel. On Linux that normally means a route-capable output path that can set a mark, a rule sending marked packets to a dedicated table, and a route in that table pointing at the WireGuard device. Membership alone installs none of it.

nft add set inet vpn_select office_v4 { type ipv4_addr\; }
ip rule add fwmark 0x40 table 200
ip route add default dev wg0 table 200
wg show wg0 allowed-ips

The peer applies a second coverage check that people forget. WireGuard encrypts a packet only for a peer whose allowed addresses include the destination, so a policy route into the interface is not enough when the peer's list excludes that prefix. Keep the list under the routing owner's control rather than relying on whatever route creation the manager happens to perform.

Marks, Tables and Peer Coverage

Marks are a shared namespace, so both the value and the mask have to be agreed with anything else that uses them. A rule sending marked traffic to a dedicated table needs a defined result when that table has no matching route, because an unanswered lookup can continue to the next rule and send the packet out of the physical interface. A blackhole default inside the dedicated table turns that quiet escape into a visible drop. What the design still cannot do is fail closed for a destination that never entered the set.

The tunnel's own outer packets have to escape the classifier. WireGuard tools provide a socket mark for exactly that purpose, and using it keeps the encapsulation from being routed back into the interface it is building.

Test Each Lifetime Separately

Three stores age on three schedules: the resolver cache, the set elements and the tracked connection. Test them in that order and watch whether each one moves when it should. The commands below read the resolver, the set, the connection table and the policy rules without changing anything.

dig +short office.example
nft list set inet vpn_select office_v4
conntrack -L -d 10.60.8.15
ip rule show

A fresh lookup that adds an element proves the feed works, while a stale element outliving its answer is a lifetime mismatch worth writing down. A new connection appearing in the connection table with the expected mark shows the classifier ran, and an old connection keeping its original mark is correct behaviour rather than a bug. The rule listing answers whether the policy lookup exists at all, which is a different question from whether it matched. Read the four outputs in that order and the failing handoff identifies itself.

Where the requirement is that a particular name always uses one path, a DNS-fed set cannot prove it, because shared addresses carry other names too. A proxy or an application-level mechanism is the tool for that guarantee.

ተዛማጅ ጽሑፎች