PF Packet filter inside a jail? (or filtering before NAT)

Hi everyone,

Is it possible to use a packet filter inside a jail?

I already use this one on my physical host but I'm doing NAT to/from my jail's virtual interfaces and in PF NAT rules need to be written before all the filtering rules. All my HTTP packets are redirected to my HTTP jail so for example I can't blacklist an IP (from some country) with my table's blocking rules, they are all redirects in my HTTP jail... before blocking :confused:

So maybe I can also use PF inside my HTTP jail with some basics rules, but in /etc/rc.conf in my jail:
Code:
# No network interfaces in jails
network_interfaces=""
Problem?

Or, if possible, how to blacklist IP lists before all NAT/redirect operations?

Thanks for the advice.

(PS: The new forum version is nice.)
 
Last edited:
Hello,

It would be a lot easier to answer you by viewing your rules. Anyway, I don't think it is a problem on your host's rules to do a redirect with rdr on (without using the quick keyword), and then to filter based on the source IP address. The destination address is modified, but the source should not.

Also, you could redirect only connections from sources you trust, as shown there: http://www.openbsd.gr/faq/pf/rdr.html (warning: OpenBSD syntax is different).

Regards,
Guillaume
 
It's not possible to control the packet filter from inside a jail, this is by design because the jails do not get their own instances of the network interfaces but have to use the ones exposed by the system as per the jail configuration. Instead what you have to do is set up all filtering and redirections in the host's PF configuration.
 
Or, if possible, how to blacklist IP lists before all NAT/Redirect operations?
Here is the rule from my greylister. I hope it helps. $argus is a jailed mail/postfix.
Code:
rdr on $ext proto tcp from { <spamd-white>, <spamd-manual> } to $main port smtp -> $argus port smtp
rdr on $ext proto tcp from { !<spamd-white>, !<spamd-manual> } to $main port smtp -> $int port spamd
 
Thanks for all your responses and help.

Indeed I'm a packet filter beginner and not a network specialist. My configuration is absolutely not fine tuned.

/etc/pf.conf:
Code:
ext_if="bge0"
int_if = "lo444"

ext_ip = "( " $ext_if " )"

#
#Jailnet lo444
jailnet = $int_if:network

# Name and IP of jails
WEBSERVER="10.8.8.8"
DATABASE="10.8.8.9"

#Services locaux
sshport ="{XXXXX}"

#Stat
set loginterface bge0

#Normalisation des paquets
scrub in all

#
#TABLE
#
table <sshguard> persist
table <blacklist> file '/etc/pf.blacklist' persist

#
# Nat and redirect
#

nat on $ext_if from $jailnet to any -> ($ext_if)
nat pass on $ext_if from $jailnet to any -> ($ext_if)

# Redirect any packets requesting port 80 or 443 to jailed webserver
rdr pass on $ext_if inet proto tcp to port http -> $WEBSERVER port http
rdr pass on $ext_if inet proto tcp to port https -> $WEBSERVER port https

#MySQL et WWW are in two differents Jail
#They need to communicate

rdr pass on $int_if inet proto tcp from $WEBSERVER to port 3306 -> $DATABASE port 3306
pass quick on $int_if inet proto tcp from $WEBSERVER to $DATABASE port 3306 keep state

#
#Rules Filtering
#

#Blocking all
block log all

#Tout ce qui se trouve dans les tables sera bloque
block in quick on $ext_if proto tcp from <sshguard> to any port $sshport label "ssh bruteforce"
block in quick on $ext_if from <blacklist> to any

# Allow SSH on physical host
pass in on $ext_if inet proto tcp from any to ($ext_if) port $sshport
pass out on $ext_if proto tcp from ($ext_if) to any port $sshport keep state

#On peut sortir
pass out on $ext_if

abishai: indeed that's useful in my case, thanks for the syntax tips, I'm not very familiar with all the PF macros.
 
