Python Socket获取远程服务器UDP端口状态与Nmap结果不符问题
问题描述
以root权限运行以下Python代码检测远程服务器10.146.25.44的UDP 152端口:
#!/usr/bin/python #(以root权限运行) from socket import * udp_scan=socket(AF_INET,SOCK_DGRAM) udp_scan.connect_ex(('10.146.25.44',152))
代码返回0(显示端口开放),但执行Nmap扫描命令:
[user@testserver~]$ sudo nmap -v -Pn -sU -p 152 10.146.25.44
得到的扫描结果显示该端口为closed状态:
Starting Nmap 5.51 ( http://nmap.org ) at 2022-09-12 16:32 GMT Initiating UDP Scan at 16:32 Scanning remoteserver.example.com (10.146.25.44) [1 port] Completed UDP Scan at 16:32, 0.05s elapsed (1 total ports) Nmap scan report for remoteserver.example.com (10.146.25.44) Host is up (0.029s latency). PORT STATE SERVICE 152/udp closed bftp
无远程服务器访问权限,疑惑为何Socket模块返回与实际不符的结果。
原因分析
UDP是无连接协议,Python的connect_ex()方法对UDP的处理和Nmap的UDP扫描逻辑完全不同:
- Python的
connect_ex():对于UDP套接字,调用connect_ex()只是在本地套接字上记录目标IP和端口,并不会发送任何数据包到远程服务器。只要本地系统能完成这个绑定操作(没有本地端口冲突等问题),就会返回0,这个返回值完全不代表远程端口是开放的。 - Nmap的UDP扫描:Nmap会向目标UDP端口发送探测数据包,然后等待响应。如果收到ICMP端口不可达的报文,就判定端口为
closed;如果没有收到响应(可能是端口开放但无返回,或者数据包被防火墙丢弃),会标记为open|filtered;只有收到对应服务的响应报文,才会明确标记为open。
这种差异本质是两种工具的检测机制不同,Python的connect_ex()根本没有实际探测远程端口状态,所以会给出和Nmap不一致的结果。
内容的提问来源于stack exchange,提问作者mallikarjun mudumali
相关产品推荐
相关产品推荐

