# best filewall program for single interface firewall



## wonslung (May 13, 2009)

Hello, i'm new to FreeBSD.  I normally use debian based linux distros...Switched to freebsd because of it's support of the ZFS filesystem (which has been amazing)
I normally use Shorewall to setup my firewall on debian based systems....it's surprisingly simple to use...i was wondering if there was any tool/guide for setting up the firewall in freebsd...when i did a search i found there are 3 firewalls for freebsd and it's a little confusing as to which one to use/which one is the best.
(PF, IPFW or IPFILTER)

any help would be greatly appreciated


----------



## Lowell (May 13, 2009)

There's no obvious answer to that question.  Different people find the syntax for one or another of the choices to be more comfortable.

You might want to look at security/fwbuilder, to see if things can be _even more_ comfortable for you.


----------



## Oko (May 13, 2009)

wonslung said:
			
		

> it's a little confusing as to which one to use/which one is the best.
> (PF, IPFW or IPFILTER)
> 
> any help would be greatly appreciated



PF

Cheers,
Oko


----------



## Oko (May 13, 2009)

Lowell said:
			
		

> There's no obvious answer to that question.  Different people find the syntax for one or another of the choices to be more comfortable.
> 
> You might want to look at security/fwbuilder, to see if things can be _even more_ comfortable for you.



So you are suggesting that he runs X on a firewall. Good advice
You probably also suggest that he installs compiler on his firewall as well:\


----------



## wonslung (May 13, 2009)

i was basically looking for something somewhat similar to shorewall
shorewall works by setting simple stuff in a couple files then it uses those files to make ipfilter rules if i understand it correctly.  

Being new to freebsd i didn't know if there was even a solution as simple or close.

like....for instance with shorewall i have these files:
interfaces:
this lists the interfaces in the system and the zone they are associated with, and options....like

net  eth0   detect    dhcp,tcpflags,logmartians,nosmurfs


then next, you have a zones file.  for my needs (single interface firewall)  it has just 2, net and fw

then next i'd have a file called "policy" that explains the default firewall policy

#SOURCE         DEST            POLICY          LOG LEVEL  
$FW             net             ACCEPT
net             $FW             DROP            info
net             all             DROP            info
all             all             REJECT          info


then finially you'd have a file called rules which would give firewall rules that you wanted, basically anything you want to be DIFFERENT than the default policy.

an example would be if you want net traffic for http something like this

ACCEPT   net    $FW     tcp     80


and with those very simple files it would set up iptables....because iptables by itself was a pain in the rump to configure....i mean, i'm sure theres lots of gurus out there who laugh at me and say "hahahah, you are stupid" but shorewall does the exact same thing as what they have in less time...very easily

sooooo
is there anything like this for pf or ipfw?


----------



## FBSDin20Steps (May 13, 2009)

This is the right one.

http://www.freebsd.org/doc/en/books/handbook/firewalls.html


----------



## wonslung (May 13, 2009)

i've read that, that lists 3.  Did you read my original question?
Does anyone have a simple guide for ANY of them when dealing with a single interface...i don't need nat, i just want to set up a firewall on my server to protect and log traffic.


----------



## wonslung (May 13, 2009)

also, it's worth mentioning that i AM using aliasing...i currently have 6 ip's on the single interface...


----------



## FBSDin20Steps (May 13, 2009)

> i've read that, that lists 3.  Did you read my original question?



Yes. pick one and then ask questions.


----------



## wonslung (May 13, 2009)

oh wow, the firewall builder lowell suggested is a web based gui? is that correct?
that's pretty cool...i'm looking at that now, also ordered a book called "the book of pf" 
hopefully that will help for the long run =)


----------



## wonslung (May 13, 2009)

never mind, i read it wrong..i do not want to install x to configure a filewall...thanks anways....going to look into understanding pf more....when i'm done reading up on it if i don't understand i'll ask....my biggest worry si that it is a remote system, i have web and ssh su access and i don't want to screw up and lock myself out


----------



## FBSDin20Steps (May 13, 2009)

http://home.nuug.no/~peter/pf/en/


----------



## tangram (May 13, 2009)

Isn't Shorewall a Linux distro that acts as a firewall? If so, on the BSD world you'd interested in pfSense.


----------



## wonslung (May 13, 2009)

tangram said:
			
		

> Isn't Shorewall a Linux distro that acts as a firewall? If so, on the BSD world you'd interested in pfSense.



no, shorewall is a linux package that helps to configure iptables.
honestly after reading up on pf i feel stupid for even ASKING

coming from a linux background, pf is exactly what iptables should be.....it's amazingly simple....it just makes sense....it took me all of 20 minutest to figure it out and get a basic config going...i guess comng from linux i was thinking that in freebsd IT HAD TO BE HARDER!...mainly because i'm still getting used to the subtle differences....for instance rc.conf and rc.d scripts vs init.d from debian based linux....

the fact of the matter is iptables is SUCH a pain in the ass that you really need something like shorewall as a beginner.

pf is even MORE simple in the default configuration

for instance

this is my iptables config for one of my systems

```
:PREROUTING ACCEPT [168403858]
:OUTPUT ACCEPT [207439200]
COMMIT
# Completed on Wed May 13 05:03:12 2009
# Generated by iptables-save v1.4.0 on Wed May 13 05:03:12 2009
*nat
:PREROUTING ACCEPT [542389]
:POSTROUTING ACCEPT [1302262]
:OUTPUT ACCEPT [1302262]
COMMIT
# Completed on Wed May 13 05:03:12 2009
# Generated by iptables-save v1.4.0 on Wed May 13 05:03:12 2009
*mangle
:PREROUTING ACCEPT [168403858]
:INPUT ACCEPT [168397599]
:FORWARD ACCEPT [0]
:OUTPUT ACCEPT [207439201]
:POSTROUTING ACCEPT [207532409]
:tcfor - [0]
:tcout - [0]
:tcpost - [0]
:tcpre - [0]
-A PREROUTING -j tcpre 
-A FORWARD -j tcfor 
-A OUTPUT -j tcout 
-A POSTROUTING -j tcpost 
COMMIT
# Completed on Wed May 13 05:03:12 2009
# Generated by iptables-save v1.4.0 on Wed May 13 05:03:12 2009
*filter
:INPUT DROP [1]
:FORWARD DROP [0]
:OUTPUT DROP [0]
:Drop - [0]
:Reject - [0]
:all2all - [0]
:dropBcast - [0]
:dropInvalid - [0]
:dropNotSyn - [0]
:dynamic - [0]
:eth0_fwd - [0]
:eth0_in - [0]
:eth0_out - [0]
:fw2net - [0]
:logdrop - [0]
:logflags - [0]
:logreject - [0]
:net2all - [0]
:net2fw - [0]
:reject - [0]
:shorewall - [0]
:smurfs - [0]
:tcpflags - [0]
-A INPUT -i lo -j ACCEPT 
-A INPUT -i eth0 -j eth0_in 
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A INPUT -j Reject 
-A INPUT -j LOG --log-prefix "Shorewall:INPUT:REJECT:" --log-level 6 
-A INPUT -j reject 
-A FORWARD -i eth0 -j eth0_fwd 
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A FORWARD -j Reject 
-A FORWARD -j LOG --log-prefix "Shorewall:FORWARD:REJECT:" --log-level 6 
-A FORWARD -j reject 
-A OUTPUT -o lo -j ACCEPT 
-A OUTPUT -o eth0 -j eth0_out 
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A OUTPUT -j Reject 
-A OUTPUT -j LOG --log-prefix "Shorewall:OUTPUT:REJECT:" --log-level 6 
-A OUTPUT -j reject 
-A Drop -p tcp -m tcp --dport 113 -j reject 
-A Drop -j dropBcast 
-A Drop -p icmp -m icmp --icmp-type 3/4 -j ACCEPT 
-A Drop -p icmp -m icmp --icmp-type 11 -j ACCEPT 
-A Drop -j dropInvalid 
-A Drop -p udp -m multiport --dports 135,445 -j DROP 
-A Drop -p udp -m udp --dport 137:139 -j DROP 
-A Drop -p udp -m udp --sport 137 --dport 1024:65535 -j DROP 
-A Drop -p tcp -m multiport --dports 135,139,445 -j DROP 
-A Drop -p udp -m udp --dport 1900 -j DROP 
-A Drop -p tcp -j dropNotSyn 
-A Drop -p udp -m udp --sport 53 -j DROP 
-A Reject -p tcp -m tcp --dport 113 -j reject 
-A Reject -j dropBcast 
-A Reject -p icmp -m icmp --icmp-type 3/4 -j ACCEPT 
-A Reject -p icmp -m icmp --icmp-type 11 -j ACCEPT 
-A Reject -j dropInvalid 
-A Reject -p udp -m multiport --dports 135,445 -j reject 
-A Reject -p udp -m udp --dport 137:139 -j reject 
-A Reject -p udp -m udp --sport 137 --dport 1024:65535 -j reject 
-A Reject -p tcp -m multiport --dports 135,139,445 -j reject 
-A Reject -p udp -m udp --dport 1900 -j DROP 
-A Reject -p tcp -j dropNotSyn 
-A Reject -p udp -m udp --sport 53 -j DROP 
-A all2all -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A all2all -j Reject 
-A all2all -j LOG --log-prefix "Shorewall:all2all:REJECT:" --log-level 6 
-A all2all -j reject 
-A dropBcast -m pkttype --pkt-type broadcast -j DROP 
-A dropBcast -m pkttype --pkt-type multicast -j DROP 
-A dropInvalid -m state --state INVALID -j DROP 
-A dropNotSyn -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j DROP 
-A eth0_fwd -m state --state INVALID,NEW -j dynamic 
-A eth0_fwd -m state --state INVALID,NEW -j smurfs 
-A eth0_fwd -p tcp -j tcpflags 
-A eth0_in -m state --state INVALID,NEW -j dynamic 
-A eth0_in -m state --state INVALID,NEW -j smurfs 
-A eth0_in -p udp -m udp --dport 67:68 -j ACCEPT 
-A eth0_in -p tcp -j tcpflags 
-A eth0_in -j net2fw 
-A eth0_out -p udp -m udp --dport 67:68 -j ACCEPT 
-A eth0_out -j fw2net 
-A fw2net -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A fw2net -d 192.168.2.0/24 -j ACCEPT 
-A fw2net -j ACCEPT 
-A logdrop -j LOG --log-prefix "Shorewall:logdrop:DROP:" --log-level 6 
-A logdrop -j DROP 
-A logflags -j LOG --log-prefix "Shorewall:logflags:DROP:" --log-level 6 
-A logflags -j DROP 
-A logreject -j LOG --log-prefix "Shorewall:logreject:REJECT:" --log-level 6 
-A logreject -j reject 
-A net2all -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A net2all -j Drop 
-A net2all -j LOG --log-prefix "Shorewall:net2all:DROP:" --log-level 6 
-A net2all -j DROP 
-A net2fw -m state --state RELATED,ESTABLISHED -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 21 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 80 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 143 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 25 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 22 -j ACCEPT 
-A net2fw -s 192.168.2.0/24 -j ACCEPT 
-A net2fw -s 192.168.1.0/24 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 25 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 465 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 587 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 143 -j ACCEPT 
-A net2fw -p tcp -m tcp --dport 993 -j ACCEPT 
-A net2fw -j Drop 
-A net2fw -j LOG --log-prefix "Shorewall:net2fw:DROP:" --log-level 6 
-A net2fw -j DROP 
-A reject -m pkttype --pkt-type broadcast -j DROP 
-A reject -m pkttype --pkt-type multicast -j DROP 
-A reject -s 255.255.255.255/32 -j DROP 
-A reject -s 224.0.0.0/4 -j DROP 
-A reject -p igmp -j DROP 
-A reject -p tcp -j REJECT --reject-with tcp-reset 
-A reject -p udp -j REJECT --reject-with icmp-port-unreachable 
-A reject -p icmp -j REJECT --reject-with icmp-host-unreachable 
-A reject -j REJECT --reject-with icmp-host-prohibited 
-A smurfs -s 192.168.1.255/32 -j LOG --log-prefix "Shorewall:smurfs:DROP:" --log-level 6 
-A smurfs -s 192.168.1.255/32 -j DROP 
-A smurfs -s 255.255.255.255/32 -j LOG --log-prefix "Shorewall:smurfs:DROP:" --log-level 6 
-A smurfs -s 255.255.255.255/32 -j DROP 
-A smurfs -s 224.0.0.0/4 -j LOG --log-prefix "Shorewall:smurfs:DROP:" --log-level 6 
-A smurfs -s 224.0.0.0/4 -j DROP 
-A tcpflags -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,PSH,URG -j logflags 
-A tcpflags -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j logflags 
-A tcpflags -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j logflags 
-A tcpflags -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j logflags 
-A tcpflags -p tcp -m tcp --sport 0 --tcp-flags FIN,SYN,RST,ACK SYN -j logflags
```

