
네트워크 스캐너 바이너리를 호출하기 위한 관용적(idiomatic) Go 라이브러리로, 호스트 발견, 포트 스캐닝, 서비스/OS 탐지, 스크립트 기반 취약점 점검을 지원하여 보안 감사를 수행합니다.
이 라이브러리는 Go 개발자에게 관용적인 nmap 바인딩을 제공하여 golang을 사용해 보안 감사 도구를 더 쉽게 작성할 수 있도록 하는 것을 목표로 합니다.
Nmap(Network Mapper)은 Gordon Lyon이 만든 무료 오픈소스 네트워크 스캐너입니다. Nmap은 패킷을 보내고 응답을 분석하여 컴퓨터 네트워크에서 호스트와 서비스를 발견하는 데 사용됩니다.
Nmap은 호스트 발견, 서비스 및 운영 체제 탐지를 포함하여 컴퓨터 네트워크를 조사하기 위한 다양한 기능을 제공합니다. 이러한 기능은 더 고급 서비스 탐지, 취약점 탐지 및 기타 기능을 제공하는 스크립트로 확장할 수 있습니다. Nmap은 스캔 중 지연 시간과 혼잡을 포함한 네트워크 조건에 적응할 수 있습니다.
대부분의 침투 테스트 도구는 현재 Python으로 작성되며 Go는 사용되지 않습니다. 스크립트를 빠르게 작성하기 쉽고, 사용 가능한 라이브러리가 많으며, 사용하기 쉬운 언어이기 때문입니다. 그러나 견고하고 신뢰할 수 있는 애플리케이션을 작성하려면 Go가 더 나은 도구입니다. Go는 정적으로 컴파일되고, 정적 타입 시스템을 가지며, 성능이 훨씬 뛰어나며, 또한 사용하기 매우 쉬운 언어이고 goroutine은 훌륭합니다... 하지만 제 의견이 다소 편향되었을 수 있으니 동의하지 않으셔도 좋습니다.
이 라이브러리는 Go의 exec 패키지를 사용하여 nmap 바이너리를 실행하고 XML 출력을 파싱합니다. 즉, 이 라이브러리가 작동하려면 nmap이 설치되어 있고 PATH에 있어야 합니다.
현재 최신 버전인 nmap 7.98에서 호환성이 확인되었습니다.
일부 스캔 유형은 상승된 권한이 필요합니다(예: SYN 스캔, OS 탐지 또는 raw socket 사용). 해당 옵션을 활성화하면 프로그램을 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] 터미널 이스케이프 시퀀스에 의존하며 프로세스가 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 스트림을 발견하며, 원격으로 액세스합니다.
더 많은 예제: