Lua モジュールを使用して WAF を実装する Nginx の原理の分析

Lua モジュールを使用して WAF を実装する Nginx の原理の分析

はじめに: 最近は暗号化データ関数を書いていますが、セキュリティの知識がまだ不足しています。偶然WAF関連の知識に触れました。偶然NginxでWAF機能を実現できることがわかりました。Lua言語も少し学びました。共有してください

1. WAFの背景

かつて、企業は通常、セキュリティの第一防衛線としてファイアウォールを使用していました。当時のファイアウォールは、第 3 層 (ネットワーク層) で一部のデータ パケットを効果的にブロックするだけでした。しかし、Web アプリケーションがますます多機能になるにつれて、Web サーバーは強力なコンピューティング能力、処理性能、および高い価値により、攻撃の主なターゲット (第 7 層、アプリケーション層) になりました。しかし、従来のファイアウォールではアプリケーションの脆弱性を悪用した攻撃を防ぐことはできません。そこで登場したのがWAF(Webアプリケーションファイアウォール)です。

2. WAFとは

Web アプリケーション ファイアウォール (WAF) は、クロスサイト スクリプティング (XSS)、SQL インジェクション、Cookie ポイズニングなどのさまざまなアプリケーション層攻撃から Web アプリケーションを保護するように設計されています。アプリケーションは重要なデータへのゲートウェイであるため、アプリケーションに対する攻撃が脆弱性の主な原因となります。 WAF を使用すると、システムに侵入してデータを漏洩しようとする一連の攻撃をブロックできます。

3. 動作原理

1. ユーザーはブラウザを通じて Web ページ要求を Web サーバーに送信します。

2. ユーザーのリクエストがWebサーバーに到達する前に、WAFはユーザーのリクエストをフィルタリングします。

3. WAF はユーザーの HTTP リクエスト パラメータを取得し、設定ファイルで定義されたルール (IP ブラックリストなど) と比較します。一致が見つかった場合は 403 拒否が返され、一致しない場合はリクエストが許可されます。

4. WEB サーバーはユーザーの要求に応答し、ページデータをユーザーに返します。

4. WAF機能

WAF は、HTTP/HTTPS に対して一連のセキュリティ ポリシーを実行することで、Web アプリケーションを保護する製品です。

5. WAFと従来のファイアウォールの違い

1. 従来のファイアウォールはネットワーク層(レイヤー3)とトランスポート層(レイヤー4)で動作します。

2.WAFはアプリケーション層(レイヤー7)で動作します

3. 従来のファイアウォールはIPとポートをフィルタリングする

4.WAF は、URL、IP、User-Agent などの HTTP リクエストをフィルタリングします。

6. WAFとDDos

DDos の正式名称は、分散型サービス拒否攻撃です。これは主に、コンピューターのグループが単一のターゲット システムへの要求を開始することに依存しており、ターゲット システムのリソースが使い果たされ、通常の要求が拒否されることになります。

OSI ネットワーク モデルによれば、最も一般的な DDos の種類は、レイヤー 3 (ネットワーク層) DDos、レイヤー 4 (トランスポート層) DDos、レイヤー 7 (アプリケーション層) DDos の 3 つです。

WAF は主にレイヤー 7 DDos 攻撃に対処し、レイヤー 7 DDos 攻撃に対処する他の保護手段よりも効率的です。 WAF は HTTP トラフィックの詳細な分析を実行して、通常のアクセス要求をモデル化し、これらのモデルを使用して通常の要求と、ロボットやスクリプトを使用する攻撃者によってトリガーされた要求を区別します。

7. Nginx WAF機能

  • IP ホワイトリストとブラックリスト機能をサポートし、ブラックリストに登録された IP へのアクセスを直接拒否します (新しく追加された cdip 機能は IP セグメントをサポートします)
  • フィルタリングする必要のないURLを定義するURLホワイトリストをサポート
  • ユーザーエージェントフィルタリングをサポートし、カスタムルールのエントリを照合して処理します。
  • CC 攻撃保護をサポートし、指定時間内に単一の URL へのアクセス回数が設定値を超えると保護されます (異なるドメイン名に新しく追加)
  • クッキーフィルタリング、カスタムルールのエントリのマッチング、そして処理をサポートします
  • URLフィルタリングをサポートし、カスタムルールのエントリを照合します。ユーザーが要求したURLにこれらが含まれている場合
  • URLパラメータフィルタリングをサポートします。原理は上記と同じです。
  • ログ記録をサポートし、拒否されたすべての操作をログに記録します。
  • ブラックリストキャッシュのサポートを追加しました(デフォルトは600秒)

8. Nginx Waf保護プロセス

whiteip() の場合
そうでない場合は、blockip() を実行して
そうでない場合は、denycc() を実行して
そうでない場合は、ngx.var.http_Acunetix_Aspect
ngx.終了(444)
そうでない場合は、ngx.var.http_X_Scan_Memo
ngx.終了(444)
そうでない場合はwhiteurl()
そうでない場合はua()
そうでない場合はurl()
elseif args() の場合
そうでない場合はcookie()
そうでない場合は、PostCheck

  • IP ホワイトリストを確認し、合格した場合は検出されません。
  • IP ブラックリストをチェックし、失敗した場合は拒否します。
  • CC攻撃をチェックし、一致した場合は拒否する
  • http_Acunetix_Aspectスキャンが有効になっているか確認する
  • http_X_Scan_Memo スキャンが有効になっているか確認する
  • ホワイトリストのURLチェックをチェックします。
  • UA をチェックし、UA が失敗した場合は拒否します。
  • URLパラメータのチェックを確認します。
  • クッキーを確認します。
  • 投稿を確認してください。

9. Nginx ベースの WAF

9.1 依存パッケージをインストールする

yum -y gccをインストール gcc-c++ autoconf automake make unzip
yum -y インストール zlib zlib-devel openssl openssl-devel pcre pcre-devel

9.2 LuaJIT2.0をインストールする

LuaJIT は Lua のジャストインタイム コンパイラです。簡単に言えば、LuaJIT は効率的な Lua 仮想マシンです。

# ディレクトリに入る cd /usr/local/src/
 
# LuaJIT2.0をダウンロード
http://luajit.org/download/LuaJIT-2.0.5.tar.gz をダウンロードしてください
 
# 解凍 tar xf LuaJIT-2.0.5.tar.gz && cd LuaJIT-2.0.5
 
# コンパイルする
 
# インストール make install PREFIX=/usr/local/lj2
 
# ソフトリンクを作成 ln -s /usr/local/lj2/lib/libluajit-5.1.so.2 /lib64/
 
# 環境変数を追加 export LUAJIT_LIB=/usr/local/lj2/lib/
LUAJIT_INC=/usr/local/lj2/include/luajit-2.0/ をエクスポートします。

9.3 ngx_devel_kitをインストールする

キットモジュールは、nginxサーバーのコア機能を拡張するモジュールです。これをベースにサードパーティのモジュール開発を迅速に実装できます。

# ディレクトリに入る cd /user/local/src/
 
# v0.3.0.tar.gz をダウンロード
https://github.com/simplresty/ngx_devel_kit/archive/v0.3.0.tar.gz -O ngx_devel_kit.tar.gz を取得します。
 
# tar xf ngx_devel_kit.tar.gz を解凍します

9.4 lua-nginx-moduleをインストールする

ngx_lua_module は、lua パーサーを nginx に埋め込み、lua 言語で記述された Web バックエンド スクリプトを解析および実行する nginx http モジュールです。

ngx_luaモジュールの原理

1. 各ワーカー (ワークプロセス) は Lua VM を作成し、ワーカー内のすべてのコルーチンは VM を共有します。
2. Nginx I/O プリミティブをカプセル化して Lua VM に挿入し、Lua コードが直接アクセスできるようにします。
3. 各外部リクエストは Lua コルーチンによって処理され、コルーチン間のデータは分離されます。
4. Lua コードが I/O 操作などの非同期インターフェースを呼び出すと、ワーカーをブロックせずに現在のコルーチンを一時停止し (コンテキスト データを保護します)、
5. I/Oなどの非同期操作が完了すると、関連するコルーチンコンテキストデータが復元され、操作が続行されます。

インストール

# ディレクトリに入る cd /user/local/src/
 
# v0.10.9rc7.tar.gz をダウンロード
https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz を取得します。
 
# tar -xzvf v0.10.9rc7.tar.gz を解凍します

9.5 Nginxをインストールする

# ディレクトリに入る cd /user/local/src/
 
# ダウンロード wget http://nginx.org/download/nginx-1.21.0.tar.gz
 
# tar xf nginx-1.21.0.tar.gz を解凍します
 
# nginxディレクトリに入る cd nginx-1.21.0
 
# コンパイル ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-http_realip_module --with-pcre --add-module=/usr/local/src/lua-nginx-module-0.10.9rc7 --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --with-stream
 
# インストール make && make install
 
# nginx 設定を追加し、サーバーブロックに次の内容を追加します [root@localhost_test_192.168.10.132 11:04:48 ~]# vim /usr/local/nginx/conf/nginx.conf
 
場所 /lua {
    デフォルトタイプ 'text/plain';
 
    content_by_lua 'ngx.say("hello, lua")';
}
 
# 構文をチェック [root@localhost_test_192.168.10.132 09:59:33 /usr/local/src]# nginx -t
nginx: 設定ファイル /usr/local/nginx/conf/nginx.conf の構文は正常です
nginx: 設定ファイル /usr/local/nginx/conf/nginx.conf のテストが成功しました
 
# [root@localhost_test_192.168.10.132 11:08:35 ~]# nginx を起動します
 
# テスト curl 127.0.0.1:80/lua

9.6 ngx_lua_wafをインストールする

# ディレクトリに入る cd /user/local/src/
 
# ngx_lua_waf を conf ディレクトリにダウンロードします wget https://github.com/loveshell/ngx_lua_waf/archive/master.zip
 
# 解凍してwafという名前を付ける
マスター.zip を解凍 -d /usr/local/nginx/conf/
 
# ディレクトリ名を変更する mv /usr/local/nginx/conf/ngx_lua_waf-master /usr/local/nginx/conf/waf
 
# nginx.conf の http セクションに lua_package_path "/usr/local/nginx/conf/waf/?.lua" を追加します。
lua_shared_dict 制限 10m;
init_by_lua_file /usr/local/nginx/conf/waf/init.lua;
アクセスバイluaファイル /usr/local/nginx/conf/waf/waf.lua;
 
# nginx.conf の最外部レイヤーにユーザー www を追加します。
 
# ログディレクトリを作成する mkdir /usr/local/nginx/logs/hack
chown www /usr/local/nginx/logs/hack
 
# Lua_waf 設定 [root@localhost_test_192.168.10.132 11:33:53 /usr/local/nginx/conf/waf]# cat config.lua
#ルール保存パス RulePath = "/usr/local/nginx/conf/waf/wafconf/"
# 攻撃情報のログ記録を有効にするかどうか、logdir を設定する必要があります
攻撃ログ = "オン"
# ログ保存ディレクトリ。ユーザーが作成する必要があり、nginx ユーザーの書き込み権限が必要です。logdir = "/usr/local/nginx/logs/hack/"
# URL アクセスをブロックするかどうか UrlDeny="on"
# 傍受後にリダイレクトするかどうか Redirect="on"
# クッキー攻撃を阻止するかどうか CookieMatch="on"
# ポスト攻撃をインターセプトするかどうか postMatch="on"
# URL ホワイトリストを有効にするかどうか whiteModule="on"
# アップロードが許可されていないファイル拡張子タイプを入力します black_fileExt={"php","jsp"}
#ip ホワイトリスト、複数の IP はカンマで区切られます ipWhitelist={"127.0.0.1"}
#ip ブラックリスト、複数の IP はカンマで区切られます ipBlocklist={"192.168.10.1"}
# cc 攻撃の傍受を有効にするかどうか (nginx.conf の http セクションに lua_shared_dict limit 10m を追加する必要があります)
CCDeny="オフ"
# CC 攻撃の頻度を秒単位で設定します。
# デフォルトでは、同じ IP は同じアドレスを 1 分間に 100 回しかリクエストできません CCrate="100/60"
# 警告内容 html = []
 
# ルールファイル [root@localhost_test_192.168.10.132 11:42:12 /usr/local/nginx/conf/waf]# ll wafconf/
合計 24
-rw-r--r-- 1 ルート ルート 749 2016年4月6日 引数
-rw-r--r-- 1 ルート ルート 652 2016年4月6日 クッキー
-rw-r--r-- 1 ルート ルート 733 2016年4月6日投稿
-rw-r--r-- 1 ルート ルート 335 2016年4月6日 url
-rw-r--r-- 1 ルート ルート 177 2016年4月6日 ユーザーエージェント
-rw-r--r-- 1 ルート ルート 8 2016年4月6日 whiteurl
 
args のルールは次のとおりです: get パラメータ フィルタリング、cookie フィルタリングはリクエスト フィルタリング用の cookie フィルタリング、url フィルタリングは get リクエスト url のみをフィルタリングするルール、post フィルタリングは post リクエストのみをフィルタリングするルール、whiteurl はホワイトリストで、その中の url はフィルタリングなしで一致します、user-agent は user-agent のフィルタリング ルールです # Nginx をロードします
[root@localhost_test_192.168.10.132 11:32:41]# nginx -s リロード

9.7 テスト結果

パラメータ付きURLへのアクセス

http://192.168.10.132/?id=<スクリプト

まとめ: Nginx は Lua モジュールを使用して WAF を実装しており、非常に強力です。二次開発用にコードを変更し、目的の効果が得られるように修正することができます。試してみるとよいでしょう。

Nginx が Lua モジュールを使用して WAF を実装する方法の原理分析に関するこの記事はこれで終わりです。Nginx による WAF の実装に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Nginx リバース プロキシと負荷分散の概念の理解とモジュールの使用
  • NGINX 権限制御ファイルのプレビューとダウンロードの実装原則
  • Nginx プロセス管理とリロードの原則の詳細な説明
  • Nginxの仕組みの詳細な説明
  • Nginx の基本概念と原則

<<:  子ども向けウェブサイトの視覚構造レイアウト設計手法の分析

>>:  JavaScript はスローモーションアニメーションのカプセル化と使用法を説明します

推薦する

Mapper SQL ステートメント フィールドとエンティティ クラス属性名の関係は何ですか?

背景: 1. データベースに通知テーブルがある あなたは見ることができますgmt_create、通知...

ネイティブJSを使用した遅延読み込みlazyLoadの3つの方法の概要

目次序文方法1: 高コントラスト方法2: getBoundingClientRect() APIを使...

Docker クロスホストネットワーク (オーバーレイ) の実装

1. Dockerのホスト間通信Docker クロスホスト ネットワーク ソリューションには以下が含...

MySQL 5.7 生成列の使用例の分析

この記事では、例を使用して、MySQL 5.7 で生成された列の使用方法を説明します。ご参考までに、...

Dockerの基本的な手順

目次基本的な指示1. 現在のマシンのコンテナステータスを確認する2. イメージをダウンロードまたは取...

MySQL 8.0.12 のインストールと設定のグラフィックチュートリアル

MySQL 8.0.12 のダウンロードとインストールのチュートリアルを録画し、全員と共有しました。...

JavaScript の for/of、for/in の詳細な紹介

目次JavaScriptでは、 forループを記述する一般的な方法がいくつかあります。最初の、そして...

MySQL で準備、実行、割り当て解除ステートメントを使用するチュートリアル

序文MySQLでは、準備、実行、割り当て解除を正式にはPREPARE STATEMENTと呼びます。...

this.parentNode.parentNode (親ノードの親ノード) はどういう意味ですか?

親ノードの親ノード、例えば、このような段落がありますHTML:コードをコピーコードは次のとおりです。...

携帯電話番号が合法かどうかを判断するWeChatアプレットのサンプルコード

目次シナリオ効果コード要約するシナリオ登録ページに携帯電話番号を入力し、登録インターフェイスを要求す...

Vue プロジェクトで TS (TypeScript) を使用するための入門チュートリアル

目次1. Typescriptの紹介2. 設定ファイル webpack 設定3. プロジェクトに.t...

検証コードケースのJavaScript実装

この記事では、検証コードの効果を実現するためのJavaScriptの具体的なコードを参考までに共有し...

Vue.set() と this.$set() の使い方と違い

開発に Vue を使用する場合、次のような状況に遭遇することがあります。Vue インスタンスを生成し...

LinuxにDockerをインストールする(非常に簡単なインストール方法)

最近、かなり暇です。大学4年生として数か月間インターンをしていました。インターンとして、Docker...

MySQL にテーブルデータを挿入するときに中国語の文字化けが発生する問題を解決する方法

1. 問題開発中に、他のデータベースから MySQL データベース テーブルにデータを挿入すると、次...