Golang で頻繁な IP アクセスの禁止を実装する方法

PHPz
リリース: 2023-04-25 10:24:39
オリジナル
1165 人が閲覧しました

アプリケーション開発では、頻繁なアクセスを禁止することが重要なセキュリティ対策であり、DDOS 攻撃などのさまざまな攻撃を防ぐことができます。この記事では、Golangを使ってIPアドレスへの頻繁なアクセスを禁止する簡単なプログラムを書く方法を紹介します。

実装アイデア

IPアドレスへの頻繁なアクセスを禁止する実装方法は、主にIPアドレスごとのアクセス数を制限することで実現します。具体的なアイデアは次のとおりです。

  1. マップを作成して、各 IP アドレスへのアクセス数を記録します。
  2. IP アドレスがアプリケーションにアクセスするときは、マップ内の 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()
}
ログイン後にコピー

上記のコードでは、マップ (ipRequestMap) を使用します。各 IP アドレスへの訪問数を記録し、ブラックリスト情報を保存するマップ (ブラックリスト)。 IP アドレスがアプリケーションにアクセスすると、まずその IP アドレスがブラックリストにあるかどうかを確認し、ブラックリストに含まれている場合は 403 Access Forbidden を返します。そうでない場合は、IP アドレスへのアクセス数を記録します。 IP アドレスへのアクセス数が指定されたしきい値 (MaxRequestsPerIP) を超えると、その IP アドレスがブラックリストに登録され、アプリケーションへのアクセスが禁止されます。

isBlacklisted() 関数では、IP がブラックリストに含まれているかどうかを判断します。その場合は true を返し、その IP からのリクエストを拒否する必要があることを StartHttpServer() 関数に伝えます。同時に、IP がブラックリストのタイムアウト (BlacklistTimeout) を超えた場合は、ブラックリストから削除されます。

recordIPRequest() 関数では、同時実行の安全性を確保するために RWMutex (RW ミューテックス ロック) を使用します。この機能は、IP アドレスへのアクセス回数を記録するために使用され、IP が当社が設定した制限に達すると、ブラックリストに登録されます。

概要

Golang を使用して頻繁な IP アクセスを禁止する方法は非常に簡単です。実装する必要があるのは、カウンターとブラックリストだけです。しかし実際には、私たち自身のニーズに応じて適切なしきい値を設定する必要があります。この記事の例では、リクエストの最大数 (MaxRequestsPerIP) とブラックリストのタイムアウト (BlacklistTimeout) という 2 つのしきい値を使用します。実際には、特定の状況に応じて、より適切なしきい値を設定できます。

以上がGolang で頻繁な IP アクセスの禁止を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート