eusanpe
March 21st, 2005, 23:09
Hello:

Can someone look and see what I have done wrong with my pf.conf rules. I gathered alot of info from multiple sites but I can't connect out. My setup is like:

Internet--Cable Modem---Bridge---Switch---nat/dhcp- router---FW/VPN---Internal

1. The cable modem has an public ip (xxx.xxx.xxx.121)
2. I have three interfaces on the bridge with one ip (192.168.1.100) as a management.
3. The servers on the switch have public ips (xxx.xxx.xxx.123, xxx.xxx.xxx.124). They
run www, mail, and dns
4. The nat/dhcp router is a linksys router with external ip (xxx.xxx.xxx.122) and
internal ip (192.168.1.1).
5. The management interface on the bridge is connected to the internal port of the
router
6. The firewall/vpn server has external ip (192.168.1.2) and internal ip (192.168.2.1)

My pf.conf rules are: (Disregard the Table.. It is formatted right on my system)

#########INITIALIZE VARIABLES

#### Define the Network Interfaces
ext_if="xl0" # Untrusted (from WAN ISP) side
int_if="xl1" # Internal to application servers
mgt_if="fxp0" # Management Interface
loop_if="lo0" # LoopBack Device
all_if="{ xl0, xl1, fxp0, lo0 }"

#### Tables
table <RFC1918> const {!192.168.0.0/24,0.0.0.0/8,1.0.0.0/8,2.0.0.0/8,5.0.0.0/8,7.0.0.0/8,10.0.0.0/8,23.0.0.0/8,
27.0.0.0/8,31.0.0.0/8,36.0.0.0/8,37.0.0.0/8,39.0.0.0/8,41.0.0.0/8,42.0.0.0/8,49.0.0.0/8,
50.0.0.0/8,58.0.0.0/8,59.0.0.0/8,73.0.0.0/8,74.0.0.0/8,75.0.0.0/8,76.0.0.0/8,77.0.0.0/8,
78.0.0.0/8,79.0.0.0/8,89.0.0.0/8,90.0.0.0/8,91.0.0.0/8,92.0.0.0/8,93.0.0.0/8,94.0.0.0/8,
95.0.0.0/8,96.0.0.0/8,97.0.0.0/8,98.0.0.0/8,99.0.0.0/8,100.0.0.0/8,101.0.0.0/8,
102.0.0.0/8,103.0.0.0/8,104.0.0.0/8,105.0.0.0/8,106.0.0.0/8,107.0.0.0/8,108.0.0.0/8,
109.0.0.0/8,110.0.0.0/8,111.0.0.0/8,112.0.0.0/8,113.0.0.0/8,114.0.0.0/8,115.0.0.0/8,
116.0.0.0/8,117.0.0.0/8,118.0.0.0/8,119.0.0.0/8,120.0.0.0/8,121.0.0.0/8,122.0.0.0/8,
123.0.0.0/8,124.0.0.0/8,125.0.0.0/8,126.0.0.0/8,127.0.0.0/8,169.254.0.0/16,
172.16.0.0/12,173.0.0.0/8,174.0.0.0/8,175.0.0.0/8,176.0.0.0/8,177.0.0.0/8,178.0.0.0/8,
179.0.0.0/8,180.0.0.0/8,181.0.0.0/8,182.0.0.0/8,183.0.0.0/8,184.0.0.0/8,185.0.0.0/8,
186.0.0.0/8,187.0.0.0/8,189.0.0.0/8,190.0.0.0/8,192.0.2.0/24,192.168.0.0/16,
197.0.0.0/8,198.18.0.0/15,223.0.0.0/8,224.0.0.0/3,255.255.255.255/32}

#### OPTIONS
set require-order yes
set block-policy return
set optimization normal
set loginterface $ext_if

#### Public Services
# -------------------------
# WWW : Web Server
# -------------------------
web_servers="{ xxx.xxx.xxx.123, xxx.xxx.xxx.124}"
web_ports="{ 80, 443, 20, 21, 8080, 8443, 55000, > 49151 }"
web_proto="{ tcp, udp }"

