记录每次连接尝试的 PID

记录每次连接尝试的 PID

netstat使用或查找已建立连接的 PID 很简单lsof。但是,我有一个进程每 60 秒创建一个到数据库的连接,并通过最大失败连接尝试限制来锁定它。我可以将数据库上的失败连接限制增加到极高,或者我可以尝试追踪是什么建立了连接,我选择了后者。

基于 tcpdump/wireshark,我可以看到发生的情况是建立了连接,然后连接服务器在服务器响应之前立即关闭连接。我不知道的是为什么。

第一步是找出打开连接的 PID。不幸的是,这似乎说起来容易做起来难。问题是当连接进入 TIME_WAIT 状态时,它不再与 PID 关联。由于我的连接寿命不到十分之一秒,有什么方法可以记录这些信息吗?

netstat并且lsof似乎能够每秒轮询,但这对于我正在处理的连接尝试来说根本不够快。是否有一个钩子可以连接到将此信息转储到日志中?或者是我通过循环和一些编码来暴力破解它的唯一选择?

我用的是CentOS 6。

答案1

考虑使用系统点击。它是动态检测引擎,可以动态修补内核,因此您可以跟踪任何内核内事件,例如打开套接字。它是由 RedHat 积极开发的,因此在 CentOS 中得到支持。

安装中

要在 CentOS 6 上安装 SystemTap:

  1. 启用调试信息存储库:

    sed -i 's/^enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Debuginfo.repo
    
  2. 安装系统Tap:

    yum install systemtap
    
  3. 安装内核的 debuginfo 包。它可以手动完成,但有一个工具可以自动完成:

    stap-prep
    

追踪

SystemTap 没有 TCP 连接的 Tapset 探针,但您可以直接绑定到内核函数!您也可以在套接字级别执行此操作。

即创建名为conn.stp

probe kernel.function("tcp_v4_connect") {
    printf("connect [%s:%d] -> %s:%d\n", execname(), pid(),
            ip_ntop(@cast($uaddr, "struct sockaddr_in")->sin_addr->s_addr),
            ntohs(@cast($uaddr, "struct sockaddr_in")->sin_port));
}

这将为您提供以下输出:

# stap conn.stp
connect [nc:2552] -> 192.168.24.18:50000
connect [nc:2554] -> 192.168.24.18:50000
connect [nc:2556] -> 192.168.24.18:50000

然而,跟踪断开连接事件似乎更加棘手。

相关内容