How Does "This Firewall (Self)" Apply in CARP Setups?
-
@planedrop
"This Firewall (Self)" is what its name implies. It's the firewall itself.
It includes any interface address as well as any virtual address assigned to any interface and also the loopback address. -
@planedrop Years ago when we set up our data center HA we did use an alias. Depending on the setup of public vs private IPs that would also block "from any to router2 LAN IP" for instance.
@viragomann But This Firewall wouldn't include router2's WAN or LAN IP...? (unless router1 was off)
-
@steveits said in How Does "This Firewall (Self)" Apply in CARP Setups?:
But This Firewall wouldn't include router2's WAN or LAN IP...? (unless router1 was off)
No, the secondary node not, naturally. Only its own addresses.
But there is no need to have the second node included in the alias at all anyway.
When the rule is synced to the secondary, it will fit as well with "This firewall" to block / pass access. So there is no need to configure an specific alias for that. -
@viragomann @SteveITS Thank you both for the help on this!
What about the CARP address though, it's technically not assigned on an interface so I'm not sure this rule would cover it?
Also, say a device attempted to contact the secondary node wouldn't the rule only be checked by the primary before traffic is forwarded? Maybe I'm misunderstanding how that would work.
-
@planedrop said in How Does "This Firewall (Self)" Apply in CARP Setups?:
say a device attempted to contact the secondary node
In my data center scenario that's what I was talking about, though I didn't explain it. If there is only one public IP and NAT is in use then the Internet can connect to either router1 WAN, router2 WAN, or the CARP WAN, and This Firewall would cover it.
However in our data center there are three public IPs on the WAN side and the LAN side is 128 public IPs. So someone could connect to router2's public LAN IP from the Internet, and This Firewall on router1 wouldn't block the connection to router2 LAN.
re: CARP, as viragomann noted, any virtual address also. You'd think This Firewall might be in Diagnostics/Tables for clarity, but it's not...maybe it's not a table, internally.
-
@steveits OK this helps me a ton, thank you!!
-
@planedrop
Again, the "This firewall" alias covers all IPs assigned to any of the firewalls interfaces.
So it includes interface IPs, CARP VIPs and IP aliases as well on either WAN or LAN or any other interface.The masters "This firewall" alias does not cover IPs of the secondary node, but since the rules are synced to the secondary, there is the same rule with "This firewall" and this one matches to the secondary nodes IPs then.
So yeah, when you block any access to the destination "This firewall", whether the primary nor the secondary can be accessed.However, this alias does not cover your whole network. That means, when you use it in a block rule from any you can still route traffic through the firewall or forward traffic to targets behind it.
-
@viragomann OK perfect, this makes total sense to me now, thank you for all the help! Kinda wish pfSense had a table or something that showed exactly what IPs this firewall referenced, but I guess now I know lol. Cool stuff regardless though.
-
@planedrop Just to expand upon what @viragomann said, since this is an issue near and dear to my heart, you're right to wonder whether this can still lead to unintended consequences. Based on our experience, there are situations where blocking "(self)" still allows access to the secondary, though this doesn't seem to be widely understood or accepted.
You can see the pf rules by looking at
/tmp/rules.debug
or runningpfctl -sr
on the command line. pf refers to it as(self)
, for example with a built-in rule for allowing CARP -# CARP rules block in log quick proto carp from (self) to any tracker 1000000201 pass quick proto carp tracker 1000000202 no state
An issue can arise where the primary firewall allows traffic through to the secondary firewall, if traffic is routed through the primary first, and "Synchronize states" is turned on. (E.g., traffic comes through the primary's WAN interface and accesses the secondary's LAN interface.) The secondary firewall's rules aren't encompassed by the
(self)
on the primary, and then by the time it hits the secondary, it's in the state table and then allowed through to the secondary without the ruleset being re-evaluated.Of course, then the secondary will send it back through its own WAN interface, so you get some asymmetric routing, and the connection on the primary eventually times out and has to be re-established. So it's not a very long window of possibility, especially for ssh, but definitely enough to keep a web session going through to the secondary, though it keeps getting re-established.
The only way we've found so far to get around this is by creating an alias, as you mentioned, or disabling state syncing.
-
See https://forum.netgate.com/topic/144339/preventing-access-to-secondary-firewall/27 for a more complete writeup.
-
@kayavila said in How Does "This Firewall (Self)" Apply in CARP Setups?:
An issue can arise where the primary firewall allows traffic through to the secondary firewall, if traffic is routed through the primary first, and "Synchronize states" is turned on.
Agree, there could be an issue if you configure your rules harum-scarumly like this:
(E.g., traffic comes through the primary's WAN interface and accesses the secondary's LAN interface.)
That means to me, you're forwarding traffic from WAN to the secondary LAN IP?
I see...But what has that to do with syncing states?
A possible risk is the Anti-Lockout Rule for sure, which allows access to the LAN address from any IP on LAN. I'd recommend to replace it by a rule only allowing access from LAN network.
But if you configure your rules carefully and allow only desired access instead of blocking the undesired, I see no risk with this.
-
The important point is that (self) doesn't always protect the secondary firewall's IP addresses in ways that people expect it to, if CARP and state syncing is turned on.
@viragomann I'm not sure what you mean by "harum-scarumly", but there's no forwarding involved - pure routing. It doesn't take anything weird to get into this situation.
Here's an example. Say you allow subnet A from somewhere outside the WAN interface access to subnet B that's routed by the firewalls on the LAN interface. The secondary firewall also has an IP address on the LAN subnet. A rule allowing subnet A access to all of subnet B allows access to the secondary firewall's LAN IP address.
How do you protect the secondary's B IP address in this situation? A rule above blocking all traffic to (self) won't stop the traffic, because the primary firewall evaluates the traffic destined to the secondary's IP address on subnet B, and it doesn't match (self) on the primary firewall. Then the state table line allowing that traffic is passed over to the secondary firewall. The secondary firewall doesn't re-evaluate the rules - which would match (self) on it if it did evaluate - because the allowed state is already in the state table.
-
@kayavila said in How Does "This Firewall (Self)" Apply in CARP Setups?:
How do you protect the secondary's B IP address in this situation?
As I wrote in my last sentence above, I rather use pass rules than block rules to allow only what is needed. I use "This firewall" in pass rules only and if the access should be limited I state a source.
However, you can also achieve security with block rules by configuring the source accordingly.So when I allow access to "This firewall" (webGUI, DNS, etc.), I state the desired sources in the pass rules. Hence forwarded or routed traffic from any other source cannot access my secondary's LAN IP, even if the packet is coming from inside my LAN, because it is blocked by the secondary node itself by the synced firewall rule.
This could only be the case if you allow access from any, as I mentioned above. -
@viragomann I'm glad that works for you, but that not may not handle everyone's cases. E.g., as in my example, where you're allowing access to an entire subnet that's protected behind the firewall. It's a very common firewall pattern (not just in pfSense) to do something like -
- Block access from 172.16.100.0/24 to 10.0.0.1
- Allow access from 172.16.100.0/24 to 10.0.0.0/24
It's important that people understand that (self) rules may not be as protective as they believe them to be in these situations.
-
@kayavila said in How Does "This Firewall (Self)" Apply in CARP Setups?:
It's a very common firewall pattern (not just in pfSense) to do something like -
Block access from 172.16.100.0/24 to 10.0.0.1I'd make if I really want to block only 172.16.100.0/24.
My policy for sources and destinations when creating firewall rules is:
block rule: as wide as possible
pass rule: as small as really neededAnd overall as less rules as necessary to keep lucidity.
So I don't need to have much concerns about allowing something, that I don't want to.
It's important that people understand that (self) rules may not be as protective as they believe them to be in these situations.
Absolutely agree. Didn't claim the opposite.
-
@kayavila OK this is great info, thank you! I read your entire write up you linked to as well but I'm still trying to wrap my brain around it. Think I've got it figured out but wanted to pose an example.
This particular one will be between different VLAN/subnets rather than with WAN as I personally don't ever allow those connections via the WAN.
So in theory if you had VLAN1 and VLAN2 setup, and there was an any-any rule below a block "This Firewall" rule on VLAN1, and some device on VLAN1 tried to contact the LAN interface of VLAN2, due to state syncing this would be let through? Since the first node would see the connection to the VLAN2 IP and see that it's not in it's block list but matches the any-any rule, and then the state would sync to the secondary which wouldn't assess it's rules?
If that is the case, I would imagine not having a rule on the primary node that allows access to any would solve the issue, but since some people do use an any rule for internet access it could pose a problem (though best practice is of course to use an alias for RFC1918 and explicitly allow the inverse of that).