# -------------------------
# DNS : Public access resolvers
# -------------------------
dns_servers="{ xxx.xxx.xxx.123, xxx.xxx.xxx.124 }"
dns_ports="{ 53 }"
dns_proto="{ tcp, udp }"

# -------------------------
# MAIL : Public mail server
# -------------------------
mx_servers="{ xxx.xxx.xxx.123, xxx.xxx.xxx.124 }"
mx_ports="{ 80, 143, 443, 25, 110, 943, 995 }"
mx_proto="{ tcp }"

# -------------------------
# SSH : Allow remote login
# -------------------------
ssh_servers="{ xxx.xxx.xxx.123, xxx.xxx.xxx.124, xxx.xxx.xxx.125, xxx.xxx.xxx.126, \ 192.168.1/24, 192.168.2/24 }"
ssh_ports="{ 22 }"
ssh_proto="{ tcp }"

# ------------------------------
# Rsync : Allow rsync to inside
# ------------------------------
rsync_ports="{ 873 }"
rsync_proto="{ tcp, udp }"

# -------------------------
# SQL : MySQL
# -------------------------
sql_servers=""
sql_ports="{ 3306 }"
sql_proto=""

# -------------------------
# LDAP : Future Use
# -------------------------
ldp_servers=""
ldp_ports=""
ldp_proto=""

#### Illegal Ports
illegal_ports="{ 67, 68, 135, 137, 138, 139, 161, 427, 1433, 1434, 3389 }"

####START FILTER RULES

#### Clean up fragmented and abnormal packets
scrub on $ext_if all random-id min-ttl 255 max-mss 1492 fragment reassemble
#
#
pass quick on $loop_if all
antispoof log for $all_if

# silently drop broadcasts cable modem noise
block in quick on $ext_if from any to 255.255.255.255

# Block bad tcp flags from malicious people and nmap scans
block in log quick on $ext_if proto tcp from any to any flags /S
block in log quick on $ext_if proto tcp from any to any flags /SFRA
block in log quick on $ext_if proto tcp from any to any flags /SFRAU
block in log quick on $ext_if proto tcp from any to any flags A/A
block in log quick on $ext_if proto tcp from any to any flags F/SFRA
block in log quick on $ext_if proto tcp from any to any flags U/SFRAU
block in log quick on $ext_if proto tcp from any to any flags SF/SF
block in log quick on $ext_if proto tcp from any to any flags SF/SFRA
block in log quick on $ext_if proto tcp from any to any flags SR/SR
block in log quick on $ext_if proto tcp from any to any flags FUP/FUP
block in log quick on $ext_if proto tcp from any to any flags FUP/SFRAUPEW
block in log quick on $ext_if proto tcp from any to any flags SFRAU/SFRAU
block in log quick on $ext_if proto tcp from any to any flags SFRAUP/SFRAUP

# Drop spoofed packets IP blocks
block in log quick on $ext_if from { <RFC1918> } to any
block out log quick on $ext_if from any to { <RFC1918> }

# block and log everything by default
block return log on $ext_if all

# block anything coming from source we have no back routes for
block in from no-route to any

# block and log outgoing packets that don't have our address as source,
# they are either spoofed or something is misconfigured NAT disabled,
# (for instance), we want to be nice and don't send out garbage.
block out log quick on $ext_if from ! $ext_if to any

#### Allow internal interface in (block on the external)
pass in quick on $int_if inet proto { tcp, udp } from any to any keep state
pass in quick on $int_if inet proto { icmp } from any to any keep state

#### Allow internal interface out (block on the external)
pass out quick on $int_if inet proto { tcp, udp } from any to any keep state
pass out quick on $int_if inet proto { icmp } from any to any keep state

#### Allow internal interface out (block on the external)
pass out quick on $mgt_if inet proto { tcp, udp } from any to any keep state
pass out quick on $mgt_if inet proto { icmp } from any to any keep state

#### Don't allow anyone to spoof non-routeable addresses or broadcasts
#### also block traffic on restricted ports

block in log quick on $ext_if inet proto { tcp, udp } from any to any port $illegal_ports
block out log quick on $ext_if inet proto { tcp, udp } from any to any port $illegal_ports

#### IN RULES

#### WWW Server Traffic
pass in on $ext_if inet proto $web_proto from any to $web_servers port $web_ports keep state

#### DNS Traffic
pass in on $ext_if inet proto $dns_proto from any to $dns_servers port $dns_ports keep state

#### MAIL Traffic
pass in on $ext_if inet proto $mx_proto from any to $mx_servers port $mx_ports keep state

#### SSH Traffic
pass in on $ext_if inet proto $ssh_proto from any to $ssh_servers port $ssh_ports keep state

#### Allow ICMP (ping) IN
pass in on $ext_if inet proto icmp all icmp-type 8 code 0 keep state

#### Allow RSYNC IN
pass in on $ext_if inet proto $rsync_proto from any to any port $rsync_ports keep state

#### OUT RULES

#### Pass (Allow) all UDP/TCP OUT and keep state
pass out on $ext_if proto udp all keep state
pass out on $ext_if proto tcp all modulate state

#### Allow rsync
pass out on $ext_if proto $rsync_proto from port $rsync_ports to any

#### Allow ICMP (ping) OUT
pass out on $ext_if inet proto icmp all icmp-type 8 code 0 keep state

----------------------
Thank you,
Tony

Strog
March 23rd, 2005, 01:13
There's a lot of things going on in your post and I can understand why people might be a bit hesitant to reply. I guess some explanation of why you have so many seperate pieces (e.g. bridge, nat, firewall, etc.) instead of something more typical like the figure below.


internet--cablemodem--firewall--internal
|
|
DMZ--server(s)


I see a few problems in this config that need addressing. It looks like you have gleaned a lot of good tips and tricks but the problem is that some of these things don't exactly apply directly to the current network configuration you are describing. Perhaps I'm misreading your network setup. :wink:

For example, the block broadcasts from the cable modem needs some tweaking. The firewall is sitting behind a NAT box a subnet away so it's not going to even reach it. Since the default block is reject, it will generate traffic of its own. I'd recomend using drop on that block instead if you hook the firewall up to the cable modem.

The tcp flags blocks are unneeded since pf blocks them by default since 3.5. You still see them in updated configs that started before that but I'd pull them out and streamline the config where possible.

There's passes in on external to the servers but they are actually in front of the firewall so these rules are essentially useless.

There's a lot of block quicks in here and it leaves some room for some abiguity. The issue is more than likely in here somewhere. I'd add log to all of them and then use tcpdump to watch pflog (the pflog man page has a good example) and see where it's actually getting snagged so you can fix it.

eusanpe
March 23rd, 2005, 02:13
I modified my current post. If I allow in then it works. I don't understand. Here is my new config:

##########INITIALIZE VARIABLES ############################

#### Define the Network Interfaces
#
# List our NIC cards. BSD uses separate drivers for different types of
# cards, unlike Linux which lists interfaces as eth0, eth1. If you are
# unsure, run 'dmesg' from the command prompt to see which drivers
# OpenBSD loaded during boot. Ours happen to be dc driver for both
# interfaces. We also list the loopback.

ext_if="xl0" # Untrusted (from WAN ISP) side
int_if="xl1" # Internal to application servers
mgt_if="fxp0" # Management Interface
loop_if="lo0" # LoopBack Device
all_if="{ xl0, xl1, fxp0, lo0 }"

#### Bad IP Networks and Addresses
#
# This section defines which IP networks to reject. Most important, we must
# filter out the non-routable IPs reserved for NAT to protect somewhat against
# spoofing. You could also add other IP's and networks to this list.
#
spoof_ip="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 0.0.0.0/8, \
169.254.0.0/16, 192.0.2.0/24, 204.152.64.0/23 }"
bcast_ip="{ 255.255.255.255, 10.0.0.191, 224.0.0.0/3 }"

#### OPTIONS
set require-order yes
set block-policy return
set optimization normal
set loginterface $ext_if

#### Public Services
# -------------------------
# WWW : Web Server
# -------------------------
web_servers="{ 67.78.202.123, 67.78.202.124}"
web_ports="{ 80, 443, 20, 21, 8080, 8443, 55000, > 49151 }"
web_proto="{ tcp, udp }"

# -------------------------
# DNS : Public access resolvers
# -------------------------
dns_servers="{ 67.78.202.123, 67.78.202.124 }"
dns_ports="{ 53 }"
dns_proto="{ tcp, udp }"

# -------------------------
# MAIL : Public mail server
# -------------------------
mx_servers="{ 67.78.202.123, 67.78.202.124 }"
mx_ports="{ 80, 143, 443, 25, 110, 943, 995 }"
mx_proto="{ tcp }"

# -------------------------
# SSH : Allow remote login
# -------------------------
ssh_servers="{ 67.78.202.123, 67.78.202.124, 67.78.202.125, 67.78.202.126, \
192.168.1/24, 192.168.2/24 }"
ssh_ports="{ 22 }"
ssh_proto="{ tcp }"

# ------------------------------
# Rsync : Allow rsync to inside
# ------------------------------
rsync_ports="{ 873 }"
rsync_proto="{ tcp, udp }"

# -------------------------
# SQL : MySQL
# -------------------------
sql_servers=""
sql_ports="{ 3306 }"
sql_proto=""

# -------------------------
# LDAP : Future Use
# -------------------------
ldp_servers=""
ldp_ports=""
ldp_proto=""

# -------------------------
# TCP / UDP Ports
#--------------------------
tcp_ports="{ 20, 21, 22, 25, 53, 80, 110, 115, 123, 143, 194, 389, 443, 636, 943, 995, > 5500}"
udp_ports="{ 22, 53, 80, 110, 123, 143, 194, 389, 636, 995 }"

#### Illegal Ports
#
# We define particular ports as "illegal". This means that no matter what,
# these ports should not be allowed, nor even attempted from the outside.
# This protects our network against DOS attacks, such as the one that affects
# Microsoft's SQL server, etc...
#
illegal_ports="{ 67, 68, 135, 137, 138, 139, 161, 427, 1433, 1434, 3389, 31335, 31337}"

############################# START FILTER RULES #############################

#### Clean up fragmented and abnormal packets
scrub in on $all_if all
scrub out on $all_if all

#### FTP Proxy
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021

#### Block and log everything by default
block return log on $ext_if all

#### Allow Default In and antispoof
pass in quick on $loop_if all
pass out quick on $loop_if all

#pass in on $ext_if all keep state
antispoof log for $all_if

#### Block inet6 packets
block in log quick inet6 all
block out quick inet6 all

#### Silently drop broadcasts cable modem noise
block in quick on $ext_if from any to 255.255.255.255

#### Block bad tcp flags from malicious people and nmap scans
block in log quick on $ext_if proto tcp from any to any flags /S
block in log quick on $ext_if proto tcp from any to any flags /SFRA
block in log quick on $ext_if proto tcp from any to any flags /SFRAU
block in log quick on $ext_if proto tcp from any to any flags A/A
block in log quick on $ext_if proto tcp from any to any flags F/SFRA
block in log quick on $ext_if proto tcp from any to any flags U/SFRAU
block in log quick on $ext_if proto tcp from any to any flags SF/SF
block in log quick on $ext_if proto tcp from any to any flags SF/SFRA
block in log quick on $ext_if proto tcp from any to any flags SR/SR
block in log quick on $ext_if proto tcp from any to any flags FUP/FUP
block in log quick on $ext_if proto tcp from any to any flags FUP/SFRAUPEW
block in log quick on $ext_if proto tcp from any to any flags SFRAU/SFRAU
block in log quick on $ext_if proto tcp from any to any flags SFRAUP/SFRAUP

# block anything coming from source we have no back routes for
block in log quick from no-route to any

# block and log outgoing packets that don't have our address as source,
# they are either spoofed or something is misconfigured NAT disabled,
# (for instance), we want to be nice and don't send out garbage.
block out quick on $ext_if from ! $ext_if to any

#### Allow internal interface in (block on the external)
pass in quick on $int_if inet proto { tcp, udp } from any to any keep state
pass in quick on $int_if inet proto { icmp } from any to any keep state

#### Allow internal interface out (block on the external)
pass out quick on $int_if inet proto { tcp, udp } from any to any keep state
pass out quick on $int_if inet proto { icmp } from any to any keep state

#### Allow internal interface out (block on the external)
pass out quick on $mgt_if inet proto { tcp, udp } from any to any keep state
pass out quick on $mgt_if inet proto { icmp } from any to any keep state

#### Don't allow anyone to spoof non-routeable addresses or broadcasts
#### also block traffic on restricted ports
block in log quick on $ext_if inet from $spoof_ip to any
block in log quick on $ext_if inet from $bcast_ip to any
block in log quick on $ext_if inet from any to $bcast_ip
block in log quick on $ext_if inet proto { tcp, udp } from any to any port $illegal_ports
block out quick on $ext_if inet from any to $spoof_ip
block out quick on $ext_if inet from $bcast_ip to any
block out quick on $ext_if inet proto { tcp, udp } from any to any port $illegal_ports

#### IN RULES
#
# These rules define what we want to allow INBOUND to our network.
# Primarily, what services are allowed on which machines.
#
#### Generic External IN Rules
@@@pass in on $ext_if inet proto tcp from any to any port $tcp_ports flags S/SA @@@modulate state
@@@pass in on $ext_if inet proto udp from any to any port $udp_ports keep state
pass in on $ext_if inet proto tcp from port 20 to ($ext_if) user proxy flags S/SA modulate state

#### WWW Server Traffic
pass in on $ext_if inet proto $web_proto from any to $web_servers port $web_ports keep state

#### DNS Traffic
pass in on $ext_if inet proto $dns_proto from any to $dns_servers port $dns_ports keep state

#### MAIL Traffic
pass in on $ext_if inet proto $mx_proto from any to $mx_servers port $mx_ports keep stat

#### SSH Traffic
pass in on $ext_if inet proto $ssh_proto from any to $ssh_servers port $ssh_ports keep state

#### Allow ICMP (ping) IN
pass in on $ext_if inet proto icmp all icmp-type 8 code 0 keep state

#### Allow RSYNC IN
pass in on $ext_if inet proto $rsync_proto from any to any port $rsync_ports keep state

#### OUT RULES
#
# This defines what we want to allow OUTBOUND on our WAN.
# Of course allow established inbound requests to be fulfilled
# and then allow everything from our internal network to be allowed
#
#### Pass (Allow) all UDP/TCP OUT and keep state
pass out on $ext_if proto tcp all modulate state
pass out on $ext_if proto udp all keep state

#### Allow rsync
pass out on $ext_if proto $rsync_proto from port $rsync_ports to any

#### Allow ICMP (ping) OUT
pass out on $ext_if inet proto icmp all icmp-type 8 code 0 keep state
===============================================

If I dont add the line that has the @@@, I can't do nothing. I can't go out on the intAny idernet. Any ideas?

Strog
March 28th, 2005, 15:21
Sorry for taking so long to respond, I was out visiting family. I think the biggest issue with this setup is the seperate NAT and firewall. If the firewall was doing the NAT too then you'd have state table entries to take care of this but pf has no idea what the Linksys box is doing at the perimeter.

I'd be extra careful with that management interface since it bypasses the NAT and would have free access through the firewall with everything passed. I'm not saying it's a backdoor but it would be if anything happened. It's my strong opinion that this setup is waaay more complicated than it needs to be and that leaves more room for security risks.