elmore
April 1st, 2005, 20:35
This ruleset is not even close to done but I thought I'd post what I had anyways, in the hope to get a little feedback. I was having trouble finding a real default deny out ruleset. I decided to create my own. I was loathing the process but once I got going it wasn't that bad. I'm obviously missing some things (lack of ftp atm, and no icmp to the inet, etc...) it's not done yet but it's enough to give everyone a rough idea of where I'm going.


# Macros: define common values, so they can be referenced and changed easily.

ext_if="em0" # replace with actual external interface name i.e., dc0
int_if="em1" # replace with actual internal interface name i.e., dc1
ssh_host="{ 172.16.3.253 }"
web_servers="{ 172.16.3.7 }"

# Tables: Lists of IP Addresses to apply rules to.

table <ineternal_nets> persist file "/etc/internal_nets"
table <NoRouteIP> persist file "/etc/norouteip"
table <Siteip> persist file "/etc/Siteip"
table <badguys> persist file "/etc/badguys"

# Set Optimizations: Set some values to better utilize memory.

set block-policy drop
set limit { frags 5000, states 2500, src-nodes 2000 }
set loginterface $ext_if
set optimization aggressive
set timeout { interval 10, frag 30 }

#Normalization: reassemble fragments and resolve or reduce traffic #ambiguities.

scrub in on $ext_if all fragment reassemble min-ttl 15 max-mss 1400
scrub on $ext_if reassemble tcp

#NAT: Translate to the internal network.

nat on $ext_if from <internal_nets> to any -> $ext_if

#Re-Direct: Re-direct packets to the PDMZ network.

rdr on $ext_if inet proto { tcp, udp } from any to any port 22 -> $ssh_host
rdr on $ext_if inet proto { tcp, udp } from any to any port 80 -> $web_servers
rdr on $ext_if inet proto { tcp, udp } from any to any port 443 -> $web_servers

#Rules: Filter Rules Explanations above each rule.

#Block in Everything by default
block in log on $ext_if all

#Don't allow anyone to spoof unroutable addresses
block in log quick on $ext_if from <NoRouteIP> to any
block out log quick on $ext_if from any to <NoRouteIP>

#Block these badguys
block in log quick on $ext_if inet proto { tcp, udp } from <badguys> to any

#Pass vpn traffic
pass in quick on $ext_if inet proto udp from <Siteip> to $ext_if port = 500 keep state
pass in quick on $ext_if inet proto udp from <Siteip> to $ext_if port = 4500 keep state
pass in quick on $ext_if inet proto esp from <Siteip> to $ext_if keep state

#Pass in ssh
pass in quick on $ext_if proto tcp from any to $ssh_host port = 22 flags S/SA synproxy state

#Pass in Web
pass in quick on $ext_if proto tcp from any to $web_servers port = 80 flags S/SA synproxy state
pass in quick on $ext_if proto tcp from any to $web_servers port = 443 flags S/SA synproxy state

#Default block out
block out log on $ext_if all

#Allow ISAKMP out
pass out quick on $ext_if inet proto udp from $ext_if to <Siteip> port = 500 keep state
pass out quick on $ext_if inet proto udp from $ext_if to <Siteip> port = 4500 keep state
pass out quick on $ext_if inet proto esp from $ext_if to <Siteip> keep state

#Allow SSH out
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = ssh keep state

#Allow WWW
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = www keep state
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = https keep state

#Allow DNS
pass out quick on $ext_if inet proto { udp, udp } from any to any port = domain keep state

#Allow Mail
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 25 keep state
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 465 keep state

#Allow IMAP
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 143 keep state
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 993 keep state

#Allow NNTP
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 119 keep state
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 563 keep state

#Allow NTP
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 123 keep state

#Allow irc
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 194 keep state
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 6667 keep state

#Allow AIM
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 5190 keep state

#Allow REAL Streams
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 554 keep state

#Allow various Poker software ;)
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 2147
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 26229
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 701
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 4095
pass out quick on $ext_if inet proto { tcp, udp } from any to any port = 8500

Kernel_Killer
April 1st, 2005, 23:20
Everything looks good except the last ruleset. :icon_smil

Maybe something to this effect would be good. :wink:


pass out quick on $ext_if inet proto { tcp, udp } from <elmoreboxen> to any port = $pokerports

matbas
April 2nd, 2005, 19:45
You could cut down that file by putting the port numbers in braces.
Also you could use the antispoof command and stop spoofing from your internal network address.

Strog
April 3rd, 2005, 19:06
Also you could use the antispoof command and stop spoofing from your internal network address.

Another option that I like is to deny all and then use explicit passes so I know exactly what can go in and out. I avoid "any to any" passes everywhere possible. I use the :network modifier to make sure that only packets on the same network/subnet that's bound to the firewall's interface is allowed to pass. Everything else will hit the block since it's obviously spoofed. :wink:

