I wrote a bash script a few months ago which I've called "iptables-trace". It takes start/stop arguments like a simple initscript. Hopefully others on this list will find it useful for debugging. I've attached the script to the bottom of this message. Synopsis: # add a log rule for each existing iptables rule /etc/rc.d/init.d/iptables-trace start # remove all log rules we've added in the past, leaving other rules # untouched /etc/rc.d/init.d/iptables-trace stop When started, the script reads all the rules that are currently loaded into iptables, and inserts a new LOG target above each rule. Every rule in all three tables (mangle,nat,filter) are logged. When stopped, the script removes all the log messages it has added, and leaves the original rules untouched. It can be used on any machine that uses iptables, and requires absolutely no knowledge of the current ruleset. The format for logging messages is as follows: An iptables entry which essentially does: iptables -t filter -A INPUT -p icmp -j icmpIn would be logged as: iptables -t filter -A INPUT -p icmp -j LOG --log-level debug --log-prefix "*f:INPUT:9:icmpIn:" The leading asterisk '*' tags the rule so it can be automatically deleted when we run "iptables-trace stop". The 'f' denotes the filter table, 'INPUT' specifies that the rule was in the INPUT chain, '9' is the index number of the logging rule in that chain (for reference), and 'icmpIn' is the target. So, as an example, here is what is logged to syslog when I ping my machine that is running iptables-trace: Feb 24 12:11:15 vmware-tony2 kernel: *f:INPUT:9:icmpIn:IN=eth0 OUT= MAC=00:50:56:43:ef:36:00:d0:b7:8f:47:af:08:00 SRC=10.33.15.71 DST=10.33.15.123 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=13068 SEQ=256 Feb 24 12:11:15 vmware-tony2 kernel: *f:icmpIn:1:ACCEPT:IN=eth0 OUT= MAC=00:50:56:43:ef:36:00:d0:b7:8f:47:af:08:00 SRC=10.33.15.71 DST=10.33.15.123 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP TYPE=8 CODE=0 ID=13068 SEQ=256 Feb 24 12:11:15 vmware-tony2 kernel: *f:OUTPUT:7:icmpOut:IN= OUT=eth0 SRC=10.33.15.123 DST=10.33.15.71 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=3568 PROTO=ICMP TYPE=0 CODE=0 ID=13068 SEQ=256 Feb 24 12:11:15 vmware-tony2 kernel: *f:icmpOut:3:ACCEPT:IN= OUT=eth0 SRC=10.33.15.123 DST=10.33.15.71 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=3568 PROTO=ICMP TYPE=0 CODE=0 ID=13068 SEQ=256 ------------------------------- #!/bin/bash # $Id: iptables-trace,v 1.6 2003/03/27 00:51:38 apc Exp $ # Author: Tony Clayton <tony-netfilter@xxxxxxxxxxxxxxxxxx> # You may use and edit this code freely. If you make changes to # it that are generally useful, please email them to me and/or # post them on the netfilter mailing list. LOGPREFIX='${table:0:1}:${chain:0:14}:$rulenum:${target:0:14}' log_entry() { local action=$1 local table=$3 chain=$5 shift 5 if [ "$last_chain" != "$chain" ]; then rulenum=1 fi case $action in (skip) ;; (add) local rulespec while [ "$1" != "-j" ]; do rulespec="$rulespec $1" shift; done shift; target=$* eval prefix="${LOGPREFIX}" iptables -t $table -I $chain $rulenum $rulespec -j LOG \ --log-level debug --log-prefix "*${prefix:0:27}:" let rulenum=$rulenum+1 ;; (delete) iptables -t $table -D $chain $rulenum let rulenum=$rulenum-1 ;; esac last_chain=$chain } start() { for table in $(cat /proc/net/ip_tables_names); do rulenum=1 iptables-save -t $table | grep '^-' | \ while read cmd; do log_entry add -t $table $cmd let rulenum=$rulenum+1 done done } stop() { for table in $(cat /proc/net/ip_tables_names); do iptables-save -t $table | grep '^-' | \ while read cmd; do echo $cmd | grep -q -e '--log-prefix "*' if [ $? -eq 0 ]; then log_entry delete -t $table $cmd else log_entry skip -t $table $cmd fi let rulenum=$rulenum+1 done done } case "$1" in start) start ;; stop) stop ;; *) echo $"Usage: $0 {start|stop}" exit 1 esac exit 0