在macOS上使用DTrace获取TCP连接、端口IP等信息的方法咨询
当然可行!虽然macOS不像Solaris那样自带专门的TCP DTrace provider,但我们可以通过内核函数的静态探针(也就是fbt(Function Boundary Tracing)provider)来实现你要的监控需求,还能完整获取IP和端口信息。下面给你具体的实现方案:
在macOS上用DTrace监控TCP活动的方法
1. 监控TCP连接发起(connect)
这个脚本会跟踪所有主动发起的TCP连接,输出进程ID、进程名、源IP/端口、目的IP/端口:
#!/usr/sbin/dtrace -s fbt::tcp_usr_connect:return { self->fd = args[0]; self->so = (struct socket *)args[1]; self->inpcb = self->so->so_pcb; self->addr = (struct sockaddr_in *)self->inpcb->inp_laddr; self->dest_addr = (struct sockaddr_in *)self->inpcb->inp_faddr; printf("CONNECT: PID %d (%s) | Src: %s:%d | Dest: %s:%d\n", pid, execname, inet_ntoa(self->addr->sin_addr), ntohs(self->addr->sin_port), inet_ntoa(self->dest_addr->sin_addr), ntohs(self->dest_addr->sin_port)); self->fd = 0; self->so = 0; self->inpcb = 0; self->addr = 0; self->dest_addr = 0; }
使用方法:将代码保存为connect.d,然后执行sudo dtrace -s connect.d
2. 监控TCP连接接受(accept)
这个脚本跟踪服务器端接受的TCP连接,输出进程ID、进程名、服务器监听端口、客户端IP/端口:
#!/usr/sbin/dtrace -s fbt::tcp_usr_accept:return { self->so = (struct socket *)args[0]; self->inpcb = self->so->so_pcb; self->server_addr = (struct sockaddr_in *)self->inpcb->inp_laddr; self->client_addr = (struct sockaddr_in *)self->inpcb->inp_faddr; printf("ACCEPT: PID %d (%s) | Server Port: %d | Client: %s:%d\n", pid, execname, ntohs(self->server_addr->sin_port), inet_ntoa(self->client_addr->sin_addr), ntohs(self->client_addr->sin_port)); self->so = 0; self->inpcb = 0; self->server_addr = 0; self->client_addr = 0; }
使用方法:保存为accept.d,执行sudo dtrace -s accept.d
3. 监控TCP数据发送(send)
这个脚本跟踪TCP数据发送动作,输出进程ID、进程名、源/目的IP端口、发送的字节数:
#!/usr/sbin/dtrace -s fbt::tcp_send:entry { self->so = (struct socket *)args[0]; self->inpcb = self->so->so_pcb; self->src_addr = (struct sockaddr_in *)self->inpcb->inp_laddr; self->dest_addr = (struct sockaddr_in *)self->inpcb->inp_faddr; self->len = args[1]; printf("SEND: PID %d (%s) | Src: %s:%d | Dest: %s:%d | Bytes: %d\n", pid, execname, inet_ntoa(self->src_addr->sin_addr), ntohs(self->src_addr->sin_port), inet_ntoa(self->dest_addr->sin_addr), ntohs(self->dest_addr->sin_port), self->len); self->so = 0; self->inpcb = 0; self->src_addr = 0; self->dest_addr = 0; self->len = 0; }
使用方法:保存为send.d,执行sudo dtrace -s send.d
关键注意事项
- 所有DTrace脚本都需要root权限运行,所以记得加上
sudo前缀。 - 内核函数名可能随macOS版本变化(比如不同大版本的内核符号有差异),如果脚本不生效,可以用
dtrace -l -f tcp_*命令查看当前系统可用的TCP相关内核函数,再调整脚本中的函数名。 - 上述脚本仅针对IPv4,若需监控IPv6,需要将结构体改为
sockaddr_in6,并使用inet_ntop来格式化IPv6地址。
内容的提问来源于stack exchange,提问作者horseyguy
相关产品推荐
相关产品推荐

