Logging with iptables and nftables

With iptables or nftables, you can log all inbound and outbound connections on a server.


Sometimes it’s helpful to log all inbound and outbound connections on a server—for example, when you need evidence to create firewall rules or to troubleshoot a misconfigured firewall.

The default firewall tool in Debian 9 and previous versions is iptables. This tool has been replaced by nftables since Debian 10.

If you run the following commands (as root), all firewall rules will be cleared, and all connections will be logged to /var/log/messages:

Multiple commands
iptables -F
iptables -I INPUT -m state --state NEW -j LOG --log-level 4 --log-prefix "INCOMING: "
iptables -I OUTPUT -m state --state NEW -j LOG --log-level 4 --log-prefix "OUTGOING: "

Because each connection is logged on a separate line, this quickly becomes hard to read. On a server with heavy traffic, the log file can grow to contain a very large number of lines.

This short and simple one‑liner below summarizes all connections recorded in /var/log/messages. Each host/port combination appears on its own line, and the number of connections is counted. Keep in mind that /var/log/messages may be rotated.

Command
cat /var/log/messages | grep "IN=" | awk -F'[= ]+' '{for (i=1;i < NF;i++) { if ($i=="DST") dst=$(i+1);if ($i=="SRC") src=$(i+1); if ($i=="PROTO") proto=$(i+1); if ($i=="DPT") dpt=$(i+1); if($i=="INCOMING:"||$i=="OUTGOING:") dir=$i} printf "%s %-20s %-20s %-15s %s \n",dir," DST:"dst," SRC:"src," PROTO:"proto," DPT:"dpt}' |sort | uniq -c

The same method can be used to log all blocked connections, which can be very useful for troubleshooting. Below is a complete example of a firewall script that only allows incoming SSH connections from 10.10.10.10 and blocks and logs all other connections:

firewall-script.sh
#!/bin/bash
I=/sbin/iptables
$I -F
$I -A OUTPUT -s 0/0 -m state --state RELATED,ESTABLISHED -j ACCEPT

#SSH in
$I -A INPUT -p TCP --dport 22 -s 10.10.10.10 -j ACCEPT

$I -A INPUT -m state --state NEW -j LOG --log-level 4 --log-prefix "INCOMING: "
$I -A OUTPUT -m state --state NEW -j LOG --log-level 4 --log-prefix "OUTGOING: "
$I -A INPUT -j DROP
$I -A OUTPUT -j DROP

exit 0

Last updated

Was this helpful?