nginx ip ブラックリストの動的禁止の例

nginx ip ブラックリストの動的禁止の例

ウェブサイトが悪意を持ってリクエストされた場合、IP アドレスをブラックリストに登録することは重要な対策です。リクエストをブラックリストに登録するたびに nginx を設定しなければならないのであれば、それは低すぎます。nginx IP ブラックリストをより便利に制御する必要があります。

1. 解決策

ブラックリストは MySQL に保存されます (一般的なソリューションは Redis ですが、有効期間が異なるさまざまな IP 設定、IP CRUD、統計などの制御には役立ちません)。

lua-nginx-module を通じて、nginx でメモリ ブロック (lua_shared_dict) が開かれ、lua は定期的に mysql から lua_shared_dict へのブラックリストを更新します。

すべてのリクエストは、lua_shared_dict 内の IP と照合する必要があります。

2. インストール

2.1 luajitをインストールする

LuaJIT-2.0.5 をCDに追加
作る
PREFIX=/usr/local/luajit をインストールします

2.2. nginxをインストールするときに、luaモジュールをコンパイルします。

LUAJIT_LIB=/usr/local/luajit/lib をエクスポートします。
LUAJIT_INC=/usr/local/luajit/include/luajit-2.1 をエクスポートします。
 
./configure --prefix=/nginx \
--with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" \
--add-module=/opt/ngx_devel_kit-0.3.1rc1 \
--add-module=/opt/lua-nginx-module-0.10.14rc3
 
-j2 を実行します
インストールする
nginx は sbin にあります。

3. 構成

3.1 nginxの設定

http {
  server_tokens オフ;
  lua_package_path "/usr/local/lib/lua/?.lua;;";
  lua_shared_dict ip_blacklist 4m;
}
 
サーバー{
  $real_ip $remote_addr を設定します。
  $http_x_forwarded_for が "^(\d+\.\d+\.\d+\.\d+)" の場合 {
    $real_ip を $1 に設定します。
  }
 
  # 管理情報、この URL にアクセスして nginx の IP ブラックリスト情報を表示します location /get-ipblacklist-info {
    アクセス_by_lua_file conf/lua/get_ipblacklist_info.lua;
  }
 
  # URL を同期し、スケジュールされたタスクを通じて URL を呼び出し、mysql から nginx の場所 /sync-ipblacklist { への IP ブラックリストのスケジュールされた更新を実装します。
   アクセス_by_lua_file conf/lua/sync_ipblacklist.lua;
  }
 
  # 本番ドメイン名の設定、IPブラックリスト制御が必要なすべての場所に次のステートメントを含める必要があります location / {
   lua ファイルによるアクセス conf/lua/check_realip.lua;
  }
 
}

nginxサーバーは次のcrrontabを設定します

* * * * * /usr/bin/curl -o /dev/null -s http://127.0.0.1/sync-ipblacklist > /dev/null 2>&1

3.2 Luaスクリプト

sync_ipblacklist.lua

local mysql_host = "mysql サーバーの IP"
ローカル mysql_port = 3306
ローカルデータベース = "dbname"
ローカルユーザー名 = "user"
ローカルパスワード = "password"
 
--cache_ttl 秒ごとに mysql から ip_blacklist を更新します
ローカルcache_ttl = 1
ローカル mysql_connection_timeout = 1000
 
ローカル client_ip = ngx.var.real_ip
ローカル ip_blacklist = ngx.shared.ip_blacklist
ローカル last_update_time = ip_blacklist:get("last_update_time");
 
last_update_time == nil または last_update_time < ( ngx.now() - cache_ttl ) の場合
 
 ローカル mysql = "resty.mysql" を必要とします。
 ローカル red = mysql:new();
 
 赤:set_timeout(mysql_connect_timeout);
 
 ローカル OK、エラー、エラーコード、SQL 状態 = 赤:接続{
     ホスト = mysql_host、
     ポート = mysql_port、
     データベース = データベース、
     ユーザー = ユーザー名、
     パスワード = パスワード、
     文字セット = "utf8"、
     最大パケットサイズ = 1024 * 1024、
    }
 大丈夫でなければ
 ngx.log(ngx.ERR, "ip_blacklist の取得中に mysql 接続エラーが発生しました: " .. err);
 それ以外
 new_ip_blacklist、err、errcode、sqlstate = red:query("ip_blacklist から ip_addr を選択、ステータス = 0、create_time で順序付け、desc 制限 10000、100")
 new_ip_blacklistでない場合は
  ngx.log(ngx.ERR, "不正な結果。errcode: " .. errcode .. " sqlstate: " .. sqlstate .. " err: " .. err);
  戻る
 終わり
 
 ip_blacklist:flush_all();
 k1、v1のペア(new_ip_blacklist)に対して
  k2、v2のペア(v1)では
  ip_blacklist:set(v2,true);
  終わり
 終わり
 
 ip_blacklist:set("last_update_time", ngx.now());
 終わり
終わり
 
ngx.say("同期が成功しました");

get_ipblacklist_info.lua

-- ブラックリスト情報を表示するには URL を呼び出します -- 10,000 個の IP は 150 万個未満の ngx.shared メモリを消費します -- すべての KEY を取得すると、他の通常のリクエストが ngx.shared メモリにアクセスするのがブロックされるため、いくつかのキーのみを表示できます "resty.core.shdict" が必要です
ngx.say("合計容量: " .. ngx.shared.ip_blacklist:capacity() .. "<br/>");
ngx.say("空き領域: " .. ngx.shared.ip_blacklist:free_space() .. "<br/>");
ngx.say("最終更新時刻: " .. os.date("%Y%m%d_%H:%M:%S",ngx.shared.ip_blacklist:get("last_update_time")) .. "<br/>");
ngx.say("最初の100個のキー: <br/>");
ngx.say("--------------------------<br/>");
ip_blacklist = ngx.shared.ip_blacklist:get_keys(100);
キーと値のペア(ip_blacklist)の場合
 ngx.say(キー .. ": " .. 値 .. "<br/>");
終わり

チェック_realip.lua

ngx.shared.ip_blacklist:get(ngx.var.real_ip) の場合
 ngx.exit(ngx.HTTP_FORBIDDEN) を返します。
終わり

3.3 データベース設計

テーブル `ip_blacklist` を作成します (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `ip_addr` varchar(15) COLLATE utf8mb4_bin デフォルト NULL,
 `status` int(11) デフォルト '0' コメント '0: 有効、1: 無効',
 `effective_hour` 小数点(11,2) デフォルト '24' コメント '有効期間、単位: 時間',
 `ip_source` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'ブラックリストソース',
 `create_time` 日時 DEFAULT CURRENT_TIMESTAMP、
 `modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP、
 `remark` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '注釈',
 主キー (`id`)
) エンジン=InnoDB デフォルト文字セット=utf8mb4 COLLATE=utf8mb4_bin;
 
 
プロシージャ proc_ip_blacklist_status_update() を作成します。
-- 期限切れのIPステータスを無効に変更する 
 ip_blacklist を更新
 ステータスを1に設定
 date_add(create_time,INTERVAL effective_hour hour) < now(); の場合
 専念;
終わり;
 
 
イベントの作成 job_ip_blacklist_status_update
スケジュールどおり1分ごとに
完了時に保存
有効にする
する
proc_ip_blacklist_status_update() を呼び出します。

4 CRUD

ブラックリストは、手動、自動、また​​はその両方で生成できます。

自動的な方法は、Python を介して elk ログを分析し、悪意のある IP を MySQL に自動的に書き込むことです。これは大きなトピックなので、ここでは説明しません。

手動の方法では、elk リクエスト ログを手動で確認し、悪意のある IP を見つけて、mysql に手動で入力します。これは、優れたユーザー エクスペリエンスを備えたオープン ソースの CRUD ツールです (直接 Navicat を使用するよりもはるかに優れています)。もちろん、自分で作成することもできます...

プロジェクトアドレス: https://github.com/jonseg/crud-admin-generator

このプロジェクトの強みは、すべてのテーブルがメニューの生成に役立ち、これらのテーブルの CRUD を直接使用できることです。

具体的な操作については公式のマニュアルを参照していただくとして、ここでは詳細には触れません。

上記のnginx ip blacklist dynamic banの例は、エディターがあなたと共有するすべてのコンテンツです。参考になれば幸いです。また、123WORDPRESS.COMをサポートしていただければ幸いです。

以下もご興味があるかもしれません:
  • Nginxを再コンパイルしてモジュールを追加する方法
  • NginxはURLのパスに応じてアップストリームに動的に転送します
  • NginxはLua+Redisを使用してIPを動的にブロックします
  • Nginx ダイナミック DNS リバース プロキシの書き方をいくつか詳しく説明します
  • Nginxにモジュールを動的に追加する方法

<<:  JavaScript で大きなファイルの並列ダウンロードを実装する方法

>>:  mysql 5.7.23 winx64 解凍バージョンのインストールチュートリアル

推薦する

MySQLデータを復元する2つの方法

1. はじめに少し前、開発者がテスト環境や本番環境で誤った操作をし、データベースを誤って削除/更新し...

高品質なウェブページのデザイン方法 高品質なウェブページ(画像とテキスト)のデザイン経験

オープンプラットフォームの増加に伴い、そこから派生するさまざまなアプリケーションサービスも増加傾向に...

Vueはフォーム検証機能を実装します

この記事では主に、NUXT の validate メソッドに基づいてフォーム検証を実装する方法につい...

bash を使って日付をカウントダウンする方法

重要なイベントまであと何日あるか知りたいですか? Linux bash と date コマンドが役に...

MySQL 5.7 でルートパスワードを忘れた後に変更する方法の詳細なチュートリアル

序文長い間、MySQL のアプリケーションおよび学習環境は MySQL 5.6 以前のバージョンであ...

HTML ページジャンプコード

次のコードを index.html などのデフォルトのホームページ ファイルとして保存し、ルート デ...

カタツムリ映画システムのDocker展開の詳細なプロセス分析

環境に関する声明ホストOS: Cetnos7.9 最小インストールdocker バージョン: 20....

JavaScript を使用して二分探索木を実装する方法

コンピュータ サイエンスで最も一般的に使用され、議論されているデータ構造の 1 つは、二分探索木です...

サブクエリ最適化における MySQL 選択の実装

以下のデモはMySQLバージョン5.7.27に基づいています。 1. MySQLサブクエリ最適化戦略...

secure_file_priv nullの問題を解決する

secure_file_priv = ' ';管理者としてcmdを実行します。 my...

ウェブインターフェースデザインでウェブサイトのスタイルガイドを作成する方法(画像とテキスト付き)

スタイル ガイドとは何でしょうか? 簡単に言えば、ストーリーを伝える方法を説明するドキュメントです。...

Vueはシンプルなショッピングカートの例を実装します

この記事では、Vueの具体的なコードを共有して、簡単なショッピングカートを実装します。具体的な内容は...

MySQL json 形式のデータクエリ操作

デフォルトのテーブル名はbase_dataで、json列名はjson_valueです。 json_v...

Zabbix動的実行監視収集スクリプトの実装原理

Zabbix カスタム スクリプトを使用して監視データを収集する場合、通常、次の問題が発生します。サ...

Python で pymysql モジュールを使用して MySQL データベースに接続する

pymysqlをインストールするpip install pymysql 2|0pymysqlの使用2...