
用于调用网络扫描器二进制的惯用 Go 库,支持主机发现、端口扫描、服务/操作系统检测,以及为安全审计而设的脚本化漏洞检查。
本库旨在为 go 开发者提供符合习惯用法的 nmap 绑定,以便更轻松地使用 golang 编写安全审计工具。
Nmap(Network Mapper)是一款由 Gordon Lyon 创建的免费开源网络扫描器。Nmap 通过发送数据包并分析响应,来发现计算机网络上的主机和服务。
Nmap 提供了许多用于探测计算机网络的特性,包括主机发现、服务检测与操作系统检测。这些特性可以通过脚本进行扩展,以提供更高级的服务检测、漏洞检测等功能。Nmap 还能适应扫描过程中的网络状况,包括延迟和拥塞。
目前大多数渗透测试工具都是用 Python 而不是 Go 编写的,因为用 Python 可以快速编写脚本、有大量可用库,而且它是一种易于使用的语言。然而,要编写健壮、可靠的应用程序,Go 是更好的工具。它是静态编译的,具有静态类型系统,性能好得多,同时也是一种非常简单的语言,而且 goroutine 非常厉害……不过我可能有点偏见,欢迎持不同意见。
该库通过 Go 的 exec 包调用 nmap 二进制程序,并解析其 XML 输出。这意味着要使用该库,必须安装 nmap 并确保它位于你的 PATH 中。
已确认与目前最新版本的 nmap 7.98 兼容。
某些扫描类型需要提升权限(例如 SYN 扫描、操作系统检测或使用原始套接字)。如果你启用了这些选项,可能需要使用 sudo 或你平台上适当的 capabilities 来运行程序。
[!TIP] 对于非特权运行,建议使用连接扫描(例如
-sT)。
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/Ullaakut/nmap/v4"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
// Equivalent to `/usr/local/bin/nmap -p 80,443,843 google.com facebook.com youtube.com`,
// with a 5-minute timeout.
scanner, err := nmap.NewScanner(
nmap.WithTargets("scanme.nmap.org"),
nmap.WithPorts("80,443,843"),
)
if err != nil {
log.Fatalf("creating nmap scanner: %v", err)
}
result, err := scanner.Run(ctx)
if err != nil {
log.Fatalf("running network scan: %v", err)
}
warnings := result.Warnings()
if len(warnings) > 0 {
log.Printf("warning: %v\n", warnings) // Warnings are non-critical errors from nmap.
}
// Use the results to print an example output
for _, host := range result.Hosts {
if len(host.Ports) == 0 || len(host.Addresses) == 0 {
continue
}
fmt.Printf("Host %q:\n", host.Addresses[0])
for _, port := range host.Ports {
fmt.Printf("\tPort %d/%s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name)
}
}
fmt.Printf("Nmap done: %d hosts up scanned in %.2f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed)
}
上面的程序输出:
Host "45.33.32.156":
Port 80/tcp open http
Port 443/tcp closed https
Port 843/tcp closed
Nmap done: 1 hosts up scanned in 0.42 seconds
[!IMPORTANT] 这依赖于终端转义序列,仅当进程附加到 TTY 时才有效。
[!NOTE] 进度不保证单调递增:nmap 会估算剩余时间并可能修正该估算值,这可能导致报告的百分比下降。
package main
import (
"context"
"log"
"time"
"github.com/Ullaakut/nmap/v4"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
scanner, err := nmap.NewScanner(
nmap.WithTargets("scanme.nmap.org"),
nmap.WithPorts("1-1024"),
nmap.WithTimingTemplate(nmap.TimingAggressive),
nmap.WithProgress(time.Second, handleProgress),
)
if err != nil {
log.Fatalf("creating nmap scanner: %v", err)
}
_, err = scanner.Run(ctx)
if err != nil {
log.Fatalf("running network scan: %v", err)
}
}
func handleProgress(p nmap.TaskProgress) {
log.Println("Current progress: ", p.Percent)
}
此示例输出如下:
2026/01/27 16:13:02 task "Connect Scan": 2.59% remaining 38
2026/01/27 16:13:02 task "Connect Scan": 21.26% remaining 4
2026/01/27 16:13:04 task "Connect Scan": 42.61% remaining 5
2026/01/27 16:13:04 task "Connect Scan": 45.51% remaining 4
2026/01/27 16:13:05 task "Connect Scan": 53.44% remaining 4
2026/01/27 16:13:07 task "Connect Scan": 59.77% remaining 5
2026/01/27 16:13:07 task "Connect Scan": 62.77% remaining 4
2026/01/27 16:13:08 task "Connect Scan": 73.24% remaining 3
2026/01/27 16:13:09 task "Connect Scan": 81.71% remaining 2
2026/01/27 16:13:10 task "Connect Scan": 92.92% remaining 1
2026/01/27 16:13:11 task "Connect Scan": 100.00% remaining 0
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/Ullaakut/nmap/v4"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
scanner, err := nmap.NewScanner(
nmap.WithTargets("scanme.nmap.org"),
nmap.WithPorts("1-1024"),
)
if err != nil {
log.Fatalf("creating nmap scanner: %v", err)
}
stdout, stderr, resultCh, err := scanner.RunAsync(ctx)
if err != nil {
log.Fatalf("running network scan: %v", err)
}
for {
select {
case <-ctx.Done():
log.Fatalf("scan timed out: %v", ctx.Err())
case out := <-stdout:
fmt.Printf("nmap output: %s\n", out)
case errOut := <-stderr:
fmt.Printf("nmap error output: %s\n", errOut)
case result := <-resultCh:
if result.Err != nil {
log.Fatalf("running network scan: %v", result.Err)
}
fmt.Printf("Nmap done: %d hosts up\n", len(result.Result.Hosts))
return
}
}
}
更多用法示例请参阅 examples 目录。
Cameradar 已经在核心部分使用该库来与 nmap 通信、发现 RTSP 流并远程访问它们。
更多示例: