On Wed, Jun 25, 2003 at 10:17:56AM +0100, Marc Beyer wrote:
> So I would assume that "keep state" only works for ICMP replies coming
> from one of the two machines directly involved in the connection. This
> makes perfect sense if pf does not inspect the ICMP content to determine
> whether it's part of an established connection. I assume this is a known
> issue/expected behaviour? Is the recommended way of dealing with this a
> set of extra rules to handle this kind of traffic?
No, they should be covered by the TCP/UDP state entries.
The two ICMP types you mentioned are both ICMP errors. These ICMP
packets must contain (sufficient parts of the header of) the TCP/UDP
packet they refer to. For instance, an ICMP time exceeded must contain
the packet whose TTL got 0.
pf uses that inner header to look up the state entry. The inner header
must be sufficiently long, so the IP source/destination addresses and
TCP/UDP source/destination port can be extracted. In case of TCP, the
sequence numbers must also be found and pass the state windows.
If you see them blocked, there's either
- no matching state entry (the ICMP error refers to a packet that
doesn't match any pf state), for instance some broken NAT gateway
translates the outer IP header but leaves the inner IP header
untranslated, so you get stuff like
rule 17/0(match): block in on kue0: 213.73.160.188 > 62.65.145.30:
icmp: host 192.168.1.2 unreachable [tos 0xc0] (ttl 55, id 64944)
213.73.160.188 is an external host, 62.65.145.30 my external
address, and I'm not using any 192.168.x.x addresses at all.
I certainly didn't send a packet with destination 192.168.1.2,
and even if I did, it would never have reached 213.73.160.188.
Instead, 192.168.1.2 is a host in the external LAN, probably
NATed (or RDRed) by 213.73.160.188. And the gateway is forwarding
(or generating) the ICMP error due to local problems, without
translating it properly. Their problem, not fixable by me. I see
this every now and then.
- or there is a matching state, but the sequence number in the
quoted TCP packet doesn't match the state windows. In this
case, pf can't trust the ICMP error. It could be spoofed by
a malicious third party (not the real peer of the ongoing TCP
connection), trying to disrupt or redirect the TCP connection.
If you enable debug logging (pfctl -xm), you get "Bad ICMP" entries in
/var/log/messages for the latter case, while the former case should be
obvious from inspecting just pflog.
But valid ICMP errors are indeed associated with TCP/UDP state entries,
and passed along with them, so you don't need to add any rules dealing
with them.
The other type of ICMP packets are ICMP queries/replies (like ping),
which do not refer to other packets. Those can create state entries
themselves (and ICMP errors can also refer to ICMP queries/replies, but
not to other ICMP errors). Ping is the only kind people commonly allow,
and the example ruleset shows how to deal with them (query creates
state, reply matches state).
HTH,
Daniel