Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I'm planning on upgrading my OpenBSD to 4.7 (from 4.6) and as you may or may not know, they changed the syntax for pf.conf.

This is the relevant portion from the upgrade guide:

pf(4) NAT syntax change

As described in more detail in this mailing list post, PF's separate nat/rdr/binat (translation) rules have been replaced with actions on regular match/filter rules. Simple rulesets may be converted like this:

nat on $ext_if from 10/8 -> ($ext_if)
rdr on $ext_if to ($ext_if) -> 1.2.3.4

becomes

match out on $ext_if from 10/8 nat-to ($ext_if)
match in on $ext_if to ($ext_if) rdr-to 1.2.3.4

and...

binat on $ext_if from $web_serv_int to any -> $web_serv_ext

becomes

match on $ext_if from $web_serv_int to any binat-to $web_serv_ext

nat-anchor and/or rdr-anchor lines, e.g. for relayd(8), ftp-proxy(8) and tftp-proxy(8), are no longer used and should be removed from pf.conf(5), leaving only the anchor lines. Translation rules relating to these and spamd(8) will need to be adjusted as appropriate.

N.B.: Previously, translation rules had "stop at first match" behaviour, with binat being evaluated first, followed by nat/rdr depending on direction of the packet. Now the filter rules are subject to the usual "last match" behaviour, so care must be taken with rule ordering when converting.

pf(4) route-to/reply-to syntax change

The route-to, reply-to, dup-to and fastroute options in pf.conf move to filteropts;

pass in on $ext_if route-to (em1 192.168.1.1) from 10.1.1.1
pass in on $ext_if reply-to (em1 192.168.1.1) to 10.1.1.1

becomes

pass in on $ext_if from 10.1.1.1 route-to (em1 192.168.1.1)
pass in on $ext_if to 10.1.1.1 reply-to (em1 192.168.1.1)

Now, this is my current pf.conf:

#       $OpenBSD: pf.conf,v 1.38 2009/02/23 01:18:36 deraadt Exp $
#
# See pf.conf(5) for syntax and examples; this sample ruleset uses
# require-order to permit mixing of NAT/RDR and filter rules.
# Remember to set net.inet.ip.forwarding=1 and/or net.inet6.ip6.forwarding=1
# in /etc/sysctl.conf if packets are to be forwarded between interfaces.

ext_if="pppoe0"
int_if="nfe0"
int_net="192.168.0.0/24"

polemon="192.168.0.10"
poletopw="192.168.0.12"
segatop="192.168.0.20"

table <leechers> persist

set loginterface $ext_if
set skip on lo

match on $ext_if all scrub (no-df max-mss 1440)

altq on $ext_if priq bandwidth 950Kb queue {q_pri, q_hi, q_std, q_low}
queue q_pri priority 15
queue q_hi priority 10
queue q_std priority 7 priq(default)
queue q_low priority 0

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"

nat on $ext_if from !($ext_if) -> ($ext_if)
rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
rdr pass on $ext_if proto tcp to port 2080 -> $segatop port 80
rdr pass on $ext_if proto tcp to port 2022 -> $segatop port 22

rdr pass on $ext_if proto tcp to port 4000 -> $polemon port 4000
rdr pass on $ext_if proto tcp to port 6600 -> $polemon port 6600

anchor "ftp-proxy/*"

block

pass on $int_if queue(q_hi, q_pri)

pass out on $ext_if queue(q_std, q_pri)
pass out on $ext_if proto icmp queue q_pri
pass out on $ext_if proto {tcp, udp} to any port ssh queue(q_hi, q_pri)
pass out on $ext_if proto {tcp, udp} to any port http queue(q_std, q_pri)
#pass out on $ext_if proto {tcp, udp} all queue(q_low, q_hi)

pass out on $ext_if proto {tcp, udp} from <leechers> queue(q_low, q_std)

pass in on $ext_if proto tcp to ($ext_if) port ident queue(q_hi, q_pri)
pass in on $ext_if proto tcp to ($ext_if) port ssh queue(q_hi, q_pri)
pass in on $ext_if proto tcp to ($ext_if) port http queue(q_hi, q_pri)
pass in on $ext_if inet proto icmp all icmp-type echoreq queue q_pri

