Whilst troubleshooting some firewall issues with a CentOS host, I wanted to enable logging. Thankfully, there is a very customisable iptables target - LOG (funnily enough) - that will do this in a few steps.
First, add a new chain with a reasonable name. I chose LOGGING:
|
1 |
# iptables -N LOGGING |
Next, review the current iptables configuration to ensure that the chain has been created successfully:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# iptables -L -n --line-numbers Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 ACCEPT udp -- 192.168.122.0/24 0.0.0.0/0 state NEW udp dpt:53 6 ACCEPT tcp -- 192.168.122.0/24 0.0.0.0/0 state NEW tcp dpt:53 7 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination Chain LOGGING (0 references) num target prot opt source destination |
Next, insert a rule at the appropriate point (hence me using --line-numbers above). You could replace the existing REJECT at line 7 in its entirety as its functionality will be moved into the LOGGING chain (where I change it to a DROP anyway):
|
1 |
# iptables -I INPUT 7 -j LOGGING |
Add the actual logging rule next. I also use the limit module to add some rate-limiting into the mix. The iptables man page documents both the LOG target and the limit module in great detail. But - here I specify a limit of 10 messages per minute, which is ample for my testing. The log level is set at debug (as per standard syslog log levels).
|
1 |
# iptables -A LOGGING -m limit --limit 10/min -j LOG --log-prefix "DROP: " --log-level 7 |
Finally, we actually DROP the packet (whether it has been logged, or not (if the rate limit has been exceeded)):
|
1 |
# iptables -A LOGGING -j DROP |
OK - let’s check our iptables configuration once again:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# iptables -L -n Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 ACCEPT udp -- 192.168.122.0/24 0.0.0.0/0 state NEW udp dpt:53 ACCEPT tcp -- 192.168.122.0/24 0.0.0.0/0 state NEW tcp dpt:53 LOGGING all -- 0.0.0.0/0 0.0.0.0/0 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain LOGGING (1 references) target prot opt source destination LOG all -- 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 5 LOG flags 0 level 7 prefix `DROP: ' DROP all -- 0.0.0.0/0 0.0.0.0/0 |
Everything looks good. Try telnetting to a bad port, or doing something else the firewall should block, and depending upon your syslog configuration, the DROP message should be logged, for example:
|
1 |
May 20 21:40:42 somehost kernel: DROP: IN=eth0 OUT= MAC=DE:AD:BE:EF:8d:b2:52:54:00:ff:d4:30:08:00 SRC=192.168.122.1 DST=192.168.122.10 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=19162 DF PROTO=TCP SPT=38141 DPT=54 WINDOW=14600 RES=0x00 SYN URGP=0 |
If nothing is broken, save your configuration:
|
1 |
# service iptables save |
As an aside, if (as with the default rsyslog configuration under CentOS 6.x) nothing is logged, you will need to configure rsyslog appropriately. We specified a --log-level of 7 - which is the debug syslog log level. So we need to configure rsyslog to send messages from the kern facility at log level 7 to somewhere useful. I chose /var/log/firewall.log:
|
1 2 3 4 5 |
# vi /etc/rsyslog.conf ... kern.debug /var/log/firewall.log ... # service rsyslog restart |
As a final tidy up, don’t forget to update your logrotate configuration, if required:
|
1 2 3 |
# cd /etc/logrotate.d # vi syslog add /var/log/firewall.log to list of filenames |