iptables: find out what packet is blocked by which rule?

You can look at packet/byte counters:

Chain FIREWALL (2 references)
pkts bytes target prot opt in out source destination

73M 42G ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0

You can clear the counters with the '-Z' option. You can direct types of packets to their own table and accept them individually based on the source if you want to track the source.

iptables -N SMTP
iptables -I INPUT -p tcp --dport 25 -j SMTP
iptables -A SMTP -s $network_1 -j ACCEPT
iptables -A SMTP -s $network_2 -j ACCEPT
iptables -A SMTP -j RETURN

#Track by network instead of application
iptables -N NETWORK_1 
iptables -I INPUT -s $network_1 -j NETWORK_1
iptables -A NETWORK_1 -p tcp --dport 25 -j ACCEPT -m comment --comment "MAIL"
iptables -A NETWORK_1 -p udp --dport 10000:20000 -j ACCEPT -m comment --comment "VOIP RTP"
iptables -A NETwORK_1 -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A NETWORK_1 -p tcp -j ACCEPT -m comment --comment "UNKNOWN TCP"
iptables -A NETWORK_1 -j RETURN -m comment --comment "This rule is not required but used for ip accounting"

There is also -j ULOG, that you can use together with ulogd.


Look into the TRACE target

This target marks packets so that the kernel will log every rule which match the packets as those tra-verse the tables, chains, rules. (The ipt_LOG or ip6t_LOG module is required for the logging.) The packets are logged with the string prefix: "TRACE: tablename:chainname:type:rulenum " where type can be "rule" for plain rule, "return" for implicit rule at the end of a user defined chain and "policy" for the policy of the built in chains. It can only be used in the raw table.