If someone has experience with porting the 4.6 pf.conf to 4.7, please help me do the correct changes.

OK, this is how far I've got:

I commented out nat-anchor and rdr-anchor, as describted in the guide:

#nat-anchor "ftp-proxy/*"
#rdr-anchor "ftp-proxy/*"

And this is how I've "converted" the rdr rules:

#nat on $ext_if from !($ext_if) -> ($ext_if)
match out on $ext_if from !($ext_if) nat-to ($ext_if)
#rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021
match in on $int_if proto tcp to port ftp rdr-to 127.0.0.1 port 8021
#rdr pass on $ext_if proto tcp to port 2080 -> $segatop port 80
match in on $ext_if proto tcp tp port 2080 rdr-to $segatop port 80
#rdr pass on $ext_if proto tcp to port 2022 -> $segatop port 22
match in on $ext_if proto tcp tp port 2022 rdr-to $segatop port 22

rdr pass on $ext_if proto tcp to port 4000 -> $polemon port 4000
match in on $ext_if proto tcp tp port 4000 rdr-to $polemon port 4000
rdr pass on $ext_if proto tcp to port 6600 -> $polemon port 6600
match in on $ext_if proto tcp tp port 6600 rdr-to $polemon port 6600

Did I miss anything? Is the anchor for ftp-proxy OK as it is now? Do I need to change something in the other pass in on... lines?

share|improve this question

1 Answer 1

up vote 0 down vote accepted

Seems nobody could or was willing to help me... :(

But I managed to get it working myself. Here's the working pf.conf (works with OpenBSD 4.8)

#       $OpenBSD: pf.conf,v 1.38 2009/02/23 01:18:36 deraadt Exp $
#
# See pf.conf(5) for syntax and examples; this sample ruleset uses
# require-order to permit mixing of NAT/RDR and filter rules.
# Remember to set net.inet.ip.forwarding=1 and/or net.inet6.ip6.forwarding=1
# in /etc/sysctl.conf if packets are to be forwarded between interfaces.

ext_if="pppoe0"
int_if="nfe0"
int_net="192.168.0.0/24"

polemon="192.168.0.10"
poletopw="192.168.0.12"
segatop="192.168.0.20"

table <leechers> persist

set loginterface $ext_if
set skip on lo

match on $ext_if all scrub (no-df max-mss 1440)

altq on $ext_if priq bandwidth 950Kb queue {q_pri, q_hi, q_std, q_low}
queue q_pri priority 15
queue q_hi priority 10
queue q_std priority 7 priq(default)
queue q_low priority 0

block

match out on $ext_if from !($ext_if) nat-to ($ext_if)
pass in on $int_if proto tcp to port ftp rdr-to 127.0.0.1 port 8021
pass in on $ext_if proto tcp to port 2080 rdr-to $segatop port 80
pass in on $ext_if proto tcp to port 2022 rdr-to $segatop port 22
pass in on $ext_if proto tcp to port 4000 rdr-to $polemon port 4000
pass in on $ext_if proto tcp to port 6600 rdr-to $polemon port 6600

anchor "ftp-proxy/*"

pass on $int_if queue(q_hi, q_pri)

pass out on $ext_if queue(q_std, q_pri)
pass out on $ext_if proto icmp queue q_pri
pass out on $ext_if proto {tcp, udp} to any port ssh queue(q_hi, q_pri)
pass out on $ext_if proto {tcp, udp} to any port http queue(q_std, q_pri)
#pass out on $ext_if proto {tcp, udp} all queue(q_low, q_hi)

pass out on $ext_if proto {tcp, udp} from <leechers> queue(q_low, q_std)

pass in on $ext_if proto tcp to ($ext_if) port ident queue(q_hi, q_pri)
pass in on $ext_if proto tcp to ($ext_if) port ssh queue(q_hi, q_pri)
pass in on $ext_if proto tcp to ($ext_if) port http queue(q_hi, q_pri)
pass in on $ext_if inet proto icmp all icmp-type echoreq queue q_pri

I had it working for over six months now. Since no one was posting an answer and this is basically working now, I decided to post my own solution. Given that this thread has over 1k views, this might help someone...

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.