View Full Version : [Solved] pf+bridge: redirect UDP to localhost?
marcnarc
September 21st, 2010, 18:12
Hi,
I'm trying to set up my bridge to redirect DNS queries to a server running on the bridge.
The following rules work fine for TCP:
rdr on vr1 inet proto tcp to port 53 -> 127.0.0.1
pass in quick route-to lo0 inet proto tcp from any to port 53 keep state
But if I change them into UDP rules traffic just passes through.
The vr1 interface is bridged with vr0. I want to intercept DNS queries that arrive on vr1.
I'm running 7.1. Here are my link.bridge sysctls:
net.link.bridge.ipfw: 0
net.link.bridge.sat_mac: 1
net.link.bridge.log_stp: 0
net.link.bridge.pfil_local_phys: 0
net.link.bridge.pfil_member: 1
net.link.bridge.pfil_bridge: 0
net.link.bridge.ipfw_arp: 0
net.link.bridge.pfil_onlyip: 1
What's the obvious thing I'm missing?
Thanks!
DutchDaemon
September 21st, 2010, 23:18
There's absolutely no reason why this would work for TCP but not UDP. Can you write the exact rules you're using for TCP and UDP here? And does the output of sockstat -l4p53 show named listening on TCP and UDP ports 53? E.g.:
bind named 1013 21 tcp4 127.0.0.1:53 *:*
bind named 1013 513 udp4 127.0.0.1:53 *:*
marcnarc
September 22nd, 2010, 22:20
Thanks for the reply, DutchDaemon!
There is more to the full config, but it's not overly complex (IMO).
First of all, sockstat shows the server (dnsmasq in this case) listening to the right ports:
nobody dnsmasq 36526 3 udp4 *:53 *:*
nobody dnsmasq 36526 4 tcp4 *:53 *:*
As for the pf rules, they're split between /etc/pf.conf and an anchor set stored in /etc/pf-dns.conf.
/etc/pf.conf has an altq rule and loads /etc/pf-dns.conf:
altq on vr0 hfsc bandwidth 100Mb rtt 800 queue { root.BasicOpt, root.Default }
queue root.BasicOpt bandwidth 100b priority 1 qlimit 300 qdlimit 300 rtt 800 hfsc( realtime 0b upperlimit 4Mb)
queue root.Default bandwidth 100b priority 7 qlimit 50 qdlimit 300 rtt 800 hfsc(default realtime 0b upperlimit 4Mb)
# DNS interception
rdr-anchor dns-interception
load anchor dns-interception from "/etc/pf-dns.conf"
/etc/pf-dns.conf has the redirection rules:
rdr on vr1 inet proto udp to port 53 -> 127.0.0.1
pass in quick route-to lo0 inet proto udp from any to port 53 keep state
There are no other rules.
If you can confirm that this configuration should work, then I'll at least be able to look elsewhere for the cause of the problem.
(Here's a stunner: On one of my machines, if I forgo the anchor mechanism and put all the rules in a single /etc/pf.conf file, the machine freezes solid as soon as a DNS UDP packet arrives! With the rules split up as above, the packets just pass right through the box.)
Thanks again!
DutchDaemon
September 23rd, 2010, 02:32
1. the rule looks rather short, it's usually something along the lines of:
rdr on $int_if inet proto tcp from any to any port 53 -> 127.0.0.1
rdr on $int_if inet proto udp from any to any port 53 -> 127.0.0.1
2. Do you have this set as well?
set skip on lo0
The route-to statement is mandatory since this is a bridge, but normally the loopback interface itself is set to skip. Things start to fail in random ways without it.
3. The route-to statement itself is usually a little bit more 'involved' as well, e.g.
pass in quick route-to lo0 inet proto tcp from any to 127.0.0.1 port 53 keep state
pass in quick route-to lo0 inet proto udp from any to 127.0.0.1 port 53 keep state
Note that collapsing the lines in 1. and 3. by using proto { tcp udp } is possible since they're otherwise identical.
marcnarc
September 23rd, 2010, 22:13
set skip on lo0
That did the trick. Without that line things go kablooey. Thanks a ton!
vBulletin® v3.8.7, Copyright ©2000-2013, vBulletin Solutions, Inc.