http://farm4.static.flickr.com/3305/4588110530_a60c934289_o.png
该图表是 munin 收集netstat -s
输出的。
我想确定连接来自哪里。wireshark 转储中没有明显的信息。
我已经很久没有用 iptables 做过什么了。我该如何记录这些内容?
谢谢
-s
答案1
要确定连接来自哪里....以下是记录 SSH 流量的示例。格式在内核日志中如下所示
MONTH DAY TIME SERVERNAME kernel: [IPTABLES] : IN=eth0 OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:00:00 SRC=REMOTEIP DST=SERVERIP LEN=00 TOS=0x00 PREC=0x00 TTL=# ID=# DF PROTO=TCP SPT=# DPT=22 WINDOW=# RES=0x00 SYN URGP=0 OPT (#)
这里我们创建一个名为MyLOG的新链
# iptables -N MyLOG
冲洗新链条以防万一
# iptables -F MyLOG
在 tcp 端口 22 上创建日志功能,将日志设置为警报,并将易于查看的“[IPTABLES]”字符串设置为日志行的开头。
# iptables -A MyLOG -i eth0 -p tcp --dport 22 -j LOG --log-level alert --log-tcp-options --log-ip-options --log-prefix '[IPTABLES] : '
将 MyLOG 链附加到输入链
# iptables -A INPUT -i eth0 -j MyLOG
这应该会将日志发送到您的内核日志(尽管某些版本的 Linux 可能会改变结果)。您可以通过跟踪内核日志来测试日志记录。
# tail -f /var/log/kern.log
如果你在控制台上,注意到屏幕上有大量数据,你可以尝试使用以下命令设置控制台日志输出
dmesg -n 1
如果你想获得“统计数据”,你可以运行
# iptables -nvxL
输出将显示从链创建时发送的数据包和字节的数量。
Chain MyLOG (1 references)
pkts bytes target prot opt in out source destination
61 4416 LOG tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0
我这里有一个脚本http://www.hilands.com/code-shell-fw.html我用它来记录某些端口活动,并收集 serverstats serverstats 的数据(可从 berlios 下载),设置 NAT,端口转发,尝试中断端口扫描,并使用 tcp-rejects 而不是 drop。
Serverstats 可能很难理解。它是一组使用 RRDTool 的 PHP 脚本。它使用 shell 脚本来触发 iptables 输出。我的乱码笔记告诉我,您需要使用类似这样的内容修改配置数组才能使其运行
'ssh-traffic' => array(
'used' => true,
'chains' => array('MyLOG'),
'graphs' => array(
'combined_bps' => array('used' => true, 'title' => 'Combined (bps)'),
'single_bps' => array('used' => true, 'title' => '%s (bps)'),
'combined_count' => array('used' => true, 'title' => 'Combined (count)'),
'single_count' => array('used' => true, 'title' => '%s (count)')
)
),
答案2
谢谢大家的回复。
我的目标是了解图表中的峰值为何有规律且周期性,然后让它们停止。这些峰值以缓慢的涓流(每次 5 个左右)涌入。我知道 TCP 连接会因某种原因而失败,但显然由于它们的规律性而发生了一些事情。我怀疑某个地方的 cron 作业、负载平衡器配置错误或监控设备是罪魁祸首。
我决定采用 UTSL 方法,目前情况如下:
netstat -s 从 /proc/net/snmp 获取其统计数据。
太好了。因此,每次连接尝试失败时,内核都会更新 SNMP 计数器。
我想要实现的是,每次连接失败时,不仅更新此计数器,还记录“在 $timestamp 时来自 IP $foo 的连接尝试失败”
那么...什么样的情况才算是连接尝试失败?
下载内核源代码 查找周围 得出的结论是,我正在寻找的计数器是 TCP_MIB_ATTEMPTFAILS
通过 2.6.18 源代码树,我发现了两个引用此内容的地方:
./net/ipv4/tcp_minisocks.c:
453 struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
454 struct request_sock *req,
455 struct request_sock **prev)
456 {
592 if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) {
593 TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
594 goto embryonic_reset;
595 }
640 }
...并且,include/net/tcp.h
915 static inline void tcp_done(struct sock *sk)
916 {
917 if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
918 TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
919
920 tcp_set_state(sk, TCP_CLOSE);
921 tcp_clear_xmit_timers(sk);
922
923 sk->sk_shutdown = SHUTDOWN_MASK;
924
925 if (!sock_flag(sk, SOCK_DEAD))
926 sk->sk_state_change(sk);
927 else
928 inet_csk_destroy_sock(sk);
929 }
我有点惊讶,这只是两个产生计数器更新的条件,但无论如何。
第一个块看起来很明显。“如果您看到 TCP 数据包同时设置了 RST 和 SYN 标志,请更新 TCP_MIB_ATTEMPTFAILS 计数器并重置连接”。
为了捕获这些,我添加了以下 iptables 规则
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j LOG
iptables -A OUTPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j LOG
等待…..没什么。=(
第二个块有点神秘,但我猜测并假设这意味着“如果套接字在拆除时处于某种状态,则更新 TCP_MIB_ATTEMPTFAILS 计数器”
这个,我不知道如何测试这个。
我现在的问题是:1) 我是否误解了这张图?2) 我走在正确的轨道上吗?3) 除了编写内核模块(我远没有足够的技能来做这件事)之外,我怎样才能实现我的日志记录目标?
谢谢
-s
答案3
我不确定 iptables 是否是您想要的,可能有一个保持活动状态并轮询 netstat 使用的相同系统调用的工具,或者您可以编写一个。
iptables 对数据包做出反应并处理它们。您所看到的基本上是所有活动套接字的分配表。
现在,根据这些实际情况,您可能能够在这些连接上捕获数据包。
如果有很多套接字处于不太明显的状态,并且持续很长时间,数字不断增长,我会更关注 netstat -anp 的输出,如果我没记错的话,它会告诉您程序。也许有人在泄漏套接字。
我对此抱有很大的怀疑。请详细说明一下您希望在该图表中看到哪些变化。
我自己评论了,但没有显示出来,所以我就编辑一下——另一篇文章绝对清楚地说明了如何使用 iptables 记录您应该能够使用 wireshark 看到的流量。在我看来,你问的是套接字,而不是数据包。难以追踪的套接字通常不会获取/发送数据包,有时这表明资源浪费。