I tried to fix your pf rules, without the complete knowledge of your network, and without being able to test it. I made some assumptions that may be wrong so be careful. I provide it "as is", use (and fix!) at your own risk:
Code:
# --- Variables and Tables ---
##############################
ext_if = "bge0"
int_if = "lo444"
lan_network = $int_if:network
JAIL_WEB="10.8.8.8"
JAIL_SQL="10.8.8.9"

# !!! Please customize these 3 variables according to your addresses !!!
# main host, running the jails
myself="10.8.8.7"

# computer you connect from
admin="10.8.8.2"

# your local ssh port
sshport="22"

table <sshguard>
table <blacklist> persist file "/etc/pf.blacklist"

# --- Global options ---
##############################
set block-policy drop
set loginterface bge0
set skip on lo
scrub in all

# --- NAT and Redirect ---
##############################
nat on $ext_if from $lan_network to any -> ($ext_if)

# Prevent unwanted networks to access your jail, redirect only if not in the table
rdr on $ext_if inet proto tcp from !<blacklist> to $myself port { http, https } -> $JAIL_WEB

# --- Rules Filtering ---
##############################
block log all

# Allow redirected connections to the jail
pass in quick on $int_if proto tcp to $JAIL_WEB port { http, https } keep state

# Allow you web jail to access your database jail
pass in quick on $int_if inet proto tcp from $JAIL_WEB to $JAIL_SQL port 3306 keep state

# Block and log accesses from disallowed hosts and networks
block in quick log on $ext_if proto tcp from <sshguard> to $myself port $sshport
block in quick log on $ext_if from <blacklist> to any

# Allow SSH from remote admin computer to physical host
pass in quick on $ext_if inet proto tcp from $admin to $myself port $sshport keep state

# Allow the host to connect out
pass out quick on $ext_if modulate state
If it does not work as intended, it should be close enough for you to be able to fix it by yourself to suit your needs. If you are unsure about a rule's syntax, you can test your file without loading it with $ sudo pfctl -nf /etc/pf.conf. If you want further help you can check the FreeBSD Handbook at http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/firewalls-pf.html.

Be careful when looking at links showing OpenBSD pf syntax, it can be quite different.

Regards,
Guillaume
 
  1. It's better to rewrite internal communications as no state to preserve resources.
  2. Why modulate state for out packets?
 
  • Indeed, I have never written rules for internal jail communications, usually the skip lo0 is all I need, I added the keep state without thinking about it.
  • This rule will apply to outbound LAN traffic being NATed as well, and generating stronger TCP ISN in that case can be better depending on the source OS (the rule description does not fully match the rule scope). I'm using that kind of rule on my router.
As I said above, I made some assumptions without knowing the network. It is certainly not optimal and may need to be improved :)

EDIT: Also the sshguard table is not filled, I let the thread creator hande that case too, either by filling a file or by adding hosts and/or networks to the table directly.
 
Thanks so much for your help.

You'r pf configuration looks like great, however my HTTP access is blocked by IP access or FQDN. I have of course made a backup of my old configuration.

In /var/log/pflog:
tcpdump -n -e -ttt -r /var/log/pflog port 443
Code:
00:00:02.852644 rule 0..16777216/0(match): block in on bge0: 85.171.63.231.50143 > 10.8.8.8.443: Flags [S], seq 65263488, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
00:00:21.002461 rule 0..16777216/0(match): block in on bge0: 85.171.63.231.50145 > 10.8.8.8.443: Flags [S], seq 1869103241, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
00:01:09.765159 rule 0..16777216/0(match): block in on bge0: 192.168.0.10.50147 > 10.8.8.8.443: Flags [S], seq 3520792887, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
00:00:00.250204 rule 0..16777216/0(match): block in on bge0: 192.168.0.10.50148 > 10.8.8.8.443: Flags [S], seq 686298177, win 8192, options [mss 1460,nop,wscale 2,nop,nop,sackOK], length 0
[/S][/S][/S][/S]
 
Last edited:
It seems I put the wrong interface in the following rule:
Code:
# Allow redirected connections to the jail
pass in quick on $int_if proto tcp to $JAIL_WEB port { http, https } keep state
It should be $ext_if I guess. At this point, you should be able to figure it out ;)
 
Back
Top