Solved nat/firewall -- all is working BUT firewall machine can't connect out

After running into a performance bug in ipf, I decided to give pf a shot. With the help of a sample configs from users like diizzy (and the docs), I managed to get things working. Everything on my LAN is happy with NAT and my ports are forwarding.

But I've clearly made a mistake somewhere, because the pf machine itself cannot reach the Internet.

Code:
[1411][user@host:~]$ wget yahoo.com
--2017-01-15 14:11:08--  http://yahoo.com/
Resolving yahoo.com (yahoo.com)... ^C

I tried checking the pflog but got zero data. Turns out my log file is 24 bytes in size, so my logging directives are not working as expected either.

Code:
root@wrongcrowd:/etc # tcpdump -n -e -vv -ttt -i pflog0
tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 262144 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

I thought I had set up a "default allow" on LAN machines connecting out, but clearly I have made a mistake somewhere.

It's a simple hardware setup... one NIC dedicated to the ISP, and one NIC connected to a switch for my LAN.

Below is my pf config in rc.conf.

Code:
pf_enable="YES"
pf_flags=""                     # additional flags for pfctl startup
pf_rules="/etc/pf.conf"
pflog_enable="YES"
pflog_logfile="/var/log/pflog"  # where pflogd should store the logfile
pflog_flags=""                  # additional flags for pflogd startup

Below is my pf.conf. Can someone help me spot the error that keeps the pf box from making connections on the external interface?

Edit to add: I was able to get the desired result by adding a pass rule to the end of the file:

Code:
pass out on $ext_if from any to any

However, I thought that shouldn't be necessary?

Code:
# pf.conf
###################
#### Variables ####
###################

#### Network interfaces

# External interface
ext_if="igb0"

# Internal interface
int_if="igb1"

# igb2 and 3 not yet in use

#### MY GADGETS (and vars for their services)

# note that ports open on the router itself are defined below in the last rules block

nvr="192.168.1.15"
shieldtv="192.168.1.16"

ps4="192.168.1.14"
    ps4_udp="{ 9303, 9296, 9297 }"

deck2="192.168.1.17"
    moonlight_udp="{ 47998, 47999, 48000, 48010 }"
    moonlight_tcp="{ 47984, 47989 }"

tvpc="192.168.1.18"

# let's not support xboxes with rdr, let's try miniupnpd
xbox-mbr="192.168.1.13"

# Follow RFC1918 and don't route to non-routable IPs
# http://www.iana.org/assignments/ipv4-address-space
# http://rfc.net/rfc1918.html
nonroute= "{ 0.0.0.0/8, 20.20.20.0/24, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.2.0/24, 192.168.0.0/16, 224.0.0.0/3, 255.255.255.255 }"

# Set allowed ICMP types
icmp_types = "{ 0, 3, 4, 8, 11, 12 }"

####################################
#### Options and optimizations #####
####################################

# Set interface for logging (statistics)
set loginterface $ext_if

# Optimization
# normal = default
# aggressive = Drop states as fast as possible without having excessively low timeouts
set optimization normal

# Block policy, either silently drop packets or tell sender that request is blocked
set block-policy return

# Don't bother to process (filter) following interfaces such as loopback:
set skip on lo0

# Scrub traffic
# If there is trouble, this is the first thing to comment out.
# Said to cause problems for game consoles?
scrub on $ext_if all

###########################################
#### RULES ORDER: NAT, RDR, PASS/BLOCK ####
###########################################

#######################
####       NAT     ####
#######################

# Enable NAT
nat on $ext_if inet from $int_if:network to any -> ($ext_if)

#######################
####      RDR      ####
#######################

# Hikvision NVR port 8000
rdr pass on $ext_if inet proto tcp from any to any port 8000 -> $nvr

# Plex port for server running on Shield Android TV
rdr pass on $ext_if inet proto tcp from any to any port 32400 -> $shieldtv

# PS4 remote play
# udp ports are defined above with the device ip
rdr pass on $ext_if inet proto udp from any to any port $ps4_udp -> $ps4

# Moonlight remote game streaming
rdr pass on $ext_if inet proto udp from any to any port $moonlight_udp -> $deck2
rdr pass on $ext_if inet proto tcp from any to any port $moonlight_tcp -> $deck2

## VNC for Windows
# WAN port 5902 goes to upstairs PC
rdr pass on $ext_if inet proto tcp from any to any port 5902 -> $deck2 port 5900
# WAN port 5901 goes to downstairs PC
rdr pass on $ext_if inet proto tcp from any to any port 5901 -> $tvpc port 5900

# Turning off the ftp proxy in this sample config, don't need it. Keeping for syntax example.

    # Redirect ftp connections to ftp-proxy
    #rdr pass on $int_if inet proto tcp from $int_if:network to any port 21 -> 127.0.0.1 port 8021
    # Enable ftp-proxy
    #nat-anchor "ftp-proxy/*"
    #rdr-anchor "ftp-proxy/*"
    # Anchors needs to be set after nat/rdr-anchor
    #anchor "ftp-proxy/*"

################################
#### Rules inbound (int_if) ####
################################

# Pass on everything
pass in quick on $int_if inet all keep state

#################################
#### Rules outbound (int_if) ####
#################################

# Pass on everything
pass out quick on $int_if inet all keep state

################################
#### Rules inbound (ext_if) ####
################################

# Drop packets from non-routable addresses directly
block drop in quick on $ext_if from $nonroute to any

# DHCP on ext_if turned off, we have a static IP from the ISP
# pass in quick on $ext_if inet proto udp to ($ext_if) port { 67, 68 }

# Allow ICMP
pass in quick on $ext_if inet proto icmp all icmp-type $icmp_types

# Allow FTPs to connect to our FTP-proxy--turned off, left in for example
#pass in quick on $ext_if inet proto tcp to ($ext_if) port ftp-data user proxy

# TCP ports that we allow in to the router itself
# 22=ssh
pass in quick on $ext_if inet proto tcp to any port { 22 }

# Block everything else
block in on $ext_if all

#################################
#### Rules outbound (ext_if) ####
#################################

# note there is an implicit PASS ALL at the beginning of a ruleset.
# Packets are evaluated against ALL rules, with the last match winning
# QUICK forces an instant match

# with no global block rule here, machines inside the LAN should be free to connect
# in any way, with only exceptions noted here as QUICK rules.


# BLOCK this traffic from LAN to WAN:

# Drop packets to non-routable addresses directly -- play with this later
#block drop out log quick on $ext_if from any to $nonroute
 
There's no pass out on $ext_if rule, so all your outgoing traffic from the firewall machine itself is blocked. Strictly speaking, PF allows traffic by default, so the outgoing traffic is allowed but the response is blocked due to block in on $ext_if all and the outgoing traffic doesn't have a state.
 
Back
Top