
Идиоматическая Go-библиотека для вызова бинарного файла сетевого сканера, обеспечивающая обнаружение хостов, сканирование портов, определение сервисов/ОС и скриптовые проверки уязвимостей для аудита безопасности.
Эта библиотека предоставляет идиоматичные привязки nmap для Go-разработчиков, чтобы упростить создание инструментов аудита безопасности на языке Go.
Nmap (Network Mapper) — это бесплатный сканер сети с открытым исходным кодом, созданный Гордоном Лайоном. Nmap используется для обнаружения хостов и сервисов в компьютерной сети путём отправки пакетов и анализа ответов.
Nmap предоставляет ряд функций для исследования компьютерных сетей, включая обнаружение хостов, определение сервисов и операционной системы. Эти возможности расширяются с помощью скриптов, обеспечивающих более продвинутое обнаружение сервисов, поиск уязвимостей и другие функции. Nmap умеет адаптироваться к сетевым условиям, включая задержки и перегрузки во время сканирования.
Большинство пентест-инструментов в настоящее время написаны на Python, а не на Go, потому что на Python легко быстро писать скрипты, доступно множество библиотек, и это простой язык. Однако для создания надёжных и стабильных приложений Go подходит лучше. Он статически компилируется, имеет статическую систему типов, гораздо более высокую производительность, также он очень прост в использовании, а горутины — это здорово... Но, возможно, я слегка предвзят, так что не стесняйтесь не соглашаться.
Эта библиотека вызывает бинарник nmap через пакет exec из Go и разбирает XML-вывод.
Это означает, что для работы библиотеки nmap должен быть установлен и доступен в вашем PATH.
Совместимость подтверждена с текущей последней версией nmap — 7.98.
Некоторые типы сканирования требуют повышенных привилегий (например, SYN-сканирование, определение ОС или использование raw-сокетов). Если вы включаете эти опции, возможно, потребуется запускать программу через sudo или с соответствующими capabilities для вашей платформы.
[!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] Это основано на управляющих escape-последовательностях терминала и работает только тогда, когда процесс привязан к 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-потоков и удалённого доступа к ним.
Больше примеров: