![不使用 tcpdump 转储 tcp 连接](https://linux22.com/image/635420/%E4%B8%8D%E4%BD%BF%E7%94%A8%20tcpdump%20%E8%BD%AC%E5%82%A8%20tcp%20%E8%BF%9E%E6%8E%A5.png)
在 centos 机器上,我喜欢转储 tcp 连接 - 我想查看服务器是否尝试向某个 IP 发送请求。通常 tcpdump 就可以解决问题 - 但是没有安装 tcpdump,并且无法安装软件(因为公司政策)。我担心 netstat 不会向我显示任何请求。
所以我想知道我还有什么其他选择。我确实拥有服务器上的 root 访问权限。
答案1
你肯定有python
吧?
from socket import *
from struct import unpack
import sys
INTERFACE = "eth0"
TARGET = "8.8.8.8"
if __name__ == "__main__":
sock = socket(AF_PACKET, SOCK_DGRAM, htons(0x0800))
sock.bind((INTERFACE, 0x0800))
while True:
data = sock.recvfrom(1500, 0)[0]
ip = inet_ntop(AF_INET, data[12:16])
if ip == TARGET:
print("GOT TARGET")
sys.exit(1)
如果返回的 IP 地址匹配,则此操作将以“GOT TARGET”退出。由于 TCP 必须在握手期间发送一些内容,因此这应该会捕获来自特定目标地址的任何内容。但它并不关心协议是 TCP 还是 UDP(我也没有检查)。
不要忘记改变TARGET和INTERFACE。
答案2
我真的想尝试使用 tcpdump。话虽如此,查看某个 IP 是否存在某个连接的一些替代方法是:
跟踪:
[kbrandt@ny-kbrandt01: ~] strace -e trace=network nc 1.2.3.4 1234
...
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(1234), sin_addr=inet_addr("1.2.3.4")}, 16) = -1 EINPROGRESS (Operation now in progress)
lsof:
[kbrandt@ny-kbrandt01: ~] nc 1.2.3.4 1234 &
[1] 11434
[kbrandt@ny-kbrandt01: ~] lsof -p 11434
....
nc 11434 kbrandt 3u IPv4 4543149 0t0 TCP 10.7.0.78:58886->1.2.3.4:search-agent (SYN_SENT)
网络状态:
[kbrandt@ny-kbrandt01: ~] nc 1.2.3.4 1234 &
[1] 11486
[kbrandt@ny-kbrandt01: ~] sudo netstat -a -p | grep 11486
tcp 0 1 10.7.0.78:58891 1.2.3.4:search-agent SYN_SENT 11486/nc
答案3
Iptables 具有调试功能,也可以用于流量分析。
解决方案在下面的 URL 中描述。
还值得阅读以下 URL,以设置将跟踪输出记录到您选择的文件中。
http://backreference.org/2010/06/11/iptables-debugging/
我不认为这个解决方案等同于 tcpdump,但它可以使用最小安装的 Centos 来实现。您需要小心不要用日志填满磁盘,因为 tcpdump 在磁盘使用方面效率更高。在不需要时关闭日志记录。
您可以在脚本中使用以下内容作为基本模板。
# Logging
log(){
SOURCE=a.b.c.d (IP address)
$IPT -A INPUT -s $SOURCE -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "In: "
$IPT -A OUTPUT -s $SOURCE -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "Out: "
$IPT -A FORWARD -s $SOURCE -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "Fw: "
$IPT -t nat -A POSTROUTING -m limit --limit 50/minute -j LOG --log-level 7 --log-prefix "Nat: "
}
#log (remove comment to enable)
trace(){
iptables -t raw -A PREROUTING -p tcp -j TRACE
iptables -t raw -A OUTPUT -p tcp -j TRACE
}
#trace (remove comment to enable)
答案4
Kyle 提供了一些不错的选择。还有一个是使用iptables
:
[james@server ~]$ sudo iptables -I OUTPUT -d 1.2.3.4/32
...
[james@server ~]$ sudo iptables -L OUTPUT -n -v
Chain OUTPUT (policy ACCEPT 105 packets, 35602 bytes)
pkts bytes target prot opt in out source destination
87 33484 LOG all -- * * 0.0.0.0/0 1.2.3.4 LOG flags 0 level 4
这本质上是一个会计规则。它没有明确允许或拒绝流量,因此使用 OUTPUT 链的默认策略(默认为 ACCEPT)。但是,任何匹配的数据包都会增加规则的计数器。
您也可以选择使用以下命令记录有关数据包的详细信息-j LOG
:
[james@server ~]$ sudo iptables -I OUTPUT -d 1.2.3.4/32 -j LOG
...
[james@server ~]@ dmesg | grep 1.2.3.4 | tail -1
IN= OUT=eth0 SRC=192.168.1.1 DST=1.2.3.4 LEN=100 TOS=0x10 PREC=0x00 TTL=64 ...
日志将进入内核日志记录工具,因此它应该出现在 Red Hat 衍生版的 /var/log/messages 中,以及 Debian 衍生版的 /var/log/kern.log 中。它也将在 的输出中可见dmesg
,如图所示。tcpdump
然而,与 不同,它不会记录数据包的完整内容,而只会记录数据包头的内容。