标题说明了一切。
如何使用 Linux 下的 iptables 记录连接到服务器的所有 IP?详细来说,我希望日志中每个 IP 每天只有一个条目。
谢谢 :)
编辑:
我把记录数据包数缩小到每会话记录 5 个数据包,这很奇怪,因为我使用--hashlimit 1 --haslimit-burst 1,我怀疑 --m limit 默认为 5 在其中发挥了作用。问题是,如果我将 --m limit 设置为 1,则只会为所有 IP 记录 1 个条目,而不是每个 IP 记录一个条目。
我想要这样做的原因也是为了尽可能避免日志增长过快,因为这将是一个相当不受管理的盒子。
编辑2: 这是我目前的尝试,采用 iptables-restore 格式:(为了便于阅读,分为几行)
-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): "
答案1
我会尝试这个:
# 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
因此,您的列表mydaily
将跟踪最后看到的 IP 地址,如果之前从未见过,或者最后看到的 IP 地址已超过一天,则将记录该数据包,并更新该 IP 地址的列表条目。
您可能应该将其设置ip_list_tot
为更高的值mydaily
,如 iptables 手册页中所述(在您的情况下为 /proc/net/xt_recent/mydaily)。
答案2
我对此进行了一次疯狂的(未经测试的)破解,但结果是:
iptables -I INPUT -m conntrack --ctstate NEW -j LOG --log-prefix 'IPT/New Connection'
iptables 会针对每个新连接向内核日志发送一条消息。然后你需要执行如下操作
grep 'IPT/New Connection' /var/log/kern.log | | wc -l
这将为您提供计数。使用 awk/perl/等进行各种操作将允许您按 IP 进行拆分。
我没有找到任何方法可以让 IPtables 在一天结束时只对每个 IP 地址输出一个计数。如果您的系统日志能够通过正则表达式过滤消息,您可以捕获这些消息并将它们汇集到一个单独的日志文件中。在一天结束时,将计算所有计数,并将消息重新插入到您的主系统日志条目中。
答案3
记录所有内容,然后对其进行后期处理以提取所需内容,这样会更简单吗?在每个阶段使用合适的内容,而不是尝试将某些内容强行塞入不属于它的地方。
答案4
我会使用修补版本ulogd使用 SQL 后端。
诀窍是修补插入SQL 查询的方式可以让数据库处理 IP 地址的冗余,并且只为唯一的 IP 将新记录插入到日志中。