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 解凍バージョンのインストールチュートリアル

推薦する

HTMLフォーム要素の詳しい解説(パート2)

HTML 入力属性値属性value 属性は、入力フィールドの初期値を指定します。 <フォーム...

Vue コンポーネント ライブラリ ElementUI はテーブル読み込みツリー データのチュートリアルを実装します

ElementUIは、参考のためにテーブルツリーリストの読み込みチュートリアルを実装しています。具体...

Vue は無限ロードウォーターフォールフローを実装します

この記事では、参考までに、無限ロードウォーターフォールフローを実現するためのVueの具体的なコードを...

ウェブページの画像を素早く表示する方法とテクニック

1. .jpg ではなく .gif を使用します。GIF は JPG に比べてサイズが小さくなります...

docker pull imageエラーの問題を解決する

説明する: Windows 10 に VM をインストールし、VM で Docker を実行し、Do...

layui をベースにしたログインページの実装

この記事の例では、ログインページを実装するためのlayuiの具体的なコードを参考までに共有しています...

CSS最適化スキルの自己実践体験

1. CSS スプライトを使用します。利点は、CSS で使用される小さな画像を 1 つの大きな画像に...

Linux ホスト上で複数の MySQL データベースを起動する方法

今日は、Linux ホスト上で 4 つの MySQL データベースを起動する方法について説明します。...

MySQL 数十億のデータのインポート、エクスポート、移行に関するメモ

最近はMySQLのメモをたくさん取っていますが、それは主に会社のOracleが比較的安定していてメン...

MySQLのスリープ関数の特殊現象例の詳しい説明

序文MySQL のスリープ システム機能は、実用的な適用シナリオが少なく、通常は実験的なテストに使用...

JavaScript の new 演算子の原理と例の詳細な説明

新しい用途new の機能は、コンストラクターを通じてインスタンス オブジェクトを作成することです。イ...

Vueは商品詳細ページの虫眼鏡機能を実装します

この記事では、商品詳細ページの虫眼鏡を実装するためのVueの具体的なコードを参考までに共有します。具...

JavaScript デザインパターン 責任連鎖パターン

目次概要コードの実装パラメータ定義成し遂げる責任連鎖パターンの実装改善概要責任チェーン パターンは、...

Vue フロントエンドと Django バックエンドを使用して、一定期間内のデータをクエリする方法

序文開発プロセスでは、すべてのデータではなく特定の期間内のデータをクエリするなど、クエリのフィルタリ...

Viteプロジェクトを作成する手順

目次序文yarn create は何をしますか?ソースコード分析プロジェクトの依存関係テンプレート構...