now, to set that up even in a config file is a major pain.

the exact same setup in pf seems to be something like this.

```
tcp_services = "{ssh, smtp, domain, ftp, www, pop3, auth, https, pop3s }
udp_services = "{ domain, ftp }
            
block all              
pass out proto tcp to any port $tcp_services keep state
pass proto udp to any port $udp_services keep state
```

i'm sure i dont' have it PERFECT yet...but just the difference in syntax simplicity is amazing
so if i made a fool of myself...please understand that i REALLY though ti was going to be hard


----------



## wonslung (May 13, 2009)

one quick question i DO have is....am i right in understanding that the basic pf config i showed will work with my single interface on all ip's? or do i need to have rules for alias ips?

again, this is a single machine attached to the internet
no NAT, no address rewriting.


----------



## wonslung (May 13, 2009)

man, is it NOT possible to edit a post here?
i wanted to edit my post before last to say that i indead know about pfsense and currently use it for my local router....love it, much props to those guys and the whole freebsd machine.


----------



## SirDice (May 13, 2009)

You can use things like:


```
$int=rl0

block all

#allow traffic to/from localhost
pass in quick on lo0 all
pass out quick on lo0 all 

pass in on $int proto tcp from any to any port $tcp_services keep state
pass in on $int proto udp from any to any port $udp_services keep state

# allow everything to go out
pass out on $int proto tcp/udp from any to any keep state
```

The "on $int" will make sure the data goes in/out that interface, regardless of it's ip addresses. You can also use "($int)" if you need to really use it's ip addresses in a rule. 

You may want to add some rules for ICMP, like TTL expired and port unreachable.

NB, you can edit posts once you reach a certain level, not sure when that happens, I'm sure it's in the FAQ somewhere.


----------



## wonslung (May 13, 2009)

thank you, your post was most helpful, durring the course of my reading i'm noticing ftp can cause problems...what is the "correct" way of dealing with an ftp server with my configuration (single interface non nat, web server with ftp)

i'm sorry for all the questions...i just dont' want to start this up till i am fairly sure i understand it....


----------



## tangram (May 13, 2009)

wonslung said:
			
		

> man, is it NOT possible to edit a post here?
> i wanted to edit my post



Hehe... almost there. You need 10 posts and 10 days of membership


----------



## SirDice (May 13, 2009)

wonslung said:
			
		

> thank you, your post was most helpful, durring the course of my reading i'm noticing ftp can cause problems...what is the "correct" way of dealing with an ftp server with my configuration (single interface non nat, web server with ftp)


FTP mainly causes problems when using NAT. That has to do with the FTP protocol dynamically opening ports (the PORT command). But since you're not using NAT this would probably be relatively simple. I just don't use FTP because of the issues, I just share my files using HTTP :e

http://www.openbsd.org/faq/pf/ftp.html


----------



## wonslung (May 13, 2009)

jesus, that scared the crap out of me....loaded the rules and did /etc/rc.d/pf start and ssh shut me out

soon as entered a new ssh it worked, i guess the old one wasn't a "state" yet....wow, scary, lol


anyways, this is what i ended up with.

my server is for web/ftp and has a bit torrent client running
i also have a couple things on non-standard ports
this is my config...my big question is....with bit torrent do i need a tule to open the ports coming in or does the outgoing rule + keep state automatically neglect the need for it?

