我想跟踪在Linux桌面上启动出站连接的过程。我能想到的最好的办法是:
iptables -A OUTPUT -m state --state NEW -j LOG --log-uid
这将记录启动连接的uid / gid,但不会记录进程/命令名称甚至pid。如果我能得到pid,我可能会编写一个脚本,该脚本会在写入日志时提取进程名称,但是看来这甚至是不可能的。
理想情况下,我还要记录也接受传入连接的进程。
有什么想法在Linux机器上使用iptables [或其他工具]怎么可能?
我想跟踪在Linux桌面上启动出站连接的过程。我能想到的最好的办法是:
iptables -A OUTPUT -m state --state NEW -j LOG --log-uid
这将记录启动连接的uid / gid,但不会记录进程/命令名称甚至pid。如果我能得到pid,我可能会编写一个脚本,该脚本会在写入日志时提取进程名称,但是看来这甚至是不可能的。
理想情况下,我还要记录也接受传入连接的进程。
有什么想法在Linux机器上使用iptables [或其他工具]怎么可能?
Answers:
您可以编写一个程序来监视/ proc / net / tcp,其输出如下所示:
obi-wan ~ # cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 4847458 1 e6060560 300 0 0 2 -1
1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 4847477 1 f2e64da0 300 0 0 2 -1
2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 7109 1 f2e65ac0 300 0 0 2 -1
3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000 1000 0 4864457 1 d2726540 300 0 0 2 -1
4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 4847462 1 e60609c0 300 0 0 2 -1
5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000 0 0 4982752 3 f2e64940 55 4 0 2 -1
6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000 1000 0 2130283 1 d59cce40 21 4 1 2 -1
7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000 1000 0 2130285 1 d59cd2a0 21 4 0 2 -1
8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000 0 0 4982629 2 d2727260 40 4 8 2 2
9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000 0 0 4864416 5 e6061b40 42 12 27 3 -1
然后,您可以将打开的端口与inode关联,通过对每个进程列出的文件描述符进行readlink,可以将它们与进程和文件描述符相关联:
obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]
此处看到inode 4847458对应于上面列表中的第一个tcp套接字。netstat -tapn的输出为我验证了这一点(并记得0x50 == 80):
obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 28850/cherokee-work
当监视程序注意到/ proc / net / tcp中的更改时,请解析数据并确定更改是否是新打开的套接字。然后,您可以枚举/ proc中列出的每个进程的所有文件描述符,对每个进程进行readlink来找到匹配的inode。一旦找到,便拥有了自己的pid,您可以从中获得所需的其他任何信息,特别是如果您具有流程记帐的话。
如果您不需要即时通知,则您的监控程序可以使用慢速轮询(可能为50ms或100ms,甚至1000ms)。
您需要所有者匹配模块,该模块仅适用于OUTPUT链(甚至可能是PREROUTING ...?)。阅读文档,但它会像这样工作:
iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "
与iptables或日志记录无关;但是这是一个类似“ top”的界面,它轮询/ proc /目录并显示每个程序/ pid的带宽:
http://sourceforge.net/projects/nethogs
“ NetHogs是一个小的'net top'工具。它没有像大多数工具一样按协议或每个子网划分流量,而是按进程对带宽进行分组。NetHogs不依赖于加载特殊的内核模块。”
当我正在寻找一个类似的问题,试图限制Skype的速度时,我发现
$ netstat -p | grep <mycmdname>
这是将端口号链接到pid / cmd的好方法,因为iptables中不再直接支持pid-owner / cmd-owner;然后,您需要解析结果,然后根据端口添加iptables规则;自然地,之后/系统关闭/重新启动时,您将需要一些清除代码;在清理时将端口号保存到文件中以供参考
实际上,对端口号问题的一个很好的答案是
$ sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`
您可能需要根据需要调整grep tcp元素
那么出于我的目的,最简单的方法是根据端口号添加tc u32过滤器,根据端口号添加iptables条目