pass out on $ext_if inet tcp from $int_if:network to any flags S/SA keep state

The :network modifier uses the network/subnet/broadcast of the interface and generates the rule from that. This makes your rules more dynamic so you don't have to change the ruleset if you resubnet or change your network settings. It also makes your rulesets more portable which is nice if you are supporting multiple firewalls/configs. This approach assumes that you are starting from a default deny config.




Default Deny
The recommended practice when setting up a firewall is to take a "default deny" approach. That is, to deny everything and then selectively allow certain traffic through the firewall. This approach is recommended because it errs on the side of caution and also makes writing a ruleset easier.

To create a default deny filter policy, the first two filter rules should be:

block in all
block out all

This will block all traffic on all interfaces in either direction from anywhere to anywhere.


Elmore,

I'm not exactly sure what you are wanting beyond this. Perhaps a bit more explanation of what you are wanting would help me see what I'm overlooking. Of course you need to add more blocks for spammers, worms, unassigned public IP blocks, etc. to this should be a good starting point.

elmore
April 3rd, 2005, 19:44
Right - The overall goal here is to make a strong egress ruleset. Only allowing out what specifically needs to go out.

For instance, I have two mail servers that need to talk to the internet, port 25 should only be open for those two mail servers outbound. No other computer should be allowed to communicate to the outside world on port 25. etc. etc. As I stated initially the ruleset is quite far from being complete. Egress filtering is something that I haven't seen a lot of in pf, most people have a default deny outbound but then allow all tcp, udp and icmp traffic out. So what's the point of that.

If you're runnning a large corporate network like I am you want very strong egress rulesets to only allow out what needs to go out. This type of ruleset might not be practical for your home but is sorely needed in today's corporate environment.

Just think of the issues you can solve in the corp. environment just by doing this.

Strog
April 3rd, 2005, 23:29
Ah yes, I've seen some really scary setups out there. I worked in a data center of a bank in the late 90's and it was a constant fight to convince the administration of securing things better. I talked to some of the IT people at other banks at some conferences and some of them were doing online banking but didn't even have a firewall on their network. :eek: Do you want your money at a bank like that?

Are you going to be running a proxy with squidguard or some other filtering product on top of this?

elmore
April 4th, 2005, 10:28
Are you going to be running a proxy with squidguard or some other filtering product on top of this?

We're currentlt running squid in trans. proxy mode. We're looking at squid gaurd and Dan's gaurdian for some content filtering.

elmore
April 8th, 2005, 17:54
Here's an update on this:


################################################## ################################################## ##############################
# Macros: define common values, so they can be referenced and changed easily.
ext_if="em0"
int_if="em1"
ssh_host="{ 172.16.3.253 }"
web_servers="{ 172.16.3.7 }"
################################################## ################################################## ##############################

################################################## ################################################## ##############################
# Tables: Lists of IP Addresses to apply rules to.
table <internal_nets> persist file "/etc/internal_nets"
table <Siteip> persist file "/etc/Siteip"
table <badguys> persist file "/etc/badguys"
table <norouteip> persist file "/etc/norouteip"
table <trusted_nets> persist file "/etc/trusted_nets"
table <trusted_hosts> persist file "/etc/trusted_hosts"
################################################## ################################################## ##############################

################################################## ################################################## ##############################
# Set Optimizations: Set some values to better utilize memory.
set block-policy drop
set limit { frags 5000, states 2500, src-nodes 2000 }
set loginterface $ext_if
set optimization aggressive
set timeout { interval 10, frag 30 }
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#Normalization: reassemble fragments and resolve or reduce traffic #ambiguities.
scrub in on $ext_if all fragment reassemble min-ttl 15 max-mss 1400
scrub on $ext_if reassemble tcp
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#NAT: Translate to the internal network.
nat on $ext_if from <internal_nets> to any -> $ext_if
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#Re-Direct: Re-direct packets to the PDMZ network.
rdr on $ext_if inet proto tcp from any to any port 22 -> $ssh_host
rdr on $ext_if inet proto tcp from any to any port 80 -> $web_servers
rdr on $ext_if inet proto tcp from any to any port 443 -> $web_servers
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#Re-Direct for ftp-proxy
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#Rules: Filter Rules Explanations above each rule.
################################################## ################################################## ##############################
#Rules from the outside to us
#Block in Everything by default
block in log on $ext_if all

#Don't allow anyone to spoof unroutable addresses
block in log quick on $ext_if from <norouteip> to any
block out log quick on $ext_if from any to <norouteip>

#Block these badguys
block in log quick on $ext_if inet proto { tcp, udp } from <badguys> to any

#Pass vpn traffic
pass in quick on $ext_if inet proto udp from <Siteip> to $ext_if port = 500 keep state
pass in quick on $ext_if inet proto udp from <Siteip> to $ext_if port = 4500 keep state
pass in quick on $ext_if inet proto esp from <Siteip> to $ext_if keep state

