On Wed, Apr 17, 2019 at 10:58:37AM +0200, Jan Engelhardt wrote: Hi Jan, > > I disagree. The ct state may be absent because the firewall has an empty state > (e.g. reboot / `conntrack -F`) — that alone does not make the TCP connection > invalid. Blocking ct-less packets breaks the user expectation to get a timely > response (the more so on connection shutdown). > Allowing ct-less packets out does not help in this situation either. If for some reason the NAT's ct gets emptied, and some abnormal packets (orphaned SYN-ACK/FIN) pass through SNAT without NATed, they'd still carry their inner source IP (e.g. 192.168.X.X) in the header, which will not be respected outside of our private network. Hence, although the bad packets are not dropped by NAT, they can go to the internet but eventually gets dropped somewhere else. So the user's experience would be the same as the packets are dropped by NAT. This is what happened here in our network. On the other hand, we see that normal established-state packets can setup ct info on-the-fly even if NAT's ct gets emptied, and can be correctly handled by SNAT later. User's expectation is not broken. > NF_ACCEPT is the proper action, because it mirrors the default policy when the > firewall is unconfigured. Pretty much all common acts of dropping, directly or > indirectly, are opt-in. Resonable. But if an admin setup a SNAT, he/she really does not expect any packet with inner-source-IP showing on the outgoing wire. ;( Not everyone knows that filtering of such packets should setup explicitly. At least that is the case here until we dug into kernel source code. It's a little bit counter intuitive. > > iptables -I FORWARD -m conntrack --ctstate UNTRACKED -j DROP > > Or better yet, model your ruleset such that > --ctstate NEW/ESTABLISHED/$OtherwiseGood -j ACCEPT > -P DROP Thanks for your reply and advice! Regards, Xiaozhou