我想在不干扰原始连接的情况下监视unix套接字上的响应,并将它们传送到脚本进行处理。
我知道如何使用 tcpdump 执行 tcp 连接,但我似乎找不到本地 unix 套接字的解决方案。
这可能吗?
答案1
有人声称可以通过创建一个应用程序来做到这一点,该应用程序充当两个套接字之间的网关并记录所有流动的数据。因此,您无法点击套接字,但如果您可以重新启动服务并对其进行调整以使用此应用程序,您将能够看到所有流量。
以下是该帖子的链接:Unix 套接字嗅探器
还有另一种方法需要您找到附加到套接字的进程 ID,然后使用 lsof 找到套接字的文件描述符,然后使用 strace 点击文件描述符。
如果您可以停止使用套接字的任何客户端/服务器并重新配置它,我会始终推荐第一种方法,第二种方法比较棘手并且需要您点击当前进程,这在某些应用程序上可能会导致它崩溃。
希望有人能用另一种方式启发我们:)
祝你好运
答案2
您可以使用socat。
sudo mv /path/to/sock /path/to/sock.original
sudo socat -t100 -x -v UNIX-LISTEN:/path/to/sock,mode=777,reuseaddr,fork UNIX-CONNECT:/path/to/sock.original
上面发生了什么:首先将原始套接字移动到 sock.original。Socat 在原始位置创建一个新的套接字(“UNIX-LISTEN”),并将所有内容转发到原始位置(“UNIX-connect”)。-v 告诉 socat 还将输出打印到 STDERR。
答案3
您也可以尝试在套接字两侧的某个进程上使用 strace,因为这可以让您查看写入/读取的内容。我发现在我的生产环境中,我没有 socat,但有 strace。
对于任何有用的目的来说,将 -s 设置为大值是必须的。
答案4
虽然有点晚了,但我修改了一个 systemtap 脚本,它可以为无法转发来自监听进程的套接字流量的人执行此操作。使用时请自担风险,我只针对 Red Hat Enterprise Linux 7 进行了测试,但我们引用的结构是通用的,并且(希望)不会发生太大变化:
/*
* watch_unix_socket.stp
*
* This is a simply more modern version of the script found here:
* https://sourceware.org/systemtap/wiki/WSunixSockets
*
* The first argument is the location of the file descriptor for a UNIX socket.
* To find this address, for example, for the Docker socket run:
*
* # lsof 2>&1 | awk '/docker.sock/ {print $7}' | grep -v '0t0' | sort -u
* 0xffff8ed0b4eb1800
*
* And use that address to run this systemtap script:
*
* # stap watch_unix_socket.stp 0xffff8ed0b4eb1800
*/
probe begin {
printf("Watching input into socket 0x%x...\n", $1);
}
probe kernel.function("unix_stream_sendmsg") {
if ($sock->sk != $1) {
printf("%d %s is accessing %p\n", pid(), execname(), $sock->sk);
printf("====================\n");
len = 0
for (i = 0; i < $msg->msg_iovlen; i++) {
len += $msg->msg_iov[i]->iov_len;
}
printf("%d [", len);
for (i = 0; i < $msg->msg_iovlen; i++) {
printf("%s", user_string_n($msg->msg_iov[i]->iov_base, $msg->msg_iov[i]->iov_len));
}
printf("] [");
for (i = 0; i < $msg->msg_iovlen; i++) {
printf("%s", user_string_n($msg->msg_iov[i]->iov_base, $msg->msg_iov[i]->iov_len));
}
printf("]\n\n");
}
}
我会持续更新我的页面上的 Github Gist。