# pf udp port forwarding



## giannidoe (Jun 4, 2010)

I'm trying to forward udp traffic on port 5080 to a host inside my network with the following rule.

```
rdr on $ext_if2 proto { tcp, udp } from any to $ext_if2 port 5080 -> $pbx_host
```

This works fine for tcp traffic and pflog shows the packets getting passed on the external interface and leaving the internal interface for the intended destination.

```
7. 725492 rule 51/0(match): pass in on tun1: x.x.x.x.58770 > 192.168.200.42.5080:  tcp 32 [bad hdr length 8 - too short, < 20]
000144 rule 19/0(match): pass out on vr0: x.x.x.x.58770 > 192.168.200.42.5080:  tcp 32 [bad hdr length 8 - too short, < 20]
```

The problem is with udp, the packets get passed on the external interface with the correct new destination but they never leave the internal interface for the final destination and seem to be somehow lost.

```
000000 rule 65/0(match): pass in on tun1: x.x.x.x.5060 > 192.168.200.42.5080: SIP, length: 1207
529850 rule 65/0(match): pass in on tun1: x.x.x.x.5060 > 192.168.200.42.5080: SIP, length: 1207
2. 028043 rule 65/0(match): pass in on tun1: x.x.x.x.5060 > 192.168.200.42.5080: SIP, length: 1207
4. 048524 rule 65/0(match): pass in on tun1: x.x.x.x.5060 > 192.168.200.42.5080: SIP, length: 1207
```

Here's my complete ruleset, anyone have any ideas why it's not working ?


```
loopback_if = "lo0"
int_if = "vr0"
localnet = "192.168.200.0/24"
pbx_host = "192.168.200.42"
mx_host = "192.168.200.41"
ext_if1 = "tun0"
ext_if2 = "tun1"
ext_ifs = "{ tun0, tun1 }"
vpn_if = "tun2"
vpn_nets = "{ 192.168.0.0/24 }"
icmp_in_types = "{ unreach,echoreq }"

table <bruteforce> persist
table <martians> persist { 127.0.0.0/8, 172.16.0.0/12 \
          			   10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \
            			   0.0.0.0/8, 240.0.0.0/4 }

set block-policy return
set skip on { $loopback_if, vr1, vr2 }
#scrub in all
scrub log all random-id min-ttl 254 max-mss 1452 reassemble tcp fragment reassemble

tcp_services = "{ 2525, ssh, smtp, smtps, domain, https, imaps, sip, 1194, 5080 }"
udp_services = "{ domain, sip, 4569, 1194, 5080 }"

tcp_client = "{ ssh, domain, pop3, pop3s, imap, imaps, smtp, smtps, auth, ntp,\
		http, https, 8080, sip, 5080, cvsup, postgresql, 3306, 8180, 1863, 444, 1194 }"

udp_client = "{ domain, sip, 5080, ntp, 4569, 1194, 5222 }"

# NAT
no nat on $ext_if1 from $localnet to $vpn_nets 
nat on $ext_if1 from $localnet to any -> ($ext_if1)
no nat on $ext_if2 from $localnet to $vpn_nets 
nat on $ext_if2 from $localnet to any -> ($ext_if2)

rdr on $ext_if1 proto tcp from any to $ext_if1 port 222 -> 192.168.200.40 port 22
rdr on $ext_if1 proto tcp from any to $ext_if1 port 25 -> $mx_host 
rdr on $ext_if1 proto tcp from any to $ext_if1 port 2525 -> $mx_host 
rdr on $ext_if1 proto tcp from any to $ext_if1 port 993 -> $mx_host 
rdr on $ext_if1 proto tcp from any to $ext_if1 port 465 -> $mx_host 

rdr on $ext_if2 proto tcp from any to $ext_if2 port 222 -> 192.168.200.40 port 22
rdr on $ext_if2 proto tcp from any to $ext_if2 port 25 -> $mx_host 
rdr on $ext_if2 proto tcp from any to $ext_if2 port 2525 -> $mx_host 
rdr on $ext_if2 proto tcp from any to $ext_if2 port 993 -> $mx_host 
rdr on $ext_if2 proto tcp from any to $ext_if2 port 465 -> $mx_host 

# SIP
rdr on $ext_if1 proto { tcp, udp } from any to $ext_if1 port 5080 -> $pbx_host 
rdr on $ext_if2 proto { tcp, udp } from any to $ext_if2 port 5080 -> $pbx_host

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr pass on $int_if proto tcp from $localnet to any port 21 -> 127.0.0.1 port 8021

antispoof log for $ext_ifs
antispoof log for $int_if

block log all
block log quick from <bruteforce>
block drop in log quick on $ext_ifs from <martians> to any
block drop out log quick on $ext_ifs from any to <martians>

pass log from { $loopback_if, $localnet } to any

pass in log on $int_if 
pass out log on $int_if
pass out log on $ext_ifs

pass out log quick on $ext_if1 route-to ($ext_if2 ($ext_if2:peer)) from $ext_if2 to any 
pass out log quick on $ext_if2 route-to ($ext_if1 ($ext_if1:peer)) from $ext_if1 to any 

# ICMP
pass in log inet proto icmp all icmp-type $icmp_in_types

pass in log on $ext_if1 reply-to ($ext_if1 ($ext_if1:peer)) inet proto icmp all icmp-type $icmp_in_types
pass in log on $ext_if2 reply-to ($ext_if2 ($ext_if2:peer)) inet proto icmp all icmp-type $icmp_in_types

# Public services 
pass in log on $ext_if1 reply-to ($ext_if1 ($ext_if1:peer)) inet proto tcp \
    from any to any port $tcp_services \
    (max-src-conn 100, max-src-conn-rate 50/5, \
    overload <bruteforce> flush global)
pass in log on $ext_if2 reply-to ($ext_if2 ($ext_if2:peer)) inet proto tcp \
    from any to any port $tcp_services \
    (max-src-conn 100, max-src-conn-rate 50/5, \
    overload <bruteforce> flush global)

pass in log on $ext_if1 reply-to ($ext_if1 ($ext_if1:peer)) inet proto tcp \
    from any to any port { ssh, 222 } \
    (max-src-conn 10, max-src-conn-rate 5/3, \
    overload <bruteforce> flush global)
pass in log on $ext_if2 reply-to ($ext_if2 ($ext_if2:peer)) inet proto tcp \
    from any to any port { ssh, 222 } \
    (max-src-conn 10, max-src-conn-rate 5/3, \
    overload <bruteforce> flush global)

pass in log on $ext_if1 reply-to ($ext_if1 ($ext_if1:peer)) inet proto udp \
    from any to any port $udp_services
pass in log on $ext_if2 reply-to ($ext_if2 ($ext_if2:peer)) inet proto udp \
    from any to any port $udp_services

# VPN
pass in log on $ext_ifs inet proto icmp from $vpn_nets to $localnet
pass out log on $vpn_if from any to any keep state 

# FTP-proxy
anchor "ftp-proxy/*" 
pass out log proto tcp from ($ext_if1) to any port 21
pass out log proto tcp from ($ext_if2) to any port 21
```


----------