#Pass in ssh
pass in log quick on $ext_if proto tcp from any to $ssh_host port = 22 flags S/SA synproxy state

#Pass in Web
pass in log quick on $ext_if proto tcp from any to $web_servers port = 80 flags S/SA synproxy state
pass in log quick on $ext_if proto tcp from any to $web_servers port = 443 flags S/SA synproxy state

#FTP Proxy Rule
pass in quick on $ext_if inet proto tcp from port 20 to ($ext_if) flags S/SA keep state
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#Rules From the inside going out
#Default Block Out for Internal Net
block in log on $int_if all

#Pass in ssh to $ssh_host
pass in log quick on $int_if inet proto tcp from $ssh_host port = ssh to any synproxy state

#Pass in www to $web_servers
pass in log quick on $int_if inet proto tcp from $web_servers port = www to any synproxy state
pass in log quick on $int_if inet proto tcp from $web_servers port = https to any synproxy state

#Let Trusted Net Traffic out
pass in quick on $int_if inet proto tcp from <trusted_nets> to any keep state
pass in quick on $int_if inet proto udp from <trusted_nets> to any keep state
pass in quick on $int_if inet proto icmp from <trusted_nets> to any keep state

#Let Trusted Hosts Traffic out
pass in quick on $int_if inet proto tcp from <trusted_hosts> to any keep state
pass in quick on $int_if inet proto udp from <trusted_hosts> to any keep state
pass in quick on $int_if inet proto icmp from <trusted_hosts> to any keep state

#Let Internal Traffic Flow Freely
pass in quick on $int_if inet proto tcp from <internal_nets> to <internal_nets> keep state
pass in quick on $int_if inet proto udp from <internal_nets> to <internal_nets> keep state
pass in quick on $int_if inet proto icmp from <internal_nets> to <internal_nets> keep state

#Allow these tcp services
pass in quick on $int_if inet proto tcp from <internal_nets> to any port \
{ www, https, ssh, smtp, 465, imap, imaps, 119, 563, 194, 6667, 5190, 554 } keep state

#Allow these udp services
pass in quick on $int_if inet proto udp from <internal_nets> to any port \
{ domain, ntp } keep state

#Allow FTP (broken out intentionally)
pass in quick on $int_if inet proto tcp from <internal_nets> to any port = 21 keep state
pass in quick on $int_if inet proto tcp from <internal_nets> to 127.0.0.1 port = 8021 keep state

#Allow All traffic up to the firewall (mainly for proxies i.e. squid - ftp-proxy)
pass in quick on $int_if inet proto tcp from <internal_nets> to $int_if keep state
################################################## ################################################## ##############################

################################################## ################################################## ##############################
#Outbound Rules for the Firewall
#Pass ISAKMP out
pass out quick on $ext_if inet proto udp from $ext_if to <Siteip> port = 500 keep state
pass out quick on $ext_if inet proto udp from $ext_if to <Siteip> port = 4500 keep state
pass out quick on $ext_if inet proto esp from $ext_if to <Siteip> keep state

#Let traffic out for the External Interface
pass out quick on $ext_if inet proto tcp from $ext_if to any flags S/SA keep state
pass out quick on $ext_if inet proto udp from $ext_if to any keep state
pass out quick on $ext_if inet proto icmp from $ext_if to any keep state
################################################## ################################################## ##############################



Lots of changes over the first one. Now filtering on both interfaces, typos fixed, ftp now working, etc.

elmore
April 10th, 2005, 01:19
Here's the production ruleset, complete with CBQ now.

If anyone has comments or suggestions I'd love to hear them.

http://screamingelectron.org/~elmore/pf/pf.egress.cbq

tarballed
April 10th, 2005, 15:01
Here's the production ruleset, complete with CBQ now.

If anyone has comments or suggestions I'd love to hear them.

http://screamingelectron.org/~elmore/pf/pf.egress.cbq

I like it elmore. You gave me a lot of ideas on rules i'd like to implement.

Being as that I have a bit more pull in decisions that are going to be made at our company now, one thing I really want to do is add at least one OpenBSD Firewall and if I have it my way, use OpenBSD as our company Firewall. Still need approval on it. I recently posted a thread in this forum about rules I am playing with at my home network as im gearing up to using PF more. I also asked what type of hardware would be a good choice for my needs, based on users and bandwidth.

I definitly like your 'egress' approach and would like to borrow some of your ideas.

Cheers.

newmember
April 13th, 2005, 15:46
http://schubert.cx/src/pf.conf

This one works really well.
I like the use of the /etc/services file.
It has:
Altq
Spamd
Tables
All in it.

I still cant get mine to except ssh from outside networks.
I'll have to give it another try.

It's default deny all.


Cheers