SpringBoot + nmap4j 获取端口信息

来源:juejin.cn/post/7458189303063035958
👉 欢迎加入小哈的星球,你将获得: 专属的项目实战(多个项目) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
-
新项目:《Spring AI 项目实战》正在更新中..., 基于 Spring AI + Spring Boot 3.x + JDK 21;
-
《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/
-
《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;
-
专栏阅读地址:https://www.quanxiaoha.com/column
截止目前,累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有4100+小伙伴加入

-
序言
-
nmap4j
-
-
代码说明
-
-
补充
-
总结
序言
今天在工作的时候,领导突然安排和我说一个需求,就是根据一个 ip 和 端口去获取对应服务上对应端口的信息,当时主要是为了确定数据库的版本和型号,比如 MySQL、Oracle 这些数据库,我后面尝试发现其他端口也可以获取信息。
这个在公司里之前是通过 python 来写的,python 里面刚好有这个模块,但是 Java 没有,所以写这篇文章记录一下,帮助大家以后避免踩坑。
代码已经提交到了我的GitHub:
“https://github.com/maoshengyzx/SpringBoot
nmap4j
nmap4j 是一个用于 Java 语言的 Nmap 端口扫描器的包装库,它允许 Java 开发者在自己的项目中方便地调用 Nmap 的功能进行网络扫描和探测。
GitHub地址:
“https://github.com/narkisr/nmap4j
在运行这个代码之前,我们是需要下载 nmap 的可执行文件,地址为:
“https://nmap.org/download.html[#windows](javascript:;)
这里下载第一个,下载后安装就行了。
代码说明
接下来和大家说一下 nmap4j 中的测试代码,这里面有个坑,我当时找了好久,代码在 test/org/nmap4j/Nmap4jTest.java
public class Nmap4jTest {
@Test
public void basicNmap4jUsageTest() {
try {
// 这里的路径要改为刚才 nmap 软件的安装路径
String path = "/usr/local" ;
Nmap4j nmap4j = new Nmap4j( path ) ;
// 这地方使用了 -oX 后面要跟文件名称
nmap4j.addFlags( "-sV -T5 -O -oX -" ) ;
nmap4j.includeHosts( "localhost" ) ;
nmap4j.execute() ;
if( !nmap4j.hasError() ) {
NMapRun nmapRun = nmap4j.getResult() ; // 这一行一定要注释掉,不然会一直报错
String output = nmap4j.getOutput() ; // 这一样代码意义也不大,我直接删掉了
if( output == null ) {
fail() ;
}
String errors = nmap4j.getExecutionResults().getErrors() ;
if (errors == null ) {
fail() ;
}
}
} catch (NMapInitializationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
fail() ;
} catch (NMapExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
fail() ;
}
}
}
参数说明:
目标选择参数:
-
-iL: 从文件中读取扫描目标列表。例如,nmap -iL targets.txt,会从targets.txt文件中读取每行一个的 IP 地址或域名作为扫描目标。 -
-iR: 随机选择指定数量的主机进行扫描。如nmap -iR 100,会随机选取 100 个主机进行扫描。 -
--exclude <host1[,host2,...]>: 排除指定的主机或网络不进行扫描。例如,nmap 192.168.1.0/24 --exclude 192.168.1.100,192.168.1.200,将扫描192.168.1.0/24网段,但排除192.168.1.100和192.168.1.200这两台主机。 -
--excludefile <exclude_file>: 从文件中读取要排除的主机或网络列表。
扫描类型参数:
-
-sS: TCP SYN 扫描,也称为半开放扫描。它发送 SYN 包到目标端口,如果收到SYN/ACK响应,就表示端口开放;如果收到 RST 响应,则表示端口关闭。这种扫描方式速度快,且不容易被目标系统记录,相对隐蔽,例如nmap -sS 192.168.1.100。 -
-sT: TCP 连接扫描,通过完整的 TCP 三次握手来确定端口是否开放。这种扫描方式最准确,但也最容易被检测到,如nmap -sT 192.168.1.100。 -
-sU: UDP 扫描,用于检测目标主机上的 UDP 端口是否开放。因为 UDP 是无连接协议,所以判断端口状态相对复杂,nmap -sU 192.168.1.100可对指定主机进行 UDP 扫描。 -
-sF、-sX、-sN: 分别是 FIN 扫描、XMAS 扫描和 NULL 扫描。这些扫描方式通过发送特殊标志位的 TCP 包来判断端口状态,常用于绕过一些简单的防火墙检测。
端口指定参数:
-
-p: 指定要扫描的端口范围。可以是单个端口,如-p 80;也可以是多个端口,如-p 80,443,8080;还可以是端口范围,如-p 1-1000表示扫描 1 到 1000 号端口。 -
--top-ports: 扫描最常用的指定数量的端口。例如,nmap --top-ports 100 192.168.1.100会扫描目标主机上最常用的 100 个端口。 -
-F: 快速扫描模式,只扫描一些常见的端口,相当于-p 1-1024加上一些其他常用端口。
服务探测参数:
-
-sV: 启用服务版本探测,尝试确定目标主机上运行的服务及其版本信息。例如,nmap -sV 192.168.1.100可以扫描出目标主机开放端口上运行的服务名称和版本号。 -
--version-intensity: 设置服务版本探测的强度,级别越高,探测越全面,但耗时也越长,取值范围是 0 到 9。
操作系统探测参数:
-
-O: 启用操作系统探测,尝试识别目标主机的操作系统类型和版本。如nmap -O 192.168.1.100。 -
--osscan-limit: 限制操作系统探测只对可能的目标进行,这样可以加快扫描速度,但可能会降低准确性。 -
--osscan-guess: 更积极地猜测操作系统类型,当 Nmap 不确定时会给出更宽泛的猜测结果。
输出参数:
-
-oN: 将扫描结果以正常格式保存到指定文件。例如,nmap -oN scan_results.txt 192.168.1.100会把扫描结果保存到scan_results.txt文件中。 -
-oX: 将扫描结果以 XML 格式保存到指定文件,方便后续使用脚本或其他工具进行解析和处理。 -
-oG: 将扫描结果以 Grep 格式保存,这种格式便于使用文本处理工具进行分析。 -
-oA: 以多种格式(包括正常、XML 和 Grep 格式)保存扫描结果,文件名为指定的基本名称加上相应的扩展名。 -
-v: 详细输出模式,显示更多的扫描过程信息,如发送的数据包、收到的响应等。使用多个v可以增加详细程度,如-vv、-vvv。
这里给大家看一下改造后的代码:
/**
* 使用 nmap4j 工具进行扫描
*
* @param ip 目标 ip
* @param ports 目标端口
* @return 端口信息列表
*/
@RequestMapping("/querydb")
public List<NmapPortInfo> querydb(@RequestParam(value = "ip") String ip, @RequestParam("ports") List<String> ports) {
ArrayList<NmapPortInfo> portInfos = new ArrayList<>();
// 1.拼接端口
String portStr = StrUtil.join(",", ports);
//2. 指定 nmap 路径
String path = "D:/StudyApps/nmap";
String fileName = "temp_result.xml";
Nmap4j nmap4j = new Nmap4j(path);
//3.读取端口耗时较长,可以使用异步
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
nmap4j.addFlags("-sV -p " + portStr + " -T5 -O -oX " + fileName);
nmap4j.includeHosts(ip);
try {
nmap4j.execute();
} catch (Exception e) {
thrownew RuntimeException(e);
}
}, threadPoolExecutor);
future.join();
//4. 获取端口信息
return getPortInfo(portInfos, fileName);
}
/**
* 获取 ip + 端口信息,封装为集合返回前端
*
* @param portInfos 返回前端集合
* @param fileName 临时的 xml 文件
* @return 信息列表
*/
@SneakyThrows
private List<NmapPortInfo> getPortInfo(List<NmapPortInfo> portInfos, String fileName) {
// 获取项目所在路径
String projectPath = System.getProperty("user.dir");
// 拼接文件路径
String filePath = projectPath + FileUtil.FILE_SEPARATOR + fileName;
log.info("文件路径:{}", filePath);
// nmap 返回 xml 格式固定,使用 dom4j 解析
SAXReader reader = new SAXReader();
org.dom4j.Document document = reader.read(FileUtil.file(filePath));
org.dom4j.Element rootElement = document.getRootElement();
org.dom4j.Element element = rootElement.element("host");
org.dom4j.Element xmlPorts = element.element("ports");
List<org.dom4j.Element> port = xmlPorts.elements("port");
for (org.dom4j.Element port1 : port) {
Element service = port1.element("service");
String product = service.attributeValue("product");
String version = service.attributeValue("version");
NmapPortInfo nmapPortInfo = new NmapPortInfo(product, version);
portInfos.add(nmapPortInfo);
}
// 删除临时文件
FileUtil.del(filePath);
return portInfos;
}
}
我这里就是没有去按照官网上的写法,我的思路是文件已经下载了我直接去读取 xml 文件解决会更快,这里是使用 dom4j 来读取的 xml 文件。代码就这么多,最后请求是可以获取到数据的:
补充
由于这段代码是在windows上运行的,而在实际的环境中项目都会部署到 Linux 环境汇总,所以我不得不在 Linux 上去运行调试这段代码。代码如下:
/**
* 使用 nmap4j 工具进行扫描, linux系统
*
* @param ip 目标 ip
* @param ports 目标端口
* @return 端口信息列表
*/
@GetMapping("/linux/querydb")
@SneakyThrows
public List<NmapPortInfo> linuxQuerydb(@RequestParam(value = "ip") String ip, @RequestParam("ports") List<String> ports) {
ArrayList<NmapPortInfo> portInfos = new ArrayList<>();
// 1.拼接端口
String portStr = StrUtil.join(",", ports);
String fileName = "temp_result.xml";
//2. linux namp 命令
String nmapCommand = "nmap -sV -p " + portStr + " -T5 -O -oX " + fileName + " " + ip;
//3. 读取端口耗时较长,可以使用异步
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
Process nampProcess = null;
try {
// 3. 运行命令
nampProcess = Runtime.getRuntime().exec(nmapCommand);
// 4. 等待命令执行完成
nampProcess.waitFor();
} catch (Exception e) {
thrownew RuntimeException(e);
}
}, threadPoolExecutor);
future.join();
// 5. 获取端口信息
return getPortInfo(portInfos, fileName);
}
这里的初步思路是直接调用 Linux 的命令执行 nmap (Linux系统中必须下载 nmap)。至于下载这里就不多说了,大家只需要注意下载的版本最好也为 7.95,其他版本下载的 xml 文件有问题,无法解析。
总结
忘记和大家说了,nmap4j 在maven仓库是搜不到的,所以只通过 jar 包的方式来引入,地址为:
“https://master.dl.sourceforge.net/project/nmap4j/1.1.0/org.nmap4j-1.1.0-RELEASE.zip?viasf=1
好书推荐

-
零基础友好:从基础概念到实战代码,全程图解+案例拆解,哪怕没学过Python也能轻松掌握大模型优化技巧。
-
硬核干货:一本书搞定深度学习全链路优化,覆盖模型训练、压缩、部署全流程,详解梯度下降、遗传算法、神经网络优化等核心技术,附赠可运行代码库。
-
实战派秘籍:真实项目经验直接搬进书里,书中包含自动驾驶、医疗诊断等落地场景优化方案,带你解决实际业务痛点。
-
前沿技术解码:独家解析分布式训练、混合专家系统等核心技术细节,手把手教你用API调通大模型。

-
国产大模型自主部署:DeepSeek全栈本地化指南,Ollama+信创系统实战详解
-
一键构建政企专属AI助手:从Dify工作流到OpenWebUI安全配置,三大企业级案例复现,附全流程代码
-
私有化AI安全防护体系:深度拆解OpenWebUI知识库引擎+Dify智能体架构,AI黑盒不再神秘
-
零基础快速上手:从理论到实操,逐步稳定获取结果,分享多种实用插件和工具
-
效率提升300%:从云端到本地DeepSeek私有化部署成本对比,各梯度显卡与硬件实测数据大公开
👉 欢迎加入小哈的星球,你将获得: 专属的项目实战(多个项目) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
-
新项目:《Spring AI 项目实战》正在更新中..., 基于 Spring AI + Spring Boot 3.x + JDK 21;
-
《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍;演示地址:http://116.62.199.48:7070/
-
《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;
-
专栏阅读地址:https://www.quanxiaoha.com/column
截止目前,累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有4100+小伙伴加入


1. 我的私密学习小圈子,从0到1手撸企业实战项目~ 2. 替代FinalShell,一款更高效、更智能的开源终端神器! 3. 一款被低估的插件:IDEA+JProfiler=性能分析神器 4. 索引10连问,你能抗住第几问?
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。 点“在看”支持小哈呀,谢谢啦
更多推荐

所有评论(0)