GO實(shí)現(xiàn)基于命令行的簡單IPS程序代碼
入侵防御系統(tǒng)
IPS(Intrusion Prevention System)即入侵防御系統(tǒng),主要用于實(shí)時(shí)檢查和阻止網(wǎng)絡(luò)入侵。與入侵檢測系統(tǒng)(IDS)不同,IPS通常部署在網(wǎng)絡(luò)的關(guān)鍵路徑上,實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)流量,并在發(fā)現(xiàn)攻擊時(shí)立即采取響應(yīng)措施,如丟棄惡意數(shù)據(jù)包、封鎖攻擊源IP地址等。
IPS的工作原理
IPS通過直接嵌入到網(wǎng)絡(luò)流量中實(shí)現(xiàn)主動防御。它通過一個(gè)網(wǎng)絡(luò)端口接收來自外部系統(tǒng)的流量,經(jīng)過檢查確認(rèn)其中不包含異?;顒踊蚩梢蓛?nèi)容后,再通過另一個(gè)端口傳送到內(nèi)部系統(tǒng)中。有問題的數(shù)據(jù)包以及所有來自同一數(shù)據(jù)流的后續(xù)數(shù)據(jù)包都會在IPS設(shè)備中被清除掉。
GO實(shí)現(xiàn)IPS
下面我們用 Go 語言編寫,一個(gè)可以在命令行中獲取并打印本地 IP 地址(基于常見網(wǎng)絡(luò)接口)的示例程序,這里主要是獲取 IPv4 地址進(jìn)行展示,示例代碼使用了標(biāo)準(zhǔn)庫中的 net 包:
獲取本地網(wǎng)絡(luò)接口上綁定的 IP
package main import ( "fmt" "net" ) func main() { addrs, err := net.InterfaceAddrs() if err!= nil { fmt.Printf("獲取網(wǎng)絡(luò)接口地址失敗: %v\n", err) return } for _, addr := range addrs { ipNet, ok := addr.(*net.IPNet) if ok &&!ipNet.IP.IsLoopback() && ipNet.IP.To4()!= nil { fmt.Println("IP地址:", ipNet.IP.String()) } } }
運(yùn)行
- 確保已經(jīng)安裝了 Go 環(huán)境(Go 1.10 及以上版本)。
- 將上述代碼保存到一個(gè)以 .go 為后綴的文件中,比如 ips.go。
- 打開命令行,切換到該文件所在的目錄。
- 運(yùn)行命令 go run ips.go,程序就會執(zhí)行并輸出找到的本地非回環(huán)的 IPv4 地址信息。
也可編譯后運(yùn)行
go build ips.go
然后運(yùn)行生成的可執(zhí)行文件(在 Windows 上是 .exe 后綴的文件,在 Linux、macOS 等系統(tǒng)上就是普通的二進(jìn)制文件)也能看到相應(yīng)的 IP 地址輸出。
請注意:這里只是簡單獲取本地網(wǎng)絡(luò)接口上綁定的 IP 示例
對于IPS而言,他要檢測的是網(wǎng)絡(luò)中的流量(比如探測網(wǎng)絡(luò)中其他設(shè)備 IP 等)這需要進(jìn)一步擴(kuò)展代碼,例如利用 net.Dial 等去做網(wǎng)絡(luò)連接測試、IP 掃描等操作。
探測網(wǎng)絡(luò)中其他設(shè)備 IP
這里只是通過簡單的 ICMP 即 ping 操作概念類似的簡單探測
package main import ( "fmt" "net" "os" "sync" "time" ) func PingIP(ip string, wg *sync.WaitGroup, result chan<- string) { defer wg.Done() conn, err := net.DialTimeout("ip4:icmp", ip, time.Second*2) if err == nil { conn.Close() result <- ip } } func main() { if len(os.Args)!= 2 { fmt.Println("請輸入要掃描的網(wǎng)段,例如 192.168.1.0/24") return } _, ipnet, err := net.ParseCIDR(os.Args[1]) if err!= nil { fmt.Printf("解析網(wǎng)段失敗: %v\n", err) return } var wg sync.WaitGroup result := make(chan string) for ip := ipnet.IP.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) { wg.Add(1) go PingIP(ip.String(), &wg, result) } go func() { wg.Wait() close(result) }() for aliveIP := range result { fmt.Println("存活I(lǐng)P:", aliveIP) } } func inc(ip net.IP) { for j := len(ip) - 1; j >= 0; j-- { ip[j]++ if ip[j] > 0 { break } } }
在命令行中使用這個(gè)擴(kuò)展版本時(shí),可以像這樣運(yùn)行(假設(shè)編譯后的可執(zhí)行文件名為 ips):
./ips 192.168.1.0/24
上述命令會嘗試去探測指定網(wǎng)段 192.168.1.0/24 內(nèi)的 IP 地址哪些是存活的(可以響應(yīng) ICMP 請求的,類似 ping 通的概念),并打印出存活的 IP 地址。
增加規(guī)則文件(rules.json)
首先我們設(shè)定一個(gè)規(guī)則文件,用json的方式來保存規(guī)則
[ { "id": "1001", "description": "SSH暴力破解檢測", "protocol": "tcp", "dst_port": 22, "action": "block", "threshold": 5, "time_window": 60 }, { "id": "1002", "description": "RDP暴力破解檢測", "protocol": "tcp", "dst_port": 3389, "action": "block", "threshold": 5, "time_window": 60 }, { "id": "1003", "description": "MySQL暴力破解檢測", "protocol": "tcp", "dst_port": 3306, "action": "block", "threshold": 5, "time_window": 60 } ]
然后我們寫一個(gè)go文件,來檢測 IP 對相應(yīng)端口的訪問是否達(dá)到規(guī)則中定義的暴力破解閾值情況
package main import ( "encoding/json" "fmt" "io/ioutil" "net" "os" "path/filepath" "sync" "time" ) // Rule結(jié)構(gòu)體表示一條安全規(guī)則 type Rule struct { ID string `json:"id"` Description string `json:"description"` Protocol string `json:"protocol"` DstPort int `json:"dst_port"` Action string `json:"action"` Threshold int `json:"threshold"` TimeWindow int `json:"time_window"` } // LoadRules從文件加載安全規(guī)則 func LoadRules(filePath string) ([]*Rule, error) { content, err := ioutil.ReadFile(filePath) if err!= nil { return nil, fmt.Errorf("讀取規(guī)則文件失敗: %v", err) } var rules []*Rule err = json.Unmarshal(content, &rules) if err!= nil { return nil, fmt.Errorf("解析規(guī)則文件失敗: %v", err) } return rules, nil } // ConnectionRecord記錄IP的連接記錄(簡化示例,僅記錄次數(shù)) type ConnectionRecord struct { mu sync.Mutex connections map[string]int } func NewConnectionRecord() *ConnectionRecord { return &ConnectionRecord{ connections: make(map[string]int), } } func (cr *ConnectionRecord) Record(ip net.IP, port int) { cr.mu.Lock() key := fmt.Sprintf("%s:%d", ip.String(), port) cr.connections[key]++ cr.mu.Unlock() } func (cr *ConnectionRecord) CheckViolation(rules []*Rule) []*Rule { var violatedRules []*Rule cr.mu.Lock() now := time.Now() for _, rule := range rules { for key, count := range cr.connections { parts := strings.Split(key, ":") ip := net.ParseIP(parts[0]) port := atoi(parts[1]) if port == rule.DstPort && count >= rule.Threshold { // 這里簡單判斷次數(shù)達(dá)到閾值就算違規(guī),實(shí)際可能需考慮時(shí)間窗口等更復(fù)雜邏輯細(xì)化 violatedRules = append(violatedRules, rule) } } } cr.mu.Unlock() return violatedRules } func atoi(s string) int { n, _ := fmt.Sscanf(s, "%d", &n) return n } func main() { // 獲取當(dāng)前目錄下的rules.json作為配置文件路徑(可根據(jù)實(shí)際調(diào)整) currentDir, err := os.Getwd() if err!= nil { fmt.Printf("獲取當(dāng)前目錄失敗: %v\n", err) return } configFilePath := filepath.Join(currentDir, "rules.json") rules, err := LoadRules(configFilePath) if err!= nil { fmt.Printf("加載規(guī)則失敗: %v\n", err) return } targetIPNet := &net.IPNet{} _, targetIPNet, err = net.ParseCIDR("192.168.1.0/24") if err!= nil { fmt.Printf("解析目標(biāo)IP網(wǎng)段失敗: %v\n", err) return } record := NewConnectionRecord() // 模擬IP對內(nèi)網(wǎng)端口的連接訪問(這里簡單循環(huán)增加連接次數(shù)示例) for i := 0; i < 10; i++ { for ip := targetIPNet.IP.Mask(targetIPNet.Mask); targetIPNet.Contains(ip); inc(ip) { // 簡單模擬多次訪問各規(guī)則關(guān)注的端口,實(shí)際場景會根據(jù)真實(shí)網(wǎng)絡(luò)連接情況記錄 for _, rule := range rules { record.Record(ip, rule.DstPort) } } } violatedRules := record.CheckViolation(rules) for _, violatedRule := range violatedRules { fmt.Printf("IP段內(nèi)存在疑似違反規(guī)則 %s 的情況,規(guī)則描述:%s\n", violatedRule.ID, violatedRule.Description) } } func inc(ip net.IP) { for j := len(ip) - 1; j >= 0; j-- { ip[j]++ if ip[j] > 0 { break } } }
- 定義規(guī)則結(jié)構(gòu)體和相關(guān)操作函數(shù):
- 首先定義了 Rule 結(jié)構(gòu)體,其字段與 JSON 格式的規(guī)則文件中的各個(gè)屬性相對應(yīng),用于表示一條安全規(guī)則。
- LoadRules 函數(shù)用于讀取指定路徑的 JSON 規(guī)則文件,并將其解析為 Rule 結(jié)構(gòu)體的切片,若讀取或解析過程出現(xiàn)錯(cuò)誤則返回相應(yīng)的錯(cuò)誤信息。
- 定義連接記錄結(jié)構(gòu)體及相關(guān)方法:
- ConnectionRecord 結(jié)構(gòu)體用于記錄 IP 地址對不同端口的連接情況,內(nèi)部使用一個(gè)互斥鎖(sync.Mutex)來保證并發(fā)安全,通過 Record 方法記錄每個(gè) IP 和端口的連接次數(shù),使用 CheckViolation 方法來檢查當(dāng)前的連接記錄是否違反了給定的規(guī)則(這里只是簡單根據(jù)連接次數(shù)是否達(dá)到閾值判斷,實(shí)際可進(jìn)一步完善考慮時(shí)間窗口等更多細(xì)節(jié))。
- 主函數(shù)邏輯:
- 先獲取當(dāng)前目錄下規(guī)則配置文件(rules.json)的路徑(可按需修改為其他路徑),調(diào)用 LoadRules 函數(shù)加載規(guī)則列表。
- 接著解析要檢測的目標(biāo) IP 網(wǎng)段(示例中為 192.168.1.0/24,可以根據(jù)實(shí)際情況更改),創(chuàng)建一個(gè) ConnectionRecord 實(shí)例來記錄連接情況。
- 然后通過循環(huán)模擬 IP 對內(nèi)網(wǎng)各端口的訪問(這里只是簡單循環(huán)增加訪問次數(shù)示意,實(shí)際需要結(jié)合真實(shí)的網(wǎng)絡(luò)連接情況來記錄),并調(diào)用 ConnectionRecord 的 Record 方法記錄每次的訪問情況。
- 最后調(diào)用 ConnectionRecord 的 CheckViolation 方法檢查是否有違反規(guī)則的情況,若有則打印出相應(yīng)的違規(guī)規(guī)則信息。
注意
這里的代碼僅是拋磚引玉,其中的規(guī)則檢查邏輯,尤其是針對時(shí)間窗口的處理比較簡化,在實(shí)際應(yīng)用場景中,你可能需要精確地記錄每個(gè)連接的時(shí)間戳,并按照時(shí)間窗口準(zhǔn)確判斷是否在指定時(shí)間段內(nèi)達(dá)到了閾值等情況,以實(shí)現(xiàn)更符合實(shí)際需求的檢測邏輯。
模擬的 IP 訪問場景也非常簡單,只是為了演示功能而進(jìn)行的簡單循環(huán)增加訪問次數(shù),實(shí)際需要對接真實(shí)的網(wǎng)絡(luò)流量監(jiān)控等相關(guān)機(jī)制來準(zhǔn)確記錄 IP 的訪問情況。
到此這篇關(guān)于GO實(shí)現(xiàn)基于命令行的簡單IPS程序代碼的文章就介紹到這了,更多相關(guān)GO實(shí)現(xiàn)基于命令行的簡單IPS內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Go如何優(yōu)雅的對時(shí)間進(jìn)行格式化
這篇文章主要為大家詳細(xì)介紹了Go語言中是如何優(yōu)雅的對時(shí)間進(jìn)行格式化的,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-06-06golang 實(shí)現(xiàn)每隔幾分鐘執(zhí)行一個(gè)函數(shù)
這篇文章主要介紹了golang 實(shí)現(xiàn)每隔幾分鐘執(zhí)行一個(gè)函數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12golang實(shí)現(xiàn)讀取excel數(shù)據(jù)并導(dǎo)入數(shù)據(jù)庫
Go 語言是一門適合用于編寫高效且并發(fā)的 Web 應(yīng)用程序的編程語言,同時(shí)也可以使用它進(jìn)行數(shù)據(jù)處理和分析,本文主要介紹了如何通過go語言實(shí)現(xiàn)讀取excel數(shù)據(jù)并導(dǎo)入數(shù)據(jù)庫,感興趣的小伙伴可以了解下2025-04-04Golang中生成隨機(jī)字符串并復(fù)制到粘貼板的方法
這篇文章主要介紹了Golang中生成隨機(jī)字符串并復(fù)制到粘貼板的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12利用golang實(shí)現(xiàn)pdf中自動換行的表格
這篇文章主要給大家介紹了如何利用golang實(shí)現(xiàn)pdf中自動換行的表格,文中通過代碼示例給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-02-02