Nginx をベースに特定の IP への短期アクセス数を制限する

Nginx をベースに特定の IP への短期アクセス数を制限する

特定の期間内に特定の IP へのアクセス回数を制限する方法は、特に悪意のある DDOS 攻撃に直面している場合には頭痛の種となります。その中で、CC攻撃(Challenge Collapsar)はDDOS(分散型サービス拒否)の一種であり、一般的なウェブサイト攻撃手法でもあります。攻撃者はプロキシサーバーやゾンビサーバーを介して被害者ホストに大量のデータパケットを継続的に送信し、相手側のサーバーリソースを枯渇させてクラッシュさせます。

CC 攻撃では通常、限られた数の IP アドレスを使用して、サーバーに頻繁にデータを送信し、攻撃の目的を達成します。Nginx は、HttpLimitReqModule および HttpLimitZoneModule 構成を通じて、同じ期間内の IP アドレスへのアクセス回数を制限することで、CC 攻撃を防ぐことができます。

HttpLimitReqModule は、単位時間あたりの接続数を制限するために使用されるモジュールです。limit_req_zone 命令と limit_req 命令を組み合わせて使用​​して制限を実現します。同時接続数が指定数を超えると、503 エラーが返されます。

HttpLimitConnModule は、limit_zone および limit_conn ディレクティブを使用して、単一の IP アドレスに対する同時接続数を制限するために使用されます。

これら 2 つのモジュールの違いは、HttpLimitReqModule は一定期間内の接続数を制限するのに対し、HttpLimitConnModule は同時接続数を制限する点です。

HttpLimitReqModulは、一定期間内に同じIPアドレスからのアクセス回数を制限します。

http{
  ...
  # セッションを保存するための、10M のメモリ サイズを持つ allips という名前の limit_req_zone を定義します。
  # $binary_remote_addr をキーとして使用し、1 秒あたりの平均リクエスト数を 20 に制限します。
  #1Mは16000の状態を保存でき、reteの値は整数でなければなりません。
  #2秒あたり1回のリクエストを制限する場合は、30r/mに設定できます
  limit_req_zone $binary_remote_addr ゾーン=allips:10m レート=20r/s;
  ...
  サーバ{
    ...
    位置 {
      ...

      #各IPを1秒あたり20リクエスト以下に制限し、リークバケットのバースト数は5です
      #brustは、1秒目、2秒目、3秒目、4秒目のリクエスト数が19の場合、
      #5 秒間に 25 件のリクエストが許可されます。
      #ただし、最初の 1 秒間に 25 件のリクエストを送信し、次の 1 秒間に 20 件を超えるリクエストを送信すると、503 エラーが返されます。
      #nodelay、このオプションが設定されていない場合、平均レートが厳密に使用され、リクエスト数が制限されます。
      #最初の 1 秒間に 25 件のリクエストがあった場合、次の 1 秒間に 5 件のリクエストが実行されます。
      #nodelay を設定すると、最初の 1 秒間に 25 件のリクエストが実行されます。

      limit_req ゾーン=allips バースト=5 ノードレイ;
      ...
    }
    ...
  }
  ...
}

HttpLimitZoneModuleは同時接続数を制限します

limit_zone は http スコープでのみ定義でき、limit_conn は http サーバーの場所スコープで定義できます。

http{
  ...
  #セッションを保存するために、メモリ サイズが 10M の one という名前の limit_zone を定義します。
  #$binary_remote_addrをキーとして使用
  #nginx 1.18以降では、limit_connはlimit_conn_zoneに置き換えられました
  #http スコープにのみ配置可能 limit_conn_zone one $binary_remote_addr 10m; 
  ...
  サーバ{
    ...
    位置 {
      ...
      limit_conn one 20; #接続制限#帯域幅制限、単一接続の数を制限します。1つのIPに2つの接続がある場合は、500x2kになります。
      制限レート 500k;      
      ...
    }
    ...
  }
  ...
}

nginx ホワイトリスト設定

上記の設定では、すべての IP が制限されます。検索エンジン スパイダーや独自のテスト IP を制限したくない場合もあります。
特定のホワイトリスト IP の場合は、geo コマンドを使用して実現できます。

1.

http{
   地域限定{
    デフォルト 1;
    #グーグル
    64.233.160.0/19 0;
    65.52.0.0/14 0;
    66.102.0.0/20 0;
    66.249.64.0/19 0;
    72.14.192.0/18 0;
    74.125.0.0/16 0;
    209.85.128.0/17 0;
    216.239.32.0/19 0;
    #M$
    64.4.0.0/18 0;
    157.60.0.0/16 0;
    157.54.0.0/15 0;
    157.56.0.0/14 0;
    207.46.0.0/16 0;
    207.68.192.0/20 0;
    207.68.128.0/18 0;
    #ヤフー
    8.12.144.0/24 0;
    66.196.64.0/18 0;
    66.228.160.0/19 0;
    67.195.0.0/16 0;
    74.6.0.0/16 0;
    68.142.192.0/18 0;
    72.30.0.0/16 0;
    209.191.64.0/18 0;
    #私のIP
    127.0.0.1/32 0;
    123.456.0.0/28 0; #サーバーCIDRの例
  }

geo ディレクティブは、デフォルト値が 1 のホワイトリスト $limit 変数を定義します。クライアント IP が上記の範囲内にある場合、$limit の値は 0 になります。

2. map コマンドを使用して、検索エンジン クライアントの IP を空の文字列にマップします。検索エンジンでない場合は、実際の IP が表示されます。このようにすると、検索エンジンの IP は limit_req_zone メモリ セッションに保存されないため、検索エンジンの IP アクセスは制限されません。

マップ $limited $limit {
1 $バイナリリモートアドレス;
0 "";
}

3. limit_req_zoneとlimit_reqを設定する

limit_req_zone $limit zone=foo:1m レート=10r/m;

limit_req ゾーン=foo バースト=5;

最後に、ab を使用して php-fpm を圧縮し、上記の方法の効果をテストします。

例 1: 構成へのアクセス数を 1 分あたり 60 回 (平均 1 秒あたり 1 回) に制限します。

まずPHPスクリプトを準備し、ルートディレクトリ$document_rootに配置します。

テスト

<?
($i=0; $i < 1000; $i++) の場合
「Hello World」をエコーし​​ます。
?>

Nginx設定にlimit_req_zoneとlimit_reqが追加されました

http{
  ...
  limit_req_zone $binary_remote_addr ゾーン=allips:10m レート=60r/m;
  ...
  サーバ{
    ...
    位置 {
      ...
      limit_req ゾーン=allips;
      ...
    }
    ...
  }
  ...
}
# ab -n 5 -c 1 http://blog.rekfan.com/test.php
127.0.0.1- - [2012/12/22:06:27:06 +0000] "GET /test.php HTTP/1.0" 200 11000 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:06:27:06 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:06:27:07 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:06:27:07 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:06:27:07 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"

brust と nodelay を設定しないと、この構成では 1 秒あたり 1 つのアクセスのみが許可され、この制限を超えるリクエストでは 503 エラーが返されることがわかります。

http{
  ...
  limit_req_zone $binary_remote_addr ゾーン=allips:10m レート=60r/m;
  ...
  サーバ{
    ...
    位置 {
      ...
      limit_req ゾーン=allips バースト=1 ノードレイ;
      ...
    }
    ...
  }
  ...
}

# ab -n 5 -c 1 http://blog.rekfan.com/test.php
127.0.0.1- - [2012/12/22:07:01:00 +0000] "GET /test.php HTTP/1.0" 200 11000 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:07:01:00 +0000] "GET /test.php HTTP/1.0" 200 11000 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:07:01:01 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:07:01:01 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"
127.0.0.1 - - [2012/12/22:07:01:01 +0000] "GET /test.php HTTP/1.0" 503 537 "-" "Rekfan_Server/1.2.6"

brust=1 および nodelay を設定すると、最初の 1 秒間に 2 つのリクエストを処理できるようになります。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • nginx 基本チュートリアル
  • Nginx 設定入門チュートリアル
  • Windows での nginx HTTP サーバーの入門チュートリアル
  • Nginx ロードバランシングとは何か、そしてそれをどのように設定するか
  • Nginx 最適化サービスで Web ページ圧縮を実装する方法
  • nginx を最適化する 6 つの方法
  • Nginx がフロントエンド リソースへのクロスドメイン アクセスの問題をどのように解決するかの詳細な説明
  • proxy_pass を設定した後に Nginx が 404 を返す問題を解決する
  • Nginx の構成と HTTP 実装コード分析との互換性
  • Nginx サービス クイック スタート チュートリアル

<<:  フロントエンドの状態管理(パート 1)

>>:  HTML テーブルタグチュートリアル (17): テーブルタイトルの垂直配置属性 VALIGN

推薦する

ボタンをクリックした後のCSS読み込み効果を実現する

自社製品にクリック後1~2秒待機時間があるボタン(確認メールを送信する)があるため、クリック後の1~...

DockerにMySQL 8.0をインストールする方法

環境: MacOS_Cetalina_10.15.1、Mysql8.0.18、Docker_2.0....

表に斜めヘッダー効果を出す5つの方法

誰もがテーブルをよく知っているはずです。コード内でよく見かけます。テーブルにスラッシュ ヘッダーを追...

Vue.js フロントエンド Web ページ ポップアップ非同期動作例の分析

目次1. 序文2. ポップアップコンポーネントを2つ見つける3. 自分で作る3.1. Promise...

Linux centos7 に phpMyAdmin をインストールするチュートリアル

yum install httpd php mariadb-server –yランプの動作環境を設定...

ウェブサイトのパフォーマンスを向上させるためのウェブサーバーの改善

<br />このシリーズの最初のセクションでは、Web サイトのパフォーマンスを向上させ...

Zabbix はどのようにして ssh 経由でネットワーク デバイス データを監視および取得するのでしょうか?

シナリオシミュレーション:ある会社の運用保守担当者は、以前購入した一連のネットワーク機器の光ポートの...

JavaScript でロジック判定コードを最適化する方法

序文日常生活で使用する論理的判断文には、if...else...、switch...case...、...

プロジェクトのフロントエンドとバックエンドでの Echart チャートの使用に関する詳細な説明

目次序文1. プロジェクトアーキテクチャ2. Echart公式サイトにアクセスして自己分析を学ぶ2....

Chrome プラグイン (拡張機能) 開発ガイド (完全デモ)

目次前面に書かれた序文ChromeプラグインとはChrome プラグイン開発を学ぶことの意義は何です...

Dockerコンテナの操作手順の概要と詳細説明

1. コンテナを作成して実行するdocker run -it --rm centos:latest ...

Nginx でバージョン番号を隠す方法

Nginx はバージョン番号を非表示にする実稼働環境では、セキュリティ上の脆弱性の漏洩を避けるために...

Linux Zabbixカスタム監視およびアラーム実装プロセスの分析

ターゲットzabbix フロントエンド監視の iostat コマンドでデータの 1 つを表示します。...

JavaScript ではおそらく switch 文を使う必要はない

目次スイッチも複雑なコードブロックもありませんPythonからのインスピレーション辞書を使用してスイ...

簡単な計算機を実装する小さなプログラム

この記事の例では、簡単な計算機を実装するための小さなプログラムの具体的なコードを参考までに共有してい...