Background.
I'm building a firewall/NAT device thats used in honeypot deployments.In simple terms, its configured to work as a reversed firewall of sorts. When one of the honeypots have been infected/compromised the firewall will allow the attacker to outbound connections, but the outbound connections are restricted to a specific set of ports, within certain limits and only a specific number of connections. If the firewall detects traffic that exceeds these limits it will start dropping packets for a certain period of time. Any traffic originating from the honeypots is logged since its considered malicious.
Problem.
The honeypots are often used by attackers to launch DDoS attacks. On average, 97% of this traffic is blocked by the firewall, its also logging all of this. The problem is that it will generate aropx. 90000 entries per second and these attacks can go on for anything from 10 min to several hours. As all of this is logged it generates some pretty large log files.
Current workaround.
I've attempted to work around this by rotating the firewall logs every 60 seconds, but this will only affect the log size. When logrotate have created the maximum number of logs ill just end up with loads of logs from one single DDoS attack. I added a dedicated hard drive to hold the log files and increased the log rotation.
Question.
I'm afraid this is a "keep the cake/eat the cake" situation. I want to log as much as possible, while telling iptables to stop logging traffic after a certain point.
Is there a way to configure iptables to write entries to the log file but, if the same entry has been written N times for the last second is will stop logging the rest?
Is there anything such as "rate limiting" for the logging function?
Is there any other way of solving this issue?
I think the limit
module is what you're looking for, as iptables-extensions
's man page suggests:
limit
This module matches at a limited rate using a token bucket filter. A rule using this extension will match until this limit is reached. It can be used in combination with the
LOG
target to give limited logging, for example.
xt_limit
has no negation support - you will have to use-m hashlimit ! --hashlimit rate
in this case whilst omitting--hashlimit-mode
.
--limit rate[/second|/minute|/hour|/day]
Maximum average matching rate: specified as a number, with an optional '/second', '/minute', '/hour', or '/day' suffix; the default is 3/hour.
--limit-burst number
Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number; the default is 5.
Therefore, and building upon this answer, I think that something of this sort would do the job:
iptables -N LOGANDDROP
iptables -A INPUT -s 192.168.1.0/24 -j LOGANDDROP
iptables -A LOGANDDROP -m limit --limit 5/min -j LOG --log-prefix "iptables dropped packets " --log-level 7
iptables -A LOGANDDROP -j DROP
You can achieve finer granularity by using several limit constraints at different rules.