如何用Python在远程服务器后台运行tcpdump并正常抓包?
解决Python SSH执行tcpdump时卡住或生成空pcap文件的问题
问题原因
- 直接执行卡住:
exec_command默认会等待远程命令执行完毕才返回,但tcpdump是持续运行的抓包工具,不会主动退出,导致Python脚本一直阻塞等待。 - 后台执行生成空文件:用
&将tcpdump放到后台后,exec_command会立即返回并关闭SSH会话,此时远程的tcpdump进程会收到SIGHUP信号被终止,仅能生成初始化的空pcap文件(1KB左右),还没来得及捕获数据包。
解决方案
方案1:用nohup让tcpdump脱离SSH会话持续抓包
通过nohup命令忽略SIGHUP信号,让tcpdump在后台独立运行,即使SSH会话关闭也能继续抓包:
ssh_client.connect(host, username=username, password=password) # 执行nohup后台命令,并重定向输出避免阻塞 command = "nohup tcpdump -i any -w test.pcap > /dev/null 2>&1 &" stdin, stdout, stderr = ssh_client.exec_command(command) # 读取输出缓冲区,防止后续操作阻塞 stdout.read() stderr.read() ssh_client.close()
注:
> /dev/null 2>&1是将标准输出和错误输出重定向到空设备,避免生成nohup.out文件,也可根据需求保留。
方案2:指定抓包时长自动退出
如果不需要持续抓包,可通过tcpdump的-G(指定抓包时长,单位秒)和-W(指定生成文件数)参数让命令自动退出,这样exec_command会等待命令完成后返回,不会卡住脚本:
ssh_client.connect(host, username=username, password=password) # 抓包60秒后自动退出,生成1个pcap文件 command = "tcpdump -i any -w test.pcap -G 60 -W 1" stdin, stdout, stderr = ssh_client.exec_command(command) # 设置超时时间,确保不会无限等待(可选) stdout.channel.set_timeout(70) try: stdout.read() except Exception: pass ssh_client.close()
方案3:使用screen/tmux(需服务器预装)
如果服务器安装了screen或tmux,也可以用它们创建后台会话运行tcpdump,不过通用性不如nohup:
ssh_client.connect(host, username=username, password=password) # 用screen创建后台会话运行tcpdump command = "screen -dmS tcpdump_session tcpdump -i any -w test.pcap" stdin, stdout, stderr = ssh_client.exec_command(command) stdout.read() stderr.read() ssh_client.close()
验证方法
执行完脚本后,可通过SSH登录服务器,用ps aux | grep tcpdump查看进程是否在运行,或直接查看test.pcap文件大小判断是否捕获到数据包。
内容的提问来源于stack exchange,提问作者Milan Paliwal
相关产品推荐
相关产品推荐

