State Filtering Question
-
Hello, I have a question about how pfSense (2.4.5) is filtering states when a ruleid is passed in.
On the Firewall->Rules->Interface Tab, under the column 'States' there is a <# of States>/<# of bytes> <KiB/MiB> entry that is also a link to
diag_dump_states.php?ruleid=...
I would expect the states shown to correspond to ones that were matched by the rule(s) specified in the ruleid.
It seems to work on some rules but not other rules. For example, if I click on the link in a row with a rule that just matches ICMP traffic, I see tcp states but If I click on a rule that just matches TCP/443 packets, that seems to correctly filter. And if I click on a rule that matches only UDP/53 packets, I see tcp connections as well.
It looks like the
pfSense_get_pf_states
function tries to do the filtering by matching thestate.rule
with the ruleid that was passed in. Does every state have a rule associated with it?https://github.com/pfsense/FreeBSD-ports/blob/a9adf1491b0e981bc12a5164570b93f4d8694a94/devel/php-pfSense-module/files/pfSense.c#L3665
Thank you
-
ICMP traffic uses states ?
It's just one packet send out, and one packet comes back. The state is done.( this is me thinking out loud - setting up an entire SYNC ACK etc session would be overkill for ICMP )
@fibersnet said in State Filtering Question:
And if I click on a rule that matches only UDP/53 packets
Not related, but keep in mind that DNS answers can be to big for UDP. TCP will be used then.
I guess another connection would be used for this.
Filtering DNS traffic using only UDP/53 can break your DNS.@fibersnet said in State Filtering Question:
Does every state have a rule associated with it?
A state is created if a initially unknown packet comes into an interface, and matches a rule.
A subsequent packets of the same "data stream" will match this uniquely constructed state, no more need to parse the entire firewall rule set again. That's what a state-base firewall is all about. -
From reading the pf docs, pf can keep state about icmp packets (as well as UDP packets which are stateless)
Thanks for the tip on filtering DNS on UDP/53, but rest assured I was not filtering, I had a permit rule just to do some logging.
That is actually how I ran into this issue.
How to reproduce:Create a permit rule on an interface:
Action: Pass
Address Family: IPv4
Protocol: TCP/UDP
Source: network for that interface
Destination: address of the interface
Destination Port Range: 53, 67, 123After some time, I click on the link that shows me the states:
https://10.1.10.1/diag_dump_states.php?ruleid=114,115,116,117,118,119
I'm guessing there are 6 rules because, 3 (ports) * 2 (tcp and udp)
As expected I see entries like:
Protocol: udp
Source -> Destination: 10.1.10.106:52707 -> 10.1.10.1:53
State: SINGLE:MULTIPLE
Packets: 1/1
Bytes 88B / 131BBut unexpectedly I see entries like:
Protocol: udp
Source -> Destination: 10.1.10.107:58362 -> 141.207.151.233:4500
State: MULTIPLE:MULTIPLE
Packets: 27.146K / 38.017 K
Bytes: 3.9 MiB / 5.78 MiBThe Destination isn't even the address of the interface, (its some verizon one), and the destination port isn't in 53, 67, 123 (its 4500).
So I am curious why that entry is showing up when it should not be associated with that permit rule.
-
@fibersnet said in State Filtering Question:
Source -> Destination: 10.1.10.107:58362 -> 141.207.151.233:4500
Very special animal.
IPSec .... NAT traversal ...I'll block that one and see what happens - I do not IPSEC ....
-
Here is another example with some more debug info:
I created a permit rule in pfSense to allow NTP traffic on 123/UDP.
pfSense creates a link in the States column:diag_dump_states.php?ruleid=122
I click on it and see tcp traffic there which of course is unexpected.
Now to verify this:
$ pfctl -vvsr | grep -A3 '@122' @122(1544378750) pass in quick on igb0.20 inet proto udp from 10.1.20.0/24 to 10.1.20.1 port = ntp keep state label "USER_RULE: allow pfSense services" [ Evaluations: 271440 Packets: 137 Bytes: 12710 States: 1 ] [ Inserted: pid 34596 State Creations: 27 ]
And now lets look at the state table, I don't understand why there is TCP traffic that is labeled with
rule 122
$ pfctl -vvss | grep -B2 -A1 'rule 122' igb0.20 tcp 172.217.7.14:443 <- 10.1.20.60:57309 ESTABLISHED:ESTABLISHED [1344343563 + 55723] wscale 8 [55088501 + 268800] wscale 7 age 17:04:30, expires in 103:27:58, 239:237 pkts, 109178:80245 bytes, rule 122 id: 010000005e9f003e creatorid: ef6de259 -- igb0.20 tcp 172.253.63.188:5228 <- 10.1.20.101:49961 ESTABLISHED:ESTABLISHED [1573218077 + 42304] wscale 8 [3525452166 + 64768] wscale 6 age 31:43:08, expires in 111:24:22, 1965:1974 pkts, 104738:118461 bytes, rule 122 id: 010000005e9e8202 creatorid: ef6de259 -- igb0.20 tcp 172.253.122.188:5228 <- 10.1.20.107:49308 ESTABLISHED:ESTABLISHED [952469950 + 445440] wscale 8 [3218978541 + 64768] wscale 8 age 18:49:36, expires in 118:51:20, 446:458 pkts, 31266:130786 bytes, rule 122 id: 020000005e9f0771 creatorid: ef6de259 --
Perhaps my understanding of the
rule 122
is incorrect, but is it valid key to use to identify which rule allowed a particular state? -
mystery solved
rawtaz in the irc channel suggested killing the state that referred to a rule it should not be referring to.
When the state was re-established, it came up referencing the correct rule. The most likely scenario is that when the firewall rules are changed (i.e. adding or removing rules changes the number of the rules), the already established states do not have the rule numbers updated.
This is a pf 'issue' and not pfSense since pfSense reads
/dev/pf
to get the states that match a particular rule.