Log dropped connections from iptables firewall using rsyslog for further analysis and troubleshooting.
Configure rsyslog to use /var/log/firewall.log
log file for firewall events.
$ cat << EOF | sudo tee /etc/rsyslog.d/firewall.conf # Log messages generated by iptables firewall to file :msg,contains,"[fw-" /var/log/firewall.log # stop processing it further & stop EOF
Apply rsyslog configuration.
$ sudo systemctl restart rsyslog
Rotate log file to conserve disk space.
$ cat << EOF | sudo tee /etc/logrotate.d/firewall.conf /var/log/firewall.log { rotate 7 daily missingok notifempty delaycompress compress postrotate invoke-rc.d rsyslog rotate > /dev/null endscript } EOF
Create iptables firewall that will allow already established connections, incoming icmp and ssh, outgoing icmp, ntp, dns, ssh, http and https. It will also log invalid packets and those dropped ones.
# Flush rules and delete custom chains iptables -F iptables -X # Define chain to allow particular source addresses iptables -N chain-incoming-ssh iptables -A chain-incoming-ssh -s 192.168.1.149 -j ACCEPT -m comment --comment "local access" iptables -A chain-incoming-ssh -p tcp --dport 22 -j LOG --log-prefix "[fw-inc-ssh] " -m limit --limit 6/min --limit-burst 4 iptables -A chain-incoming-ssh -j DROP # Define chain to log and drop incoming packets iptables -N chain-incoming-log-and-drop iptables -A chain-incoming-log-and-drop -j LOG --log-prefix "[fw-inc-drop] " -m limit --limit 6/min --limit-burst 4 iptables -A chain-incoming-log-and-drop -j DROP # Define chain to log and drop outgoing packets iptables -N chain-outgoing-log-and-drop iptables -A chain-outgoing-log-and-drop -j LOG --log-prefix "[fw-out-drop] " -m limit --limit 6/min --limit-burst 4 iptables -A chain-outgoing-log-and-drop -j DROP # Drop invalid packets iptables -A INPUT -m conntrack --ctstate INVALID -j chain-incoming-log-and-drop # Accept everything on loopback iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # ACCEPT incoming packets for established connections iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Accept incoming ICMP iptables -A INPUT -p icmp -j ACCEPT # Accept incoming SSH iptables -A INPUT -p tcp --dport 22 -j chain-incoming-ssh # Accept outgoing packets for established connections iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Accept outgoing DNS iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT iptables -A OUTPUT -p udp --dport 53 -j ACCEPT # Accept outgoing NTP iptables -A OUTPUT -p tcp --dport 123 -j ACCEPT iptables -A OUTPUT -p udp --dport 123 -j ACCEPT # Accept outgoing HTTP/S iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # Accept outgoing SSH iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT # Accept outgoing ICMP iptables -A OUTPUT -p icmp -j ACCEPT # Log not accounted outgoing traffic iptables -A OUTPUT -j chain-outgoing-log-and-drop # Log not accounted forwarding traffic iptables -A FORWARD -j chain-incoming-log-and-drop # Drop everything else iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP
List all firewall rules to verify that executed commands are applied as desired.
$ sudo iptables -L -v -n
Chain INPUT (policy DROP 14 packets, 756 bytes) pkts bytes target prot opt in out source destination 0 0 chain-incoming-log-and-drop all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 515 188K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 1 60 chain-incoming-ssh tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 Chain FORWARD (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 chain-incoming-log-and-drop all -- * * 0.0.0.0/0 0.0.0.0/0 Chain OUTPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 380 70413 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 8 530 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:123 0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:123 2 120 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 2 120 chain-outgoing-log-and-drop all -- * * 0.0.0.0/0 0.0.0.0/0 Chain chain-incoming-log-and-drop (2 references) pkts bytes target prot opt in out source destination 0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 6/min burst 4 LOG flags 0 level 4 prefix "[fw-inc-drop] " 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain chain-incoming-ssh (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * * 192.168.1.149 0.0.0.0/0 /* local access */ 1 60 LOG tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 limit: avg 6/min burst 4 LOG flags 0 level 4 prefix "[fw-inc-ssh] " 1 60 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 Chain chain-outgoing-log-and-drop (1 references) pkts bytes target prot opt in out source destination 2 120 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 6/min burst 4 LOG flags 0 level 4 prefix "[fw-out-drop] " 2 120 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Sample log entries.
$ sudo tail /var/log/firewall.log
Dec 31 13:48:24 debian kernel: [29030.017110] [fw-out-drop] IN= OUT=eth0 SRC=192.168.1.131 DST=84.16.240.28 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=63807 DF PROTO=TCP SPT=34610 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 Dec 31 13:48:25 debian kernel: [29031.040102] [fw-out-drop] IN= OUT=eth0 SRC=192.168.1.131 DST=84.16.240.28 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=63808 DF PROTO=TCP SPT=34610 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 Dec 31 13:48:29 debian kernel: [29034.614317] [fw-inc-ssh] IN=eth0 OUT= MAC=52:54:00:26:97:1f:b8:27:eb:0e:4e:b6:08:00 SRC=192.168.1.252 DST=192.168.1.131 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=25292 DF PROTO=TCP SPT=55354 DPT=22 WINDOW=29200 RES=0x00 SYN URGP=0