PF pf - does not block traffic to jail

I have remote FreeBSD server with name server inside jail. My rules are:

Code:
ext_if="em0"
ext_ip="X.X.X.X"
jail_net="10.0.0.0/24"

ns_ip="10.0.0.1"

icmp_types = "echoreq"

table <blacklist> persist file "/etc/pf/blacklist"
table <trusted> persist file "/etc/pf/trusted"

set block-policy drop
set loginterface $ext_if
set skip on { lo0 lo1 lo2 lo3 lo4 lo5 lo6 lo7 lo8 lo9 lo10 }

# nat
nat on $ext_if from $jail_net to any -> ($ext_if)

# jail rdr
rdr on $ext_if proto { tcp, udp } from !<blacklist> to $ext_ip port 53 -> $ns_ip
rdr on $ext_if proto { tcp, udp } from any to $ext_ip port 953 -> $ns_ip

# filtering
block log all
pass in quick from <trusted> to any
block quick from <blacklist> to any

pass in quick proto icmp from any to any

pass in quick on $ext_if inet proto tcp from any to $ext_ip port 22 keep state
pass out quick on $ext_if to any keep state

pass in inet proto udp from any to $ns_ip port 53
pass in inet proto { tcp, udp } from any to $ns_ip port 953

Despite having
Code:
block quick from <blacklist> to any
my dns server is still getting queries from IP addresses on the <blacklist>.
What am I missing here?
 
Packets passing in or out on the interface that has "skip on" are not filtered. If your jail interface network is using some of those loopback interfaces this explain why the filtering is not working.

set skip on <ifspec>
List interfaces for which packets should not be filtered. Packets
passing in or out on such interfaces are passed as if pf was dis-
abled, i.e. pf does not process them in any way. This can be use-
ful on loopback and other virtual interfaces, when packet filtering
is not desired and can have unexpected effects. For example:

set skip on lo0
 
How did you update the table?
Several ways:
Code:
pfctl -tblacklist -Tadd <ip_address>
or I'll get ip addresses by script, add it to /etc/pf/blacklist and run:
Code:
pfctl -tblacklist -Treplace -f /etc/pf/blacklist
or just simply restarting pf.
 
Ok, then VladiBG's idea is probably the cause. Just adding to it: restricting your rdr rule doesn't help either (the restriction here is pretty useless) if there's already a connection state recorded for the address in question.
 
Translations that doesn't have pass are still inspected by the filtering and need additional pass rule. In his case he's not having filtering enabled on the loopback interfaces and that's why his " block quick from <blacklist> to any" doesn't include the loopback interfaces. You can easy see this with tcpdump on pflog interface.
 
Code:
rdr on $ext_if proto { tcp, udp } from any to $ext_ip port 953 -> $ns_ip
Not a good idea to allow unfettered access to the control port of your DNS server. If you accidentally forget to set a key on it anyone could take control of your server.
 
Translations that doesn't have pass are still inspected by the filtering and need additional pass rule.
Sure, I'm just saying to restrict the translation is pretty useless here, what you want is actual filtering (block rule).
Hypothetically, in absence of any filtering, are you saying a rdr would be evaluated for every packet arriving, even if it already matches a connection state entry? I'd be surprised ;)
 
If there's already established state for that traffic inside the state table the packet is passed through the firewall without going through ruleset evaluation. You can check your state table using pfctl -ss
 
See, that's what I meant (and expected). And with UDP, there's no way to know when a "connection" ends, so I'd assume a simple timeout mechanism might be used. Therefore my argument that restricting the rdr rule here with the blacklist is pretty much useless. Better redirect all traffic, but then block in a consistent way (already addressed towards your nameserver).
 
Restricting rdr rule with a blacklist is not useless it's a option to allow only traffic of interest as he does with a <trusted> table. The states are created on the filtering rules not on the translation rules but you need to have filtering enabled on the interface in this case loopback interface where the actual jail network is.
 
Restricting rdr rule with a blacklist is not useless it's a option to allow only traffic of interest as he does with a <trusted> table.
It just means it only rewrites addresses on "traffic of interest", so I'd even consider it dangerous in case any service would listen on :53 on the firewall machine. Without rewriting, the correct block rule wouldn't catch that any more, you'd have to additionally block :53 on the host itself. And then, with changing tables, it's unreliable anyways cause the address newly added to your blacklist table could still have an active connection state.
 
Sure you can. To what benefit? If you just rewrite all incoming traffic on port 53 to the internal target machine, you can just filter it in a consistent way (as filtering always happens after rewriting). IMHO, don't restrict the rules doing the rewriting.
 
Yes. And I'd argue this is useless (or maybe even dangerous if, without rewriting, you would reach something on that port).
 
Translations that doesn't have pass are still inspected by the filtering and need additional pass rule. In his case he's not having filtering enabled on the loopback interfaces and that's why his " block quick from <blacklist> to any" doesn't include the loopback interfaces. You can easy see this with tcpdump on pflog interface.
loopback interfaces have nothing to do with it. Anyways, regarding block quick from <blacklist> to any adding interface to it ($ext_if) does exactly the same thing.
Not a good idea to allow unfettered access to the control port of your DNS server. If you accidentally forget to set a key on it anyone could take control of your server.
Sure, it's being taken care of on dns level.
I see what you mean he's not only filtering <blacklist> but also exclude it from rdr
Yes, this config is kinda work in progress.

I do believe connections are being passed due to already established state.
 
Back
Top