基于Go語(yǔ)言實(shí)現(xiàn)一個(gè)并發(fā)端口掃描器
一、實(shí)戰(zhàn)背景
端口掃描器是網(wǎng)絡(luò)安全領(lǐng)域常用的工具,它通過(guò)對(duì)目標(biāo)主機(jī)的端口進(jìn)行掃描,檢測(cè)目標(biāo)設(shè)備是否開(kāi)放某些服務(wù)端口(如 HTTP、FTP、SSH 等)。常見(jiàn)的端口掃描場(chǎng)景包括:
- 安全審計(jì):檢測(cè)主機(jī)是否存在未授權(quán)服務(wù)
- 漏洞掃描:識(shí)別可能存在漏洞的服務(wù)端口
- 網(wǎng)絡(luò)診斷:排查服務(wù)器是否正常工作
傳統(tǒng)的端口掃描使用串行方式,一個(gè)端口一個(gè)端口地檢查,速度非常慢。而 Go 的并發(fā)編程可以極大地提升掃描效率。
二、實(shí)戰(zhàn)目標(biāo)
我們將實(shí)現(xiàn)一個(gè)并發(fā)端口掃描器,具備以下功能:
- 輸入目標(biāo)主機(jī) IP 和端口范圍
- 使用并發(fā)掃描多個(gè)端口
- 輸出每個(gè)端口的開(kāi)放狀態(tài)
- 使用超時(shí)機(jī)制控制掃描時(shí)間,避免阻塞
三、完整代碼實(shí)現(xiàn)
1. 掃描器實(shí)現(xiàn)(scanner.go)
package main
import (
"fmt"
"net"
"strconv"
"sync"
"time"
)
func scanPort(ip string, port int, wg *sync.WaitGroup, resultCh chan<- string) {
defer wg.Done()
address := fmt.Sprintf("%s:%d", ip, port)
conn, err := net.DialTimeout("tcp", address, 1*time.Second) // 設(shè)置連接超時(shí)時(shí)間
if err != nil {
resultCh <- fmt.Sprintf("端口 %d: 關(guān)閉", port)
return
}
conn.Close()
resultCh <- fmt.Sprintf("端口 %d: 開(kāi)放", port)
}
func main() {
var wg sync.WaitGroup
resultCh := make(chan string, 100) // 創(chuàng)建帶緩沖的 Channel,緩沖區(qū)大小為 100
fmt.Print("請(qǐng)輸入目標(biāo) IP 地址: ")
var ip string
fmt.Scanln(&ip)
fmt.Print("請(qǐng)輸入端口范圍(例如:80 100): ")
var startPort, endPort int
fmt.Scanln(&startPort, &endPort)
// 掃描指定范圍的端口
for port := startPort; port <= endPort; port++ {
wg.Add(1)
go scanPort(ip, port, &wg, resultCh)
}
// 等待所有掃描任務(wù)完成并關(guān)閉 Channel
go func() {
wg.Wait()
close(resultCh)
}()
// 打印掃描結(jié)果
fmt.Println("\n掃描結(jié)果:")
for result := range resultCh {
fmt.Println(result)
}
}
四、運(yùn)行方式
執(zhí)行端口掃描器
go run scanner.go
輸入示例:
請(qǐng)輸入目標(biāo) IP 地址: 192.168.1.1 請(qǐng)輸入端口范圍(例如:80 100): 80 90
輸出示例:
掃描結(jié)果: 端口 80: 開(kāi)放 端口 81: 關(guān)閉 端口 82: 關(guān)閉 端口 83: 關(guān)閉 端口 84: 開(kāi)放 端口 85: 關(guān)閉 端口 86: 開(kāi)放 端口 87: 關(guān)閉 端口 88: 關(guān)閉 端口 89: 開(kāi)放 端口 90: 關(guān)閉
五、關(guān)鍵技術(shù)點(diǎn)解析
1. 使用 Goroutine 并發(fā)掃描端口
每個(gè)端口的掃描任務(wù)都是由獨(dú)立的 Goroutine 執(zhí)行的。這樣可以最大化利用 CPU 核心,實(shí)現(xiàn)端口掃描的并發(fā)化。
go scanPort(ip, port, &wg, resultCh)
2. 使用 sync.WaitGroup 等待所有 Goroutine 完成
WaitGroup 用來(lái)等待所有掃描任務(wù)完成,確保在關(guān)閉結(jié)果通道之前所有掃描任務(wù)已經(jīng)結(jié)束。
var wg sync.WaitGroup wg.Add(1)
3. 使用 net.DialTimeout 設(shè)置連接超時(shí)
DialTimeout 可以在指定的超時(shí)時(shí)間內(nèi)完成連接,如果超時(shí)則返回錯(cuò)誤。我們?cè)谶@里設(shè)置了 1 秒的超時(shí)。
conn, err := net.DialTimeout("tcp", address, 1*time.Second)
4. 使用 channel 收集掃描結(jié)果
通過(guò) Channel 傳遞每個(gè)端口的掃描結(jié)果,避免了主線程和 Goroutine 之間的數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題。
resultCh <- fmt.Sprintf("端口 %d: 開(kāi)放", port)
5. 緩存掃描結(jié)果并打印
使用帶緩沖的 Channel resultCh 存儲(chǔ)掃描結(jié)果。所有任務(wù)完成后,我們關(guān)閉通道并打印掃描結(jié)果。
go func() {
wg.Wait()
close(resultCh)
}()
六、優(yōu)化和擴(kuò)展方向
| 優(yōu)化方向 | 說(shuō)明 |
|---|---|
| 控制并發(fā)數(shù)量 | 使用令牌桶算法(Token Bucket)或 sem 控制并發(fā)掃描的 Goroutine 數(shù)量 |
| 支持輸入多個(gè)目標(biāo) IP | 擴(kuò)展支持一次掃描多個(gè) IP 地址 |
| 掃描端口的協(xié)議支持 | 不僅支持 TCP 端口掃描,還可支持 UDP 掃描 |
| 日志記錄 | 將掃描結(jié)果輸出到日志文件,便于后期分析 |
| 進(jìn)度條顯示 | 添加掃描進(jìn)度顯示,提升用戶體驗(yàn) |
| 智能端口掃描 | 根據(jù)常見(jiàn)端口列表(如 80、443、21 等)進(jìn)行掃描 |
七、小結(jié)
通過(guò)本篇案例,你學(xué)會(huì)了如何用 Go 實(shí)現(xiàn)一個(gè)并發(fā)端口掃描器,掌握了以下關(guān)鍵技術(shù):
- 使用 Goroutine 實(shí)現(xiàn)并發(fā)任務(wù)處理
- 利用
sync.WaitGroup等待所有并發(fā)任務(wù)完成 - 使用
net.DialTimeout進(jìn)行超時(shí)控制,防止阻塞 - 使用 Channel 收集并傳遞任務(wù)結(jié)果
這個(gè)并發(fā)端口掃描器可以幫助你在網(wǎng)絡(luò)安全和系統(tǒng)維護(hù)中快速診斷目標(biāo)主機(jī)的開(kāi)放端口。通過(guò)優(yōu)化,您還可以將其擴(kuò)展成更完整的網(wǎng)絡(luò)掃描工具。
以上就是基于Go語(yǔ)言實(shí)現(xiàn)一個(gè)并發(fā)端口掃描器的詳細(xì)內(nèi)容,更多關(guān)于Go并發(fā)端口掃描器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
golang抓取網(wǎng)頁(yè)并分析頁(yè)面包含的鏈接方法
今天小編就為大家分享一篇golang抓取網(wǎng)頁(yè)并分析頁(yè)面包含的鏈接方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08
go語(yǔ)言基礎(chǔ) seek光標(biāo)位置os包的使用
這篇文章主要介紹了go語(yǔ)言基礎(chǔ) seek光標(biāo)位置os包的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-05-05
Golang設(shè)計(jì)模式之適配器模式詳細(xì)講解
這篇文章主要介紹了使用go實(shí)現(xiàn)適配器模式,這個(gè)模式就是用來(lái)做適配的,它將不兼容的接口轉(zhuǎn)換為可兼容的接口,讓原本由于接口不兼容而不能一起工作的類可以一起工作,需要的朋友可以參考下2023-01-01
聊聊Go語(yǔ)言編譯github上的項(xiàng)目遇到的坑
這篇文章主要介紹了解決Go語(yǔ)言編譯github上的項(xiàng)目遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
Go語(yǔ)言中兩個(gè)比較流行的緩存庫(kù)使用示例
緩存是計(jì)算機(jī)科學(xué)中的一個(gè)重要概念,設(shè)想某個(gè)組件需要訪問(wèn)外部資源,它向外部源請(qǐng)求資源,接收并使用資源,這些步驟都需要花費(fèi)時(shí)間,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中兩個(gè)比較流行的緩存庫(kù)使用的相關(guān)資料,需要的朋友可以參考下2024-04-04
golang開(kāi)發(fā)及數(shù)字證書研究分享
這篇文章主要為大家介紹了golang開(kāi)發(fā)以及數(shù)字證書的研究示例分享,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11
VSCode1.4 搭建Golang的開(kāi)發(fā)調(diào)試環(huán)境(遇到很多問(wèn)題)
這篇文章主要介紹了VSCode1.4 搭建Golang的開(kāi)發(fā)調(diào)試環(huán)境(遇到很多問(wèn)題),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Go語(yǔ)言中如何實(shí)現(xiàn)并發(fā)
Go的并發(fā)機(jī)制通過(guò)協(xié)程和通道的簡(jiǎn)單性和高效性,使得編寫并發(fā)代碼變得相對(duì)容易,這種并發(fā)模型被廣泛用于構(gòu)建高性能的網(wǎng)絡(luò)服務(wù)、并行處理任務(wù)和其他需要有效利用多核處理器的應(yīng)用程序,這篇文章主要介紹了在Go中如何實(shí)現(xiàn)并發(fā),需要的朋友可以參考下2023-09-09

