Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Title says it all.

How can I, with iptables under Linux, log all IP connecting to a server? As a little detail, I'd like to have only ONE entry in the log PER DAY PER IP.

Thanks :)


I narrowed it down to 5 packets logged for every new session which is weird since I use --hashlimit 1 --haslimit-burst 1, I suspect that --m limit which defaults to 5 plays a role in there. Trouble is, if I set --m limit to 1, only 1 entry is logged for ALL IP instead one per EACH IP.

The reason I want to do this is also to avoid as much as possible logs growing too fast since this will be a rather unmanaged box.

EDIT2: Here is my current try, in a iptables-restore format: (on several lines for ease of reading)

-A FORWARD -d 10.x.x.x -p tcp --dport 443 -m state --state NEW 
-m hashlimit --hashlimit-upto 1/min --hashlimit-burst 1 
--hashlimit-mode srcip --hashlimit-name denied-client 
-j LOG --log-prefix "iptables (denied client): "
share|improve this question
What service? http, mysql, other? – Zoredache Mar 12 '10 at 22:13
https for example, although the part about service I can handle, it is the logging part that is giving me trouble ;) – Alexandre Nizoux Mar 12 '10 at 22:21
up vote 2 down vote accepted

I would try this:

# IP address entry older than one day
iptables -A ... -m recent --name mydaily ! --rcheck ! --seconds 86400 -j logandset
# IP address never seen before
iptables -A ... -m recent --name mydaily ! --rcheck -j logandset

# Custom chain for logging and refreshing
iptables -N logandset
iptables -A logandset -j LOG
iptables -A logandset -m recent --name mydaily --set

So your list mydaily will keep track of the last seen IP addresses, and if it was never seen before, or if the last seen is older than one day, the packet will be logged, and the list entry for that IP address be updated.

You should probably set ip_list_tot to a higher value for mydaily, as explained in the iptables manpage (In your case for /proc/net/xt_recent/mydaily).

share|improve this answer
Both lines have to be "! --rcheck" to work but that's it! Thanks a bunch! Good bounty hunt ;) – Alexandre Nizoux Mar 22 '10 at 9:09
Thanks! I corrected it to ! --rcheck. – Chris Lercher Mar 22 '10 at 10:33
Actually works with just the first line: "! --rcheck --seconds 86400 -j logandset" – Alexandre Nizoux Mar 22 '10 at 11:58
(And you forgot to remove the second ! from the first line) – Alexandre Nizoux Mar 22 '10 at 11:59
Are you sure? My current version seems to work for me (maybe I haven't tested it enough). I'll give it a spin on my server - because logging IPs just once per day is a good idea anyway! Then I'll edit my answer. Hm, maybe both versions work? Iptables' recent module has a bit of a strange syntax IMO: Actually it should check, that that the address is in the list (--rcheck), but that its timestamp is older than 86400 (! --seconds). But maybe the arguments must be read as a bracket term. – Chris Lercher Mar 22 '10 at 13:22

I'm taking a wild (untested) crack @ this, but something like:

iptables -I INPUT -m conntrack --ctstate NEW -j LOG --log-prefix 'IPT/New Connection' 

iptables will emit a message to the kernel log for every new connection. You will then need to do something like

grep 'IPT/New Connection' /var/log/kern.log | | wc -l

Which will give you a count. Various dances w/ awk/perl/etc will let you split it up by IP.

I don't see a way to convince IPtables to spit out just one count per IP address at the end of the day. If your syslog is capable of filteirng messages by regexp, you can capture the messages and funnel them into a seperate log file. @ the end of the day, all the counts are computed, and the message is reinserted into your main syslog entry.

share|improve this answer
prefixing and extracting are not the main focus here, but the one entry/day/ip is. Let me show you what I got so far. – Alexandre Nizoux Mar 13 '10 at 8:42

Would it be much simpler to just log everything and then post process it to extract what you need? Use what's appropriate at each stage rather than try to shoehorn something to fit where it doesn't belong.

share|improve this answer
That's usually what I try to do but I am asked to keep this log to bare minimum, so I figured I'd ask just in case someone has a better iptables logging knowledge than I do. I will post my lines soon. – Alexandre Nizoux Mar 13 '10 at 8:42

I'd use a patched version of ulogd with an SQL backend.

The trick would be to patch the INSERT SQL query in a way that would let the database deal with redundancy in IP addresses and insert new records into the logs only for unique IPs.

share|improve this answer
I'd rather stay on a plain text version than have to install a db server just for that. On a system where SQL is already installed, sure is a good way. – Alexandre Nizoux Mar 16 '10 at 16:28
You could use sqlite, which is trivial to install, requires 0 configuration and is supported by ulogd as backend. It can also store its databases in RAM, so this might suit you as well, especially on servers with big uptime. – Anonymous Mar 17 '10 at 15:03

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.