Nmap NSE检测关闭端口的脚本未触发预期输出问题求助
问题根源分析
你遇到的核心问题是Nmap默认不会对closed状态的端口执行脚本。Nmap的脚本引擎(NSE)出于效率考虑,默认只针对open、open|filtered这类被判定为“有扫描价值”的端口触发脚本逻辑,closed端口会被直接跳过——哪怕你的portrule写了匹配closed状态,脚本也根本没机会执行。
另外你的脚本里还有几个隐性语法问题:用了中文引号(“Peter”)和HTML转义的引号("),虽然Nmap可能勉强解析,但规范的英文双引号能避免潜在的解析报错。
解决方案
1. 修正脚本语法
把脚本里的中文引号和转义引号替换为英文双引号,修正后的完整脚本如下:
-- HEAD -- description = [[ This is a simple script example that determines if a port is closed. ]] author = "Peter" -- RULE -- portrule = function(host, port) return port.protocol == "tcp" and port.state == "closed" end -- ACTION -- action = function(host, port) return "This port is closed!" end
2. 添加强制扫描所有端口的脚本参数
执行Nmap时,必须加上--script-args nmap.script_scan_all_ports=1参数,这个参数会强制Nmap对所有你指定的端口(无论状态如何)都运行脚本。
正确的执行命令
nmap -p80,443 --script testy2closed.nse --script-args nmap.script_scan_all_ports=1 127.0.0.1
预期输出效果
执行后就能看到你想要的结果:
Starting Nmap 7.97 ( https://nmap.org ) at 2025-08-25 18:55 +0200
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00012s latency).PORT STATE SERVICE
80/tcp closed http
|_testy2closed: This port is closed!
443/tcp closed https
|_testy2closed: This port is closed!Nmap done: 1 IP address (1 host up) scanned in 0.12 seconds
补充说明
如果你的需求是扫描全端口的closed状态,可以结合-p-参数扫描所有65535端口,但务必保留--script-args nmap.script_scan_all_ports=1,否则脚本依然不会触发。
内容来源于stack exchange

