初めに #
近年では Web アプリケーションを標的とした攻撃は高度化・多様化しており、SQL インジェクション、クロスサイトスクリプティング(XSS)、リモートコード実行などへの対策が不可欠となっています。
このような背景から、アプリケーション側のセキュリティ対策に加えて、サーバーレイヤーでの防御手段として WAF を併用する構成が一般的となっています。
WAF には、サーバー組み込み型や SaaS 型など、有料・無料を含めてさまざまな形態が存在します。
Apache を利用している環境であれば、Webサーバーに組み込み可能な mod_security モジュールを利用することで、比較的容易に WAF を導入することが可能です。
さらに検知ルールとして OWASP CRS を適用することで、一般的な Web 攻撃に対して包括的な防御を実現できます。
本記事では、AlmaLinux 10 環境において Apache に mod_security を導入し、OWASP CRS を有効化するまでの手順について解説します。
mod_security とは? #
mod_security は、Apache(httpd) に組み込んで利用できる WAF モジュールとなります。
Apache に組み込む形で動作するため、専用のソフトや外部サービスを利用することなく、Web サーバー単体で WAF 機能を実装することができます。
mod_security には 1系 と 2系 のバージョンが存在しますが、現在は 2系が主流となっております。
mod_security では検知ルールを柔軟にカスタマイズでき、用途に応じて独自のルールを作成することも可能です。
また、代表的なルールセットとして、OWASP により開発・提供されている OWASP Core Rule Set(OWASP CRS) が存在します。
以下は mod_security の公式リポジトリとなっております。
ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analysis.
Apacheの導入 #
本記事は、Webサーバーとして Apache が導入済みであることを前提とした内容となっています。
未導入の環境では、以下の手順に従いインストールを実施してください。
なお、既に導入済みの場合は、本手順は読み飛ばしていただいて問題ありません。
初めに次のコマンドを実行してください。
dnf install httpd
実行すると、以下のようにインストールパッケージの確認画面が表示されます。
Total download size: 2.0 M
Installed size: 6.1 M
Is this ok [y/N]:
内容を確認し問題なければ y を入力してインストールを進めてください。
インストールが完了すると、次のメッセージが表示されます。
Complete!
以下のコマンドを実行することで、パッケージの導入有無を確認することができます。
$ rpm -qa |grep "httpd"
httpd-tools-2.4.63-4.el10_1.3.x86_64
httpd-filesystem-2.4.63-4.el10_1.3.noarch
httpd-core-2.4.63-4.el10_1.3.x86_64
almalinux-logos-httpd-100.3-3.el10_0.noarch
httpd-2.4.63-4.el10_1.3.x86_64
上記のようにパッケージ情報が表示されれば、Apache のインストールは完了となります。
Apache のインストール完了後、運用要件に応じてバーチャルホスト(VirtualHost)の設定を行ってください。
また、以下のコマンドにてサービスと自動起動を有効化する事ができます。
systemctl enable --now httpd
なお、外部からアクセスを行う場合は、ファイアウォールにて HTTP ポート(80番)およびHTTPS ポート(443番)を解放する必要があります。
必要に応じてポート解放を実施してください。
mod_security の導入 #
AlmaLinux 10 環境では、mod_security は標準リポジトリでは提供されておらず、EPEL リポジトリにて提供されています。
EPELは Fedora Project によって提供されている、Enterprise Linux 向けの追加パッケージリポジトリとなっており、高い安定性と信頼性を備えた、準公式的な位置づけのリポジトリとなっています。
初めに次のコマンドを実行し EPEL リポジトリを有効化してください。
すでに有効になっている場合は、この作業は不要となります。
dnf install epel-release
続いて、mod_security パッケージのインストールを行います。
次のコマンドを実行してください。
dnf install mod_security
実行すると、先ほどと同様に以下のようにインストールパッケージの確認画面が表示されます。
Total download size: 253 k
Installed size: 796 k
Is this ok [y/N]:
内容を確認し問題なければ y を入力してインストールを進めてください。
インストールが完了すると、次のメッセージが表示されます。
Complete!
以下のコマンドを実行することで、パッケージの導入有無を確認することができます。
$ rpm -qa |grep "mod_security"
mod_security-2.9.9-1.el10_1.x86_64
インストールされた本体ファイルは、以下のシステム領域に配置されています。
$ ls /etc/httpd/modules/ |fgrep mod_security
mod_security2.so
OWASP CRSの導入 #
OWASP CRS は、mod_security による Web 攻撃対策のために提供されている代表的なセキュリティルール集となります。
これらのルールは 1 から自作することも可能ですが、SQL インジェクションや XSS などの代表的な攻撃パターンをすべて網羅するには多くの手間と専門知識が必要となります。
そのため、初心者の方や、運用にあまり手間をかけたくない場合には、これらのルールセットをそのまま活用するのがおすすめです。
以下は OWASP CRS の公式リポジトリとなっております。
OWASP CRS (Official Repository)
初めに以下のコマンドを実行し設定ファイルを配置するディレクトリへ移動してください。
cd /etc/httpd/modsecurity.d/
次に、以下のコマンドを実行し OWASP CRS を公式 GitHub リポジトリから取得してください。
git clone https://github.com/coreruleset/coreruleset.git
git コマンドが利用できない場合は以下のように 公式リポジトリから ZIP ファイルを取得しファイルを展開してください。
curl -LO https://github.com/coreruleset/coreruleset/archive/refs/heads/main.zip \
&& unzip main.zip \
&& mv coreruleset-main coreruleset \
&& unlink main.zip
上記コマンドを実行すると、/etc/httpd/modsecurity.d/ 配下に coreruleset ディレクトリが作成されます。
$ ls -1 /etc/httpd/modsecurity.d/
activated_rules
coreruleset
local_rules
coreruleset ディレクトリの構成は以下のようになっております。
coreruleset/
├── crs-setup.conf.example
├── rules/
├── docs/
├── plugins/
├── tests/
├── util/
├── regex-assembly/
└── *.md
OWASP CRS では、あらかじめ設定例となるサンプルファイル(crs-setup.conf.example)が用意されております。
今回はこのサンプルをベースとして利用し設定を行います。
以下のコマンドを実行しサンプルファイルを複製してください。
cp /etc/httpd/modsecurity.d/coreruleset/crs-setup.conf.example \
/etc/httpd/modsecurity.d/coreruleset/crs-setup.conf
複製が完了すると、以下のディレクトリに設定ファイルが作成されます。
ls -al /etc/httpd/modsecurity.d/coreruleset/crs-setup.conf
-rw-r--r--. 1 root root 37039 Dec 29 22:09 /etc/httpd/modsecurity.d/coreruleset/crs-setup.conf
以上で OWASP CRS の導入は完了となります。
OWASP CRS の有効化 #
CRS 導入を行っただけでは、これらのルールはまだ Web サーバーに適用されていない状態となっています。
そのため、設定ファイルから、これらのファイルを呼び出す必要があります。
では実際に OWASP CRS の有効化を行っていきます。
以下のコマンドを実行し設定ファイルを編集してください。
vi /etc/httpd/conf.d/mod_security.conf
この設定ファイルは、mod_security の基本的な動作や設定を行うファイルとなります。
今回はデフォルトの設定を利用しつつ、OWASP CRS の有効化設定のみを追加します。
ファイルを開くと、<IfModule mod_security2.c> というブロックが存在しています。
以下の内容を、このブロックの末尾(閉じタグ </IfModule> の直前)に追記してください。
IncludeOptional /etc/httpd/modsecurity.d/coreruleset/crs-setup.conf
IncludeOptional /etc/httpd/modsecurity.d/coreruleset/rules/*.conf
この設定により、crs-setup.conf で定義された初期設定を前提として、rules ディレクトリ配下の各ルールファイルが適用されるようになります。
検知モードの変更 #
mod_security には、不正なアクセスを「検知のみ行うモード」と「通信を遮断するモード」の2つが用意されています。
インストール直後の初期状態では遮断モードに設定されております。
そのため、環境によっては正常な通信までブロックされてしまう可能性がございます。
初めてWAFを導入する場合は、誤検知によるトラブルを避けるために、まずは検知モードで運用を開始することが推奨されています。
先ほどと同様に以下のコマンドを実行し設定ファイルを編集してください。
vi /etc/httpd/conf.d/mod_security.conf
次に既存の「SecRuleEngine」設定をOn から DetectionOnly に修正してください。
SecRuleEngine DetectionOnly
これにより、不正なリクエストが検知された場合でも、検知内容がログに記録されるだけとなり、通信自体は遮断されずに継続されるようになります。
一定期間の試験運用を行い、問題がないことを確認し、遮断モードへ切り替えることをおすすめします。
Apacheの再起動 #
これらの設定変更が完了したら、変更を反映させるために Apache を再起動する必要があります。
まずは、設定に問題がないか、以下のコマンドでシンタックスチェックを行ってください。
httpd -t
設定に問題が無ければ以下のように表示されます。
Syntax OK
エラーが発生した場合は、内容に従って修正を行ってください。
問題がなければ、以下のコマンドで Apache のリロードを行ってください。
systemctl reload httpd
これにより、稼働中のサービスを停止することなく、設定変更を反映させることができます。
ルールの読み込み確認 #
次に以下のコマンドを実行し、導入した OWASP CRS のルールが正しく読み込まれていることを確認してください。
httpd -t -D DUMP_INCLUDES | grep coreruleset
上記コマンドを実行すると、Apache 起動時に読み込まれる設定ファイルの一覧が表示されます。
以下は実行結果の例となります。
(56) /etc/httpd/modsecurity.d/coreruleset/crs-setup.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-901-INITIALIZATION.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-913-SCANNER-DETECTION.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-921-PROTOCOL-ATTACK.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-922-MULTIPART-ATTACK.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-950-DATA-LEAKAGES.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-955-WEB-SHELLS.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-956-DATA-LEAKAGES-RUBY.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
(57) /etc/httpd/modsecurity.d/coreruleset/rules/RESPONSE-980-CORRELATION.conf
このように、crs-setup.conf および rules ディレクトリ配下の複数のルールファイルが表示されていれば正しく読み込まれています。
動作確認 #
最後に、mod_security の OWASP CRS ルールが正しく動作しているかを確認します。
初めに以下のコマンドを実行し、SQL インジェクションを模したリクエストを送信してください。
curl "http://<サーバーのIPまたはドメイン名>/?id=1%20OR%201=1"
このリクエストにより、mod_security の OWASP CRS ルールが不正なパラメータを検知し監査ログに検知情報が記録されます。
なお、今回は検知モードで運用しているため、この段階では通信自体は遮断されず、「検知のみ」が行われます。
実際にアクセスがブロックされるのは、遮断モードへ切り替えた後となります。
次に、以下のコマンドを実行し、mod_security の監査ログを確認してください。
tail -f /var/log/httpd/modsec_audit.log
監査ログには設定した SecAuditLogParts に従い、複数のセクションが出力されます。
その中で、実際にどのルールに検知されたかといった結果は、H セクションに記録されます。
H セクションには、検知されたルールIDや検知理由、攻撃と判定されたパラメータの内容など、セキュリティ上重要な情報がまとめて出力されます。
例えば、以下のような内容が表示されます。
--3c83db37-H--
Message: Warning. Pattern match ... [id "920350"] [msg "Host header is a numeric IP address"]
Message: Warning. detected SQLi using libinjection ... [id "942100"] [msg "SQL Injection Attack Detected via libinjection"]
Message: Warning. Operator GE matched 5 ... [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 8)"]
Message: Warning. Unconditional match in SecAction ... [id "980170"]
上記の例のうち、942100 は libinjection エンジンにより、SQL インジェクションと判定されたリクエストを検知したことを示しています。
このように、OWASP CRS では 1 つのリクエストに対して複数のルールによる評価が行われ、危険度スコアの合計に応じて最終的な判定が行われます。
以上で動作確認は完了となります。