# pf+bridge: redirect UDP to localhost?



## marcnarc (Sep 21, 2010)

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 (Sep 21, 2010)

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 [cmd=]sockstat -l4p53[/cmd] 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 (Sep 22, 2010)

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 (Sep 23, 2010)

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 (Sep 23, 2010)

*Solved!*



> set skip on lo0



That did the trick.  Without that line things go kablooey.  Thanks a ton!


----------

