在没有 tcpdump 的情况下转储 tcp 连接

Isa*_*aac 17 linux tcp

在 centos 机器上,我喜欢转储 tcp 连接 - 我想看看服务器是否尝试向某个 IP 发送请求。通常 tcpdump 可以解决问题 - 但 tcpdump 没有安装,并且安装软件不是一个选项(因为公司政策)。恐怕 netstat 不会向我显示一个请求。

所以我想知道我还有什么其他选择。我确实在服务器上有 root 访问权限。

Kyl*_*ndt 17

我真的会尝试获取 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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

网络状态:

[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
Run Code Online (Sandbox Code Playgroud)


Mat*_*Ife 17

你肯定有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, 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)
Run Code Online (Sandbox Code Playgroud)

这将退出“GOT TARGET”,提供返回匹配的 IP 地址。由于 TCP 必须在握手期间发回一些内容,因此这应该从特定目标地址捕获任何内容。不过,它并不关心协议是 TCP 还是 UDP(我也不检查)。

不要忘记更改 TARGET 和 INTERFACE。

  • 这个脚本不是新软件(所以不是要安装在系统中)? (3认同)
  • 非常酷,但您仍然需要为此提升权限。我得到了 `socket.error: (1, 'Operation not allowed')` (2认同)

小智 15

iptables 具有调试功能,也可用于流量分析。

下面的 URL 中描述了解决方案。

Iptables 中的调试规则

还值得阅读以下 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)
Run Code Online (Sandbox Code Playgroud)


eww*_*ite 8

如果您需要特定的软件来完成您的工作,但不允许这样做,那么您要么没有制定好的商业案例,要么没有将您的想法出售给合适的人……或者您无法控制这个系统。 .

如果我的任务是做某事并且需要您在这种情况下需要的调试/故障排除信息类型,我会使用正确的工具。那很可能tcpdumptshark。是的,这些都是软件,但我认为它们是更重要的实用程序。事实上,它们是可以临时安装或加载到系统上的实用程序,并且可以毫无意外地删除(可移动媒体是一种选择吗?...提示

但关键是,公司政策的一个笨拙的解决方法可能比获得此用例的批准需要更多的努力。

  • @ewwhite:任何好的变更管理政策都应该能够免除特定或类别的变更,使其免于经历整个过程。如果这个没有.... (3认同)
  • 你不能在别处编译一个静态链接的 `tcpdump`,然后将它复制到 /tmp 并从那里运行吗? (2认同)

Jam*_*ger 5

凯尔提供了一些不错的选择。还有一种方法是使用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
Run Code Online (Sandbox Code Playgroud)

这本质上是一个会计规则。它没有明确允许或拒绝流量,因此使用 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 ...
Run Code Online (Sandbox Code Playgroud)

日志将进入内核日志记录工具,因此它应该显示在 Red Hat 衍生产品的 /var/log/messages 和 Debian 衍生产品的 /var/log/kern.log 中。它也将在 的输出中可见dmesg,如图所示。tcpdump然而,与 不同的是,它不会记录数据包的完整内容,只会记录数据包头的内容。