New pf.conf 4.7

Previously I was unable to reach the Internet from my internal network, but have made a change and am now able to get out.

I know this pf.conf is for 4.7, but I am *hoping* someone could review my configuration and let me know if there are any problems I need to fix before I put it in place.

This is going to be a (OpenBSD 4.7) firewall in front of my FreeBSD laptop on an internal network and a FreeBSD server running VirtualBox guests in a DMZ. I realize it isn't the FreeBSD pf, so I'd be grateful for a review and not get the thread bounced. :)

Code:
##### Macros #####
# ext_if -- the interface to the outside world
ext_if="axe0"

# prv_if -- the interface to the private hosts
prv_if="axe1"
localnet = $prv_if:network

# dmz_if -- the interface to the DMZ
dmz_if="axe2"

# prv_hosts -- the list of addresses of hosts on the screened LAN
prv_hosts = "{ 192.168.1.129/25, 192.168.1.130/25 }"

# dmz_hosts -- the list of addresses of hosts in the DMZ
dmz_hosts = "{ 192.168.1.1/25, 192.168.1.2/25, 192.168.1.3/25 }"

# dmz_www -- the address of the WWW server in the DMZ
dmz_www = "192.168.1.1/25"

# dmz_smtp -- the address of the SMTP server in the DMZ
dmz_smtp = "192.168.1.2/25"

# dmz_dns -- the address of the DNS server in the DMZ
dmz_dns = "192.168.1.3/25"

# known ports
www_ports = "{ http, https }"
mail_ports = "{ smtp, pop3, imap, imaps, pop3s }"

##### Tables #####
# Non-routable addresses
table <rfc1918> const { 127.0.0.0/8, 192.168.0.0/16, 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 }

##### Options #####
set skip on lo
set reassemble yes
set require-order yes
set block-policy drop
set loginterface $ext_if
set state-policy if-bound
set fingerprints "/etc/pf.os"
set ruleset-optimization none
set optimization aggressive
set timeout { frag 30, tcp.established 120 }
set timeout { tcp.first 30, tcp.closing 30, tcp.closed 30, tcp.finwait 30 }
set timeout { udp.first 30, udp.single 30, udp.multiple 30 }
set timeout { other.first 30, other.single 30, other.multiple 30 }

##### Traffic Normalization #####
match in all scrub (no-df random-id min-ttl 5 set-tos lowdelay max-mss 1440 reassemble tcp)
match out on $ext_if scrub (no-df random-id)

##### Queueing #####

##### Translation (NAT) #####
# Network Address Translation
# nat for the private hosts
match out on egress from $prv_hosts to any nat-to egress
# nat for the DMZ hosts
match out on egress from $dmz_hosts to any nat-to egress
# redirect connections to port 80 (HTTP) to DMZ
match in on egress inet proto tcp from any to any port $www_ports rdr-to $dmz_www
# redirect connections to port 25 (SMTP) to DMZ
match in on egress inet proto tcp from any to any port 25 rdr-to $dmz_smtp
# redirect connections to port 53 (DNS) to DMZ
match in on egress inet proto { tcp, udp } from any to any port 53 rdr-to $dmz_dns 

##### Filtering #####
# Block all incoming connections sent from the outside
# Log all blocked packets
block log on $ext_if
block return log on $prv_if
block return log on $dmz_if

# Block to/from illegal sources/destinations
block drop in quick on $ext_if from <rfc1918> to any
block drop out quick on $ext_if from any to <rfc1918> 
block in quick on $ext_if inet from any to 255.255.255.255
block in log quick on $ext_if inet from urpf-failed to any
block in log quick on $ext_if inet from no-route to any

# Block spoofed packets: enable "set state-policy if-bound" above
antispoof log quick for { lo0 $dmz_if $prv_if ($ext_if) }

# pass all connections originating from the firewall
pass out quick on $ext_if inet \
        from ($ext_if) to any flags S/SA modulate state
# pass all connections originating from the screened LAN
pass in quick on $prv_if from $prv_hosts to any flags S/SA

# pass all connections originating from the DMZ
pass in quick on $dmz_if from $dmz_hosts to any flags S/SA

# pass all connections to the WWW host in the DMZ
pass in on $ext_if proto { tcp, udp } from any to $dmz_www \
        port $www_ports flags S/SA synproxy state

# pass all connections to the SMTP host in the DMZ
pass in on $ext_if proto { tcp, udp } from any to $dmz_smtp \
        port $mail_ports flags S/SA synproxy state

# pass all connections to the DNS host in the DMZ
pass in on $ext_if proto { tcp, udp } from any to $dmz_dns \
        port 53 flags S/SA keep state

# Allow anything from the internal network out onto the Internet
pass out on $ext_if proto tcp from $localnet to any modulate state flags S/SA
pass out on $ext_if proto { tcp, icmp } from $localnet to any keep state
 
Hello,

Code:
# prv_hosts -- the list of addresses of hosts on the screened LAN
prv_hosts = "{ 192.168.1.129/25, 192.168.1.130/25 }"

# dmz_hosts -- the list of addresses of hosts in the DMZ
dmz_hosts = "{ 192.168.1.1/25, 192.168.1.2/25, 192.168.1.3/25 }"

=>
Code:
# prv_hosts -- the list of addresses of hosts on the screened LAN
prv_hosts = "{ 192.168.1.129/32, 192.168.1.130/32 }"

# dmz_hosts -- the list of addresses of hosts in the DMZ
dmz_hosts = "{ 192.168.1.1/32, 192.168.1.2/32, 192.168.1.3/32 }"
or just without any mask
Code:
# prv_hosts -- the list of addresses of hosts on the screened LAN
prv_hosts = "{ 192.168.1.129, 192.168.1.130 }"

# dmz_hosts -- the list of addresses of hosts in the DMZ
dmz_hosts = "{ 192.168.1.1, 192.168.1.2, 192.168.1.3 }"
, because /mask means network
1.1 , 1.2 and 1.3 are in same /25 network; 1.129 and 1.130 are in same /25 network



For NAT would be better with the following example:
Code:
match out on $ext_if from { $prv_if:network, $dmz_if:network } nat-to ($ext_if) static-port
where you have already defined $prv_if:network as localnet, static-port is just an example

I didn't look in detail in your filter rules, but
Code:
pass out on $ext_if proto { tcp, icmp } from $localnet to any keep state
=>
Code:
pass out on $ext_if inet proto { tcp, icmp } from $localnet to any keep state
 
I appreciate it very much, thank you.

Can you explain the difference between:
Code:
proto { tcp, icmp }
and
Code:
inet proto { tcp, icmp }
 
Hello,

Just follow your rules for outgoing filtering
Code:
# pass all connections originating from the firewall
pass out quick on $ext_if inet \
        from ($ext_if) to any flags S/SA modulate state

Here you pass inet af, and it would be correct to put address family also in
Code:
# Allow anything from the internal network out onto the Internet
pass out on $ext_if proto tcp from $localnet to any modulate state flags S/SA
pass out on $ext_if proto { tcp, icmp } from $localnet to any keep state
because these rules will actually allow all families ( inet and inet6 ) , but in first rule inet6 is not allowed for outgoing
 
Back
Top