
ネットワークスキャナのバイナリを起動するための慣用的なGoライブラリで、セキュリティ監査のためのホスト検出、ポートスキャン、サービス/OS検出、スクリプト化された脆弱性チェックを可能にします。
このライブラリは、golang を使ってセキュリティ監査ツールを書きやすくするために、Go 開発者向けの慣用的な nmap バインディングを提供することを目的としています。
Nmap(Network Mapper)は、Gordon Lyon によって作られたフリーかつオープンソースのネットワークスキャナです。Nmap は、パケットを送信して応答を解析することにより、コンピュータネットワーク上のホストとサービスを発見するために使用されます。
Nmap は、ホスト発見、サービスおよびオペレーティングシステムの検出など、コンピュータネットワークを調査するための多くの機能を提供します。これらの機能は、より高度なサービス検出、脆弱性検出、その他の機能を提供するスクリプトによって拡張できます。Nmap は、スキャン中のレイテンシや混雑などのネットワーク状況に適応できます。
現在、多くのペンテストツールはGoではなくPythonで書かれています。それは、スクリプトを素早く書くのが簡単で、ライブラリが豊富にあり、使いやすい言語だからです。しかし、堅牢で信頼性の高いアプリケーションを書くには、Goの方が適しています。Goは静的にコンパイルされ、静的型システムを持ち、パフォーマンスがはるかに優れています。また、非常に使いやすい言語であり、goroutineも素晴らしいです...ただ、私は少々偏っているかもしれませんので、異論があればどうぞ。
このライブラリは、Goの exec パッケージを使って nmap バイナリを外部プロセスとして実行し、XML出力を解析します。
つまり、このライブラリを動作させるには、nmap がインストールされ、PATH上で利用可能である必要があります。
互換性は、現在の最新バージョンである nmap 7.98 で確認されています。
一部のスキャンタイプは昇格した権限を必要とします(例:SYNスキャン、OS検出、rawソケットの使用)。 これらのオプションを有効にする場合、プログラムを sudo またはプラットフォームに適したケーパビリティで実行する必要があるかもしれません。
[!TIP] 非特権での実行には、connectスキャン(例:
-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ストリームの発見、リモートからのアクセスを実現するための中核としてこのライブラリを使用しています。
その他の例: