首頁  >  文章  >  後端開發  >  Golang禁止IP頻繁存取的實作方法

Golang禁止IP頻繁存取的實作方法

PHPz
PHPz原創
2023-04-25 09:10:491167瀏覽

在應用程式開發中,禁止頻繁存取是關鍵的安全措施,可以幫助你防範各種攻擊,例如DDOS攻擊。本文將介紹如何使用Golang編寫一個簡單的程序,來禁止IP位址的頻繁存取的實作方法。

實現想法

禁止IP位址的頻繁存取的實作方法主要是透過限制每個IP位址存取的次數來實現。具體想法如下:

  1. 建立一個map,用來記錄每個IP位址存取的次數。
  2. 當一個IP位址存取我們的應用程式時,在map中增加該IP位址的計數器的值。
  3. 如果我們發現該IP位址的計數器已經超過了指定的限制次數,就把該IP位址列入黑名單,禁止存取我們的應用程式。
  4. 可以設定計數器的逾時時間,以確保IP位址的黑名單不會持續太久。

程式碼實作

下面是一個使用Golang實作上述想法的程式碼範例:

package main

import (
    "fmt"
    "net"
    "sync"
    "time"
)

const (
    MaxRequestsPerIP = 10      // 每个IP最大请求数
    BlacklistTimeout = 60 * 5  // 黑名单超时时间(秒)
)

type IPRequests struct {
    Requests   int       // 请求计数器
    LastAccess time.Time // 最后一次访问时间
}

var (
    lock         sync.RWMutex
    ipRequestMap = make(map[string]*IPRequests)
    blacklist    = make(map[string]time.Time)
)

// 判断IP是否在黑名单内
func isBlacklisted(ip string) bool {
    lock.RLock()
    defer lock.RUnlock()
    if blacklistedTime, ok := blacklist[ip]; ok {
        if time.Since(blacklistedTime) < time.Second*BlacklistTimeout {
            return true
        } else {
            // 超时,从黑名单中删除 
            lock.Lock()
            delete(blacklist, ip)
            lock.Unlock()
        }
    }
    return false
}

// 记录IP访问次数
func recordIPRequest(ip string) {
    lock.Lock()
    defer lock.Unlock()
    req, ok := ipRequestMap[ip]
    if !ok {
        req = &IPRequests{}
        ipRequestMap[ip] = req
    }
    req.Requests++
    req.LastAccess = time.Now()
    // 如果IP访问次数过多,将其列入黑名单
    if req.Requests > MaxRequestsPerIP {
        blacklist[ip] = time.Now()
    }
}

// 启动HTTP服务器
func StartHttpServer() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        ip, _, _ := net.SplitHostPort(r.RemoteAddr)
        // 如果IP地址在黑名单内,则拒绝访问
        if isBlacklisted(ip) {
            http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
            return
        }
        // 记录IP地址的访问次数
        recordIPRequest(ip)
        // 处理请求
        fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
    })
    http.ListenAndServe(":8080", nil)
}

func main() {
    StartHttpServer()
}

如上程式碼中,我們使用了一個map(ipRequestMap)來記錄每個IP位址存取的次數,一個map(blacklist)來儲存黑名單資訊。當IP位址存取我們的應用程式時,我們先檢查該IP位址是否在黑名單內,如果在則回傳403禁止存取。如果不在,則記錄該IP位址的造訪次數。當IP位址存取的次數超過了指定的閾值(MaxRequestsPerIP)時,我們就把該IP位址列入黑名單,禁止存取我們的應用程式。

在 isBlacklisted() 函式中,我們判斷某個IP是否在黑名單內。如果是,則傳回 true,告訴 StartHttpServer() 函數我們應該拒絕該IP的請求。同時,如果這個IP已經超過黑名單的時長(BlacklistTimeout),則從黑名單中刪除。

在recordIPRequest()函數中,我們用RWMutex(RW互斥鎖)來確保並發安全。此函數用於記錄IP位址存取的次數,如果該IP達到了我們設定的限制,就將其列入黑名單中。

總結

使用 Golang 禁止 IP 頻繁存取的方法很簡單。我們只需要實作一個計數器和一個黑名單。但是在實際中,我們需要根據自己的需求設定合適的閾值。在本文的範例中,我們使用了最大請求數(MaxRequestsPerIP)和黑名單逾時時間(BlacklistTimeout)兩個閾值。在實際中,你可以根據具體情況設定更合適的閾值。

以上是Golang禁止IP頻繁存取的實作方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn