Just a quick reminder for when you have to do some basic iptables’ logs parsing job.
Let’s say you have this kind of logs to parse :
Nov 24 08:43:35 xmpptest kernel: FW_INPUT_DROP: IN=eth0 OUT= MAC=6a:9d:bb:6a:2f:f4:00:0d:b9:28:1b:6e:08:00 SRC=10.100.3.57 DST=10.100.2.56 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=31678 DF PROTO=TCP SPT=21748 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0 Nov 24 08:43:35 xmpptest kernel: FW_INPUT_DROP: IN=eth0 OUT= MAC=6a:9d:bb:6a:2f:f4:00:0d:b9:28:1b:6e:08:00 SRC=10.100.3.57 DST=10.100.2.56 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=31688 DF PROTO=TCP SPT=21750 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0 Nov 24 08:43:38 xmpptest kernel: FW_INPUT_DROP: IN=eth0 OUT= MAC=6a:9d:bb:6a:2f:f4:00:0d:b9:28:1b:6e:08:00 SRC=10.100.3.57 DST=10.100.2.56 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=31723 DF PROTO=TCP SPT=21748 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0 Nov 24 08:43:38 xmpptest kernel: FW_INPUT_DROP: IN=eth0 OUT= MAC=6a:9d:bb:6a:2f:f4:00:0d:b9:28:1b:6e:08:00 SRC=10.100.3.57 DST=10.100.2.56 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=31726 DF PROTO=TCP SPT=21750 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0 Nov 24 08:43:38 xmpptest kernel: FW_INPUT_DROP: IN=eth0 OUT= MAC=6a:9d:bb:6a:2f:f4:00:0d:b9:28:1b:6e:08:00 SRC=10.100.3.98 DST=10.100.2.56 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=31726 DF PROTO=TCP SPT=21750 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0 Nov 24 08:43:38 xmpptest kernel: FW_INPUT_DROP: IN=eth0 OUT= MAC=6a:9d:bb:6a:2f:f4:00:0d:b9:28:1b:6e:08:00 SRC=10.100.3.201 DST=10.100.2.56 LEN=52 TOS=0x00 PREC=0x00 TTL=127 ID=31726 DF PROTO=TCP SPT=21750 DPT=80 WINDOW=8192 RES=0x00 SYN URGP=0
Here’s a python2 script that permits to count and sort denied source IP, so you can identify the source of an attack.
iptables_log_parser.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import re
import sys
from collections import Counter
DENY_PATTERN = re.compile('SRC=(\S*) .*DST=(\S*) .*PROTO=(\S*) .*DPT=(\S*)')
LINE_FORMAT=' {0:<12.12} {1:<12.12} {2:<6.6} {3:<6.6} {4}'
def process_log_file(logfile):
"""Reads through the log_file, and returns a counter based on Deny-lines."""
# Process file line by line
with open(logfile, 'r') as data:
seen = Counter()
# find all Deny line and append them in a list
for line in data :
# If line has 'Deny ' in it, then check it some more
if 'FW_INPUT_DROP' in line:
seen.update(DENY_PATTERN.findall(line))
return seen
def print_counter(counter):
"""Pretty print the result of the counter."""
print(LINE_FORMAT.format('source', 'destination', 'prot', 'port', 'hitcnt'))
print(LINE_FORMAT.format(*tuple(('------------------',) * 5)))
for (SRC, DST, PROTO, DPT), count in counter.most_common():
print(LINE_FORMAT.format(SRC, DST, PROTO, DPT, count))
if __name__ == '__main__':
# if file is specified on command line, parse, else ask for file
if sys.argv[1:]:
print "File: %s" % (sys.argv[1])
logfile = sys.argv[1]
else:
logfile = raw_input("Entrez le fichier de log a parser, e.g /var/log/secure: ")
denial_counter = process_log_file(logfile)
print_counter(denial_counter)
Output exemple for the given input above :
File: logfile2
source destination prot port hitcnt ------------ ------------ ------ ------ ------------------ 10.100.3.57 10.100.2.56 TCP 80 4 10.100.3.98 10.100.2.56 TCP 80 1 10.100.3.201 10.100.2.56 TCP 80 1
./Kriss
