Logging port access with iptables and logwatch

I’ve recently installed a program (let’s call it Foo) on my home server that requires one port (let’s call that 12345) to be forwarded from the public interface on my ADSL modem to my internal server (via NAT translation). I’m always a bit hesistant to do this kind of action so why not ease my fears and log who’s accessing this port?

This idea requires two steps:

  1. Configuring iptables to log ‘socket open’ actions
  2. Making sure my daily ‘logwatch’ run does a DNS lookup on the found addresses

Step 1 - iptables configuration

Setting iptables up to log socket access is actually quite straightforward:

#log incoming Foo connections
iptables -I INPUT -p tcp --dport 12345 -m state --state NEW -j LOG --log-prefix "Foo inbound: "

This line logs any new TCP connection to port 12345 to the kernel log and /var/log/messages.

Execute the above command in a terminal (as root) and check that the rule is working with ‘nc’:

benjamin@nas:~$ nc localhost 12345
<some garbage indicating that socket was opened>
^C
benjamin@nas:~$ dmesg -T|grep "Foo inbound"|tail -n 1
[Thu Oct 22 08:30:03 2015] Foo inbound: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=23309 DF PROTO=TCP SPT=37456 DPT=12345 WINDOW=43690 RES=0x00 SYN URGP=0

This message indicates that the iptables rule is working! Once you’re satisfied, you can persist this rule by adding it to your ‘/etc/rc.local’ file. There are probably nicer ways to do that but this works fine :)

Step 2 - logwatch configuration

Logwatch is an excellent tool to get a daily report about your server status. Imagine my surprise that the iptable rule automatically was processed into a neat report:

--------------------- iptables firewall Begin ------------------------

Listed by source hosts:
Logged 4 packets on interface br0
  From 1.2.3.4 - 2 packets to tcp(12345)
  From 5.6.7.8 - 2 packets to tcp(12345)

---------------------- iptables firewall End -------------------------

However, wouldn’t it be nice to see actual DNS hostnames (if available) for those addresses? After a lot of troubleshooting I found out that the ‘iptables’ service of logwatch doesn’t do lookups by default (probably for performance reasons).

Following the steps on this page you can fix that, in short it comes down to this:

# Copy default iptables module config to proper /etc directory
sudo cp /usr/share/logwatch/default.conf/services/iptables.conf /etc/logwatch/conf/services/

Now edit ‘/etc/logwatch/conf/services/iptables.conf’, search for ‘iptables_ip_lookup’ and make sure it looks like this:

# Set this to yes to lookup IPs in kernel firewall report
$iptables_ip_lookup = Yes

Now re-run logwatch manually and verify the results:

benjamin@nas:~$ sudo /usr/sbin/logwatch --hostformat split
<cut out a lot of stuff for this example>

 --------------------- iptables firewall Begin ------------------------

 Listed by source hosts:
 Logged 4 packets on interface br0
   From 1.2.3.4 (bla.blah.com) - 2 packets to tcp(12345)
   From 5.6.7.8 (some.otherdomain.com) - 2 packets to tcp(12345)

 ---------------------- iptables firewall End -------------------------

Mission accomplished, happy hunting :)