Simple? PF question. Just learning

Ive been working with some examples of pf.conf trying to get my own firewall up and running. I have several questions probably but i'll start with what I think is a simple one. I found a sample pf.conf that had a couple of rules in it that I dont quite understand.

1.

Code:
block in log quick on $ext_if from </rfc1918><rfc1918> to any

The table is.

Code:
table <rfc1918> const { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

I understand this table and what it is for. What I dont understand is why this rule has </rfc1918> and also <rfc1918>

2.

Code:
pass in quick on $int_if inet proto { udp, icmp } from $pvt_net to !</firewall><firewall> keep state

This table is

Code:
table <firewall> const { self }

Once again I understand "sort of" the table created for this. The { self } is not 100% clear. Once again I see the same thing only this time there is a !</firewall> and <firewall>. Can anyone explain this usage to me?
 
I would guess this is a bug in the example, it should be like this:
Code:
block in log quick on $ext_if from <rfc1918> to any
I'm not sure why they used tables for some of these, like the rfc1918 stuff. Personally I'd use a Macro like this:
Code:
rfc1918 = '{ 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }'
Tables are for things that are changing often, like a dynamic add/remove of IPs that get thrown in and pulled out via a script.
 
And here I thought that he knew a secret. :)

Now for the tougher question. I am using a computer running 7.0-RELEASE-p5 as a firewall/gateway for my home lan using PF for firewall and nat. I am also running a ftpd in one jail, and a httpd in another. I am finding that it is tough to impose firewall rules on the jailed environments since i notice through the logs that they connect out as the hosts ip and not the alias that I have set. My question, is there a way to firewall/restrict the ability of the jailed environments to connect out without affecting the host? And if not, I would like to remove all non required binaries to each jail especially ones that allow connecting out. Is there a good place to find information on something like this? Or any suggestions?
 
neurosis said:
I am finding that it is tough to impose firewall rules on the jailed environments since i notice through the logs that they connect out as the hosts ip and not the alias that I have set.

I'm not necessarily saying I disagree, but could you prove this with some log entries?

I am not seeing the behavior you describe.

From one my jails (IP x.y.174.231):
Code:
somejail# nc -z -w 2 172.16.83.29 443
Connection to 172.16.83.29 443 port [tcp/https] succeeded!

From its host (IP x.y.174.216), with tcpdump running during that scan:
Code:
myhost# tcpdump -n port 443
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on le0, link-type EN10MB (Ethernet), capture size 96 bytes
23:05:18.990639 IP x.y.[b]174.231[/b].52871 > 172.16.83.29.443: S 2105350826:2105350826(0) win 65535 <mss 1460,nop,wscale 1,nop,nop,timestamp 190218784 0,sackOK,eol>
23:05:18.991200 IP 172.16.83.29.443 > x.y.[b]174.231[/b].52871: S 181417086:181417086(0) ack 2105350827 win 5792 <mss 1460,sackOK,timestamp 2718361686 190218784,nop,wscale 2>
23:05:18.991261 IP x.y.[b]174.231[/b].52871 > 172.16.83.29.443: . ack 1 win 33304 <nop,nop,timestamp 190218785 2718361686>
...

In this case it would be easy to add filtering rules restricting the jail's IP specifically.
 
Code:
$ ftp ftp.freebsd.org
Trying 62.243.72.50...
Connected to ftp.freebsd.org.
220 ftp.FreeBSD.org NcFTPd Server (licensed copy) ready.

This is me trying to connect to ftp.freebsd.org using ftp from inside of my jail. my jail ip is 10.1.10.10

Code:
]$ ifconfig
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8<VLAN_MTU>
        ether 00:40:2b:42:b7:a7
        inet 10.1.10.10 netmask 0xffffffff broadcast 10.1.10.10
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active

Here is what tcpdump shows. Keep in mind that my firewall is set up behind a router at the moment for testing so the ip is issued from the router.


Code:
# tcpdump -e -n -i pflog0
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 96 bytes
21:26:26.926172 rule 2/0(match): pass out on re0: 192.168.1.12.59439 > 192.168.1.1.53: [|domain]
21:26:26.927850 rule 2/0(match): pass out on re0: 192.168.1.12.60785 > 192.168.1.1.53: [|domain]
21:26:26.989300 rule 2/0(match): pass out on re0: 192.168.1.12.60327 > 62.243.72.50.21:  tcp 40 [bad hdr length 0 - too short, < 20]

At the moment I have all rules set to log all incoming and outgoing connections.

192.168.1.12 is the external address of the machine. Maybe I have something set up wrong? I would love to figure this out.

Also, I have my jail alias's set to my internal nic rather than external. Would this make a difference?


Here is what I get when I try to make the same connection from my lan which is 10.1.10.1/29


Code:
]# tcpdump -e -n -i pflog0
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 96 bytes
22:16:56.679304 rule 3/0(match): pass in on rl0: 10.1.10.2.1070 > 68.87.69.146.53: [|domain]
22:16:56.679367 rule 2/0(match): pass out on re0: 192.168.1.12.57238 > 68.87.69.146.53: [|domain]
22:16:56.840289 rule 3/0(match): pass in on rl0: 10.1.10.2.1116 > 204.152.184.73.21: [|tcp]
22:16:56.840356 rule 2/0(match): pass out on re0: 192.168.1.12.54613 > 204.152.184.73.21:  tcp 28 [bad hdr length 0 - too short, < 20]
22:16:57.255265 rule 3/0(match): pass in on rl0: 10.1.10.2.1117 > 204.152.184.73.45705: [|tcp]
22:16:57.255332 rule 2/0(match): pass out on re0: 192.168.1.12.50094 > 204.152.184.73.45705: [|tcp]

See how it shows the connection coming in from the lan (10.1.10.2) and then going out on re0 (192.168.1.12).
 
A couple questions:
  1. Are you doing NAT?
  2. Could you also try tcpdump on the ethernet interface itself (in the same fashion as my example)? Do you see the same behavior then?

If 'yes' to question #2, please post your /etc/rc.conf entries related to jails.
 
Yes, I am using NAT


Code:
$ nc -z -w 2 171.161.161.173 443
Connection to 171.161.161.173 443 port [tcp/https] succeeded!

Code:
tcpdump -i rl0 -n port 443
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on rl0, link-type EN10MB (Ethernet), capture size 96 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel

Code:
$ nc -z -w 2 171.161.161.173 443
Connection to 171.161.161.173 443 port [tcp/https] succeeded!

Code:
]# tcpdump -i re0 -n port 443
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on re0, link-type EN10MB (Ethernet), capture size 96 bytes
11:24:46.652280 IP 192.168.1.12.56217 > 171.161.161.173.443: S 3792416822:3792416822(0) win 65535 <mss 1460,nop,wscale 3,sackOK,timestamp 65243527 0>
11:24:46.717704 IP 171.161.161.173.443 > 192.168.1.12.56217: S 3310184549:3310184549(0) ack 3792416823 win 33304 <nop,nop,timestamp 873254270 65243527,mss 1460,nop,wscale 0,nop,nop,sackOK>
11:24:46.717826 IP 192.168.1.12.56217 > 171.161.161.173.443: . ack 1 win 8326 <nop,nop,timestamp 65243592 873254270>
11:24:46.720565 IP 192.168.1.12.56217 > 171.161.161.173.443: F 1:1(0) ack 1 win 8326 <nop,nop,timestamp 65243595 873254270>
11:24:46.783253 IP 171.161.161.173.443 > 192.168.1.12.56217: . ack 2 win 33304 <nop,nop,timestamp 873254277 65243595>
11:24:46.787017 IP 171.161.161.173.443 > 192.168.1.12.56217: F 1:1(0) ack 2 win 33304 <nop,nop,timestamp 873254277 65243595>
11:24:46.787090 IP 192.168.1.12.56217 > 171.161.161.173.443: . ack 2 win 8325 <nop,nop,timestamp 65243662 873254277>

Goes right to re0

This behavior I believe is due to my nat rules. I changed them and it fixed this behavior but then it broke my ftpd. Now I am struggling trying to figure out which ports i need and how to forward them to get my ftpd working again. :(
 
Ftp is not so messy but when I am running it in a jail and requires nat it becomes confusing to me. :) with the nat rule set as before it made it easy to deal with. Now i have to figure out how to allow the needed traffic out of the jail and to pass through the firewall in to the real world. :( My web server was very simple..

I read the faq on openbsd.org. I dont want to use proxy. I will try to stick with passive ports.
 
I've same setup a single FreeBSD r7p5 box. I run http and FTP inside jail. One interface is connected to the Internet and other to my Lan. This box can be accesed through my office via admin IP range. Here is complete working /etc/pf.conf,

Code:
#### First declare a couple of variables ####
### Outgoing tcp / udp port ####
### 43 - whois, 22 - ssh ###
tcp_services = "{ ssh, smtp, domain, www, https, 22, ntp, 43,ftp, ftp-data}"
udp_services = "{ domain, ntp }"
### allow ping / pong ####
icmp_types = "{ echoreq, unreach }"
 
#### define tables. add all subnets and ips to block
table <blockedip> persist file "/etc/pf.block.ip.conf"
 
martians = "{ 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 }"
 
### admin server ranges ###
adminrange = "112.220.11.0/23"
 
# connected to internet
ext_if = "em1"

# connected to vpn / lan
int_if = "em0"
 
##### ftp proxy
#proxy="127.0.0.1"
#proxyport="8021"
 
#### Normliaztion
#scrub provides a measure of protection against certain kinds of attacks based on incorrect handling of packet fragments
scrub in all
 
#### NAT and RDR start
#nat-anchor "ftp-proxy/*"
#rdr-anchor "ftp-proxy/*"
 
# redirect ftp traffic
#rdr pass proto tcp from any to any port ftp -> $proxy port $proxyport
 
# Drop incomming everything
block in all
block return 
 
# keep stats of outging connections
pass out keep state
 
# We need to have an anchor for ftp-proxy
#anchor "ftp-proxy/*"
 
# unlimited traffic  for loopback and lan / vpn
set skip on {lo0, $int_if}
 
# activate spoofing protection for all interfaces
block in quick from urpf-failed
 
#antispoof is a common special case of filtering and blocking. This mechanism protects against activity from spoofed or forged IP addresses
antispoof log for $ext_if
 
#Block RFC 1918 addresses
block drop in log (all)  quick on $ext_if from $martians to any
block drop out log (all) quick on $ext_if from any to $martians
 
# Block all ips
# pfctl -t blockedip -T show
block drop in log (all)  quick on $ext_if from <blockedip> to any
block drop out log (all) quick on $ext_if from any to <blockedip>
 
# allow outgoing
pass out on $ext_if proto tcp to any port $tcp_services
pass out on $ext_if proto udp to any port $udp_services
 
# Allow trace route
pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 keep state
 
# Allow admin to get into box
pass in on $int_if from $adminrange to any
 
# Allo incomming ssh, http, bind traffic
# pass in  on $ext_if proto tcp from any to any port 25
pass in on $ext_if proto tcp from ant to any port ssh  flags S/SA synproxy state
pass in on $ext_if proto tcp from ant to any port http  flags S/SA synproxy state
pass in on $ext_if proto udp from any to any port domain
pass in on $ext_if proto tcp from any to any port domain flags S/SA synproxy state
pass in on $ext_if proto tcp from any to any port http flags S/SA synproxy modulate state
pass inet proto icmp all icmp-type $icmp_types keep state
## add your rule below ##

You need to create /etc/pf.block.ip.conf to block IPs as follows:
Code:
192.168.30.1
202.54.1.2
 
vivek said:
I've same setup a single FreeBSD r7p5 box. I run http and FTP inside jail. One interface is connected to the Internet and other to my Lan. This box can be accesed through my office via admin IP range. Here is complete working /etc/pf.conf,

I have a couple of questions about your rules. Maybe this will help me to understand a little better.

Do you only connect to your ftpd from your LAN? I dont see any rules allowing outside connections in to your ftpd.

I am also a little confused by this. You have

Code:
# keep stats of outging connections
pass out keep state

Doesnt this allow "ALL" outgoing connections from your firewall? and would that make these next rules un-necessary?

Code:
# allow outgoing
pass out on $ext_if proto tcp to any port $tcp_services
pass out on $ext_if proto udp to any port $udp_services
 
# Allow trace route
pass out on $ext_if inet proto udp from any to any port 33433 >< 33626 keep state

I havent tested this but want to some time today or tomorrow. Im sorry if these are dumb questions, but I am just trying to learn.

Thanks.
 
neurosis said:
Do you only connect to your ftpd from your LAN? I dont see any rules allowing outside connections in to your ftpd.
I connect it from both LAN and the Internet, add something as follows:

Code:
pass in on $ext_if proto tcp from any to any port 21 flags S/SA synproxy state
pass in on $ext_if proto tcp from any to any port > 49151 keep state
Note, you need to set ftp ranges in file and this is what indicated by port > 49151.

neurosis said:
I am also a little confused by this. You have

Code:
# keep stats of outging connections
pass out keep state

You can modify it if you want.. this is just template I copied from some website. My original rules are same but with little modification and 1 public IP. So yes it will allow outgoing traffic. All I wanted was filter incoming. Once in traffic is permitted to go outside. As I said you need to modify template for your setup.

Hope this helps.
 
Back
Top