```
#defined services 
tcp_services = "{ssh, smtp, domain, ftp, www, pop3, auth, https, pop3s }"
udp_services = "{ domain, ftp }"

#interface for all ip's on em0
int="em0"

#default block rule    
block all

#allow traffic to/from localhost
pass in quick on lo0 all
pass out quick on lo0 all

#non-standard web ports for "hidden" web config pages 
pass in on $int proto tcp from any to any port 8080 keep state
pass in on $int proto tcp from any to any port 85 keep state

#default pass in for our defined services
pass in on $int proto tcp from any to any port $tcp_services keep state
pass in on $int proto udp from any to any port $udp_services keep state

#pass in for passive ftp ports
pass in quick on $int proto tcp from any to any port 10064:10264 keep state

#pass in for all torrentflux-b4rt services
pass in quick on $int proto tcp from any to any port 44000:49000 keep state

# allow everything else out
pass out on $int proto tcp from any to any keep state
pass out on $int proto udp from any to any keep state
```

i'm still reeling over how much more simple the syntax was than iptables/ipchains....

i switched to freebsd for ZFS support, it just makes sense for my application (non-profit seedbox where i need to put size quotas on directories)

i have had a FEW bumps in the road, i do appreciate everyone's help, except the people who just point at manual pages, that's pretty annoying....but at least you didn't REALLY flame me...there is THAT.

thanks guys


----------



## vivek (May 13, 2009)

+1 for pf. 

PF is not just easy to use but perfect alternative (PF+CRAP+ALTQ) to overpriced Cisco gear 

Apart from man page, I also recommend "The Book Of PF".


----------



## DutchDaemon (May 13, 2009)

FreeBSD has excellent manual pages, as opposed to, well, you know. That's why people keep pointing other people to them, especially when it's apparent that they've not been read, or read enough.


----------



## SirDice (May 13, 2009)

wonslung said:
			
		

> jesus, that scared the crap out of me....loaded the rules and did /etc/rc.d/pf start and ssh shut me out
> 
> soon as entered a new ssh it worked, i guess the old one wasn't a "state" yet....wow, scary, lol


If you want to test a new ruleset use something like this:

Test if the syntax is ok:

```
# pfctl -nf /etc/pf.conf
```

This will load the rules, sleep for 10 seconds then disable pf:

```
# pfctl -f /etc/pf.conf && sleep 10 && pfctl -d
```

If you make a mistake and lock yourself out you can get back in after 10 seconds :e



> my big question is....with bit torrent do i need a tule to open the ports coming in or does the outgoing rule + keep state automatically neglect the need for it?



Bittorrent will need at least a few ports open (tcp/udp 6882 IIRC), if you don't downloads will go horribly slow. The outgoing connections should work fine when keeping state.


----------



## Lowell (May 13, 2009)

Oko said:
			
		

> So you are suggesting that he runs X on a firewall. Good advice
> You probably also suggest that he installs compiler on his firewall as well:\



No, I don't think so.  Although I don't use it, my understanding is that fwbuilder's gui doesn't need to run on the same machine being configured.


----------



## wonslung (May 13, 2009)

yah, i guess i was intimidated into thinking everything on freebsd was harder than linux but it turns out it's just different, and in many cases more logical/easy.

I'm glad i switched


----------



## hydra (May 14, 2009)

I would recommend PF, it's fairly easy to set up and the documentation on OpenBSD's site is great too.


----------



## wonslung (May 14, 2009)

yes, i did end up going with pf hydra, it's fantastic.


----------



## wonslung (May 17, 2009)

Rather than start a new thread i am just going to use this one to post my new pf questions.


If my interface has several ip's and i want to make a rule for just a single ip instead of something like

pass in on $int proto tcp from any to any port 8000 keep state


would it be

pass in on 1.1.1.1 

or would it be 

pass in on $int:1.1.1.1 

sorry if this is a stupid question...my reason for asking is i have 6 ip's, and i'm running nginx which is listening on port 80 on all ip's....i want to enable http downloading from my server but currently users will use some kind of download manager and make 20 connections....so i want to limit the number of connections per ip AND i want to throttle the total bandwidth.

i recompiled my kernel with ALTQ...and i think this should be pretty easy but since i have different pages on those different ip's all pertaining to the site...i don't want to just set a hard limit on the entire interface....i don't want to block access to the forums just because a user is downloading a file, or block access to the blogs because they are downloading a file.


----------



## DutchDaemon (May 17, 2009)

Just leave _$int_ alone and replace the second _any_ (the destination) with the IP address. IMO, those any's are way overused in most firewall rulesets.


----------



## wonslung (May 17, 2009)

ok, cool, makes sense....i feel stupid now but thanks =)


----------

