PF pf - does not block traffic to jail

generic

Member

Reaction score: 7
Messages: 53

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?
 

VladiBG

Daemon

Reaction score: 554
Messages: 1,201

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
 
OP
G

generic

Member

Reaction score: 7
Messages: 53

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.
 

Zirias

Son of Beastie

Reaction score: 1,571
Messages: 2,695

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.
 

VladiBG

Daemon

Reaction score: 554
Messages: 1,201

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.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,345
Messages: 38,863

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.
 

Zirias

Son of Beastie

Reaction score: 1,571
Messages: 2,695

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 ;)
 

VladiBG

Daemon

Reaction score: 554
Messages: 1,201

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
 

Zirias

Son of Beastie

Reaction score: 1,571
Messages: 2,695

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).
 

VladiBG

Daemon

Reaction score: 554
Messages: 1,201

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.
 

Zirias

Son of Beastie

Reaction score: 1,571
Messages: 2,695

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.
 

VladiBG

Daemon

Reaction score: 554
Messages: 1,201

You can also flush the state table if it's needed. This will drop all connections tho.
 

Zirias

Son of Beastie

Reaction score: 1,571
Messages: 2,695

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.
 

VladiBG

Daemon

Reaction score: 554
Messages: 1,201

I see what you mean he's not only filtering <blacklist> but also exclude it from rdr
rdr on $ext_if proto { tcp, udp } from !<blacklist> to $ext_ip port 53 -> $ns_ip
 

Zirias

Son of Beastie

Reaction score: 1,571
Messages: 2,695

Yes. And I'd argue this is useless (or maybe even dangerous if, without rewriting, you would reach something on that port).
 
OP
G

generic

Member

Reaction score: 7
Messages: 53

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.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,345
Messages: 38,863

Sure, it's being taken care of on dns level.
Still not a good idea to allow the entire internet access to it. Firewall it properly and only allow access from trusted IP addresses.
 
Top