※ この記事は 2024/04/05 に投稿され、 2024/04/05 に内容が更新されています
Web サイトのセキュリティは非常に重要です。
特に WordPress のような人気のある CMS を使用している場合、攻撃者のターゲットになる可能性が高くなります。
そのため、セキュリティ対策は必須です。
ModSecurity は、WordPress を運用している Apache など Web サーバにおけるセキュリティ強化のための優れたソフトウェアです。
本記事では、 ModSecurity を使って Apache で運用している WordPress のセキュリティを強化する方法と、その効果について詳しく説明します。
利用環境は Ubuntu Server 22.04 / Apache 環境となります。
ModSecurity を使って Web サーバのセキュリティ強化を
ModSecurity は WAF として知られるツールで、 Apache をはじめとした Web サーバ上で動作します。
このソフトウェアは、攻撃を検知してブロックすることができるため、 WordPress のセキュリティを強化するのに非常に役立ちます。
ModSecurity は、 SQL インジェクション、クロスサイトスクリプティング (XSS)、リモートコード実行などのよく知られた攻撃パターンを検出し、ブロックすることができます。
WAF には「ソフトウェア型」「アプライアンス型」「クラウド型」と種類がありますが、 ModSecurity は「ソフトウェア型」であり、なおかつ OSS のため無料で利用することができます。
当サイトは Cloudflare の無料版 WAF を利用しているのですが、残念ながらそれをもってしても、攻撃的なアクセスがあるという状況です。
そのため ModSecurity を導入することにしました。

※ 「IP アドレスは隠すべし」という批判はありましょうが、明らかに攻撃的意図があるアクセス元なので、そのまま晒しています
Apache 上の WordPress に ModSecurity を導入する手順
ModSecurity を Apache に導入するためには、まずはじめに ModSecurity をインストールする必要があります。
次に Apache の設定ファイルで ModSecurity を有効化し、ルールを追加します。
これにより、ModSecurity が WordPress のリクエストを監視し、検出した攻撃をブロックすることができます。
また、ModSecurity のログ機能を有効にして、攻撃の詳細情報を確認することも重要です。
Apache を apt でインストールされている場合は、簡単に導入することができます
※ modsecurity-crs
は CRS で、つまり既知の攻撃などに対するルールセット (シグネイチャ) となります
apt update
apt install libapache2-mod-security2 modsecurity-crs
# ModSecurity モジュールを有効化
sudo a2enmod security2
# 推奨設定を有効化
sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# Apache 再起動
sudo systemctl restart apache2.service
ただ、私はインフラエンジニアということもあり、脆弱性が発見されたら即パッチをあてるやバージョンアップの対応したいので、 Apache をソースからインストールしています。
なので、 ModSecurity もソースからインストールすることになります。
apt update
apt install libpcre-dev yajl-tools yajl2 ssdeep libyajl-dev lib-lua5.3-dev
# ディレクトリ移動
cd /usr/local/src
# ソースコードダウンロード
wget https://github.com/owasp-modsecurity/ModSecurity/releases/download/v2.9.7/modsecurity-2.9.7.tar.gz
# ソースコード解凍
# 知らない人もいたのが以外だけど、 a オプションは z とか j とか拡張子でよきにはからってくれるよ
tar xavf modsecurity-2.9.7.tar.gz
# ソースコードディレクトリに移動
cd modsecurity-2.9.7
# configure
./configure --with-apxs=[PATH_TO_APXS] --with-apr=[PATH_TO_APX_UTILS] --with-yajl --with-ssdeep --with-lua --with-libxml
# 4 は CPU コア数に合わせて修正
make -j4
# モジュールインストール
sudo make install
# CRS ダウンロード
mkdir /usr/share/modsecurity
cd /usr/share/modsecurity
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
sudo vim [PATH_TO_httpd.conf]
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so
cd [PATH_TO_HTTPD-CONF-DIR]/conf/extra/
cat << EOF > modsecurity.conf
<IfModule security2_module>
SecDataDir /var/cache/modsecurity
IncludeOptional /etc/modsecurity/*.conf
IncludeOptional /usr/share/modsecurity-crs/*.load
</IfModule>
EOF
sudo mkdir -p /etc/modsecurity/crs
sudo cd /etc/modsecurity
sudo cat << EOF > mod_security.conf
# ブロック有効化
SecRuleEngine On
# 検出のみ
#SecRuleEngine DetectionOnly
SecRequestBodyAccess On
SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
SecRequestBodyLimit 2147483648
SecRequestBodyNoFilesLimit 2147483648
SecRequestBodyInMemoryLimit 1310720
SecRequestBodyLimitAction Reject
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
SecPcreMatchLimit 100000
SecPcreMatchLimitRecursion 100000
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
SecResponseBodyAccess Off
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
SecTmpDir /usr/local/apache2/logs/mod_security/tmp
SecDataDir /usr/local/apache2/logs/mod_security/data
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABDEFHIJZ
SecAuditLogType Serial
SecAuditLog /usr/local/apache2/logs/mod_security/modsec_audit.log
SecArgumentSeparator &
SecCookieFormat 0
SecUnicodeMapFile unicode.mapping 20127
SecStatusEngine On
EOF
sudo systemctl restart [apache サービス名]
ModSecurity の導入による WordPress セキュリティ向上の効果
ModSecurity を導入することで、WordPress のセキュリティと防御力を大幅に向上させることができます。
ModSecurity は攻撃の検出とブロックを自動的に行うため、攻撃者の害悪なリクエストを阻止することができます。
これにより、WordPress の脆弱性を悪用した攻撃やデータ漏洩を防ぐことができます。ModSecurity のルールセットを適切に設定することで、独自のセキュリティポリシーを実装し、WordPress のセキュリティを最適化することも可能です。
ですが、誤検出も多いです、、というのが実情です。
ModSecurity の恩恵を受けるための WordPress の最適な設定
誤検知が多いと述べましたが、そのまま CRS を WorsPress に適用するとどうなるか見てみましょう。
記事を投稿あるいは編集してみます。
はい、 403 エラーになってますね。

HTTP/1.1 403 Forbidden
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Length: 199
Connection: close
Content-Type: text/html; charset=iso-8859-1
Date: Thu, 04 Apr 2024 17:33:10 GMT
Server: Apache
攻撃と思われるアクセスを検出すると、ログに以下のようなルールセットの名前と ID が刻まれます。
この場合のルールセットは RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf で ID が 949110 になります。
This 'deny' is by default paired with a 'status:403' action.\n#\n# In order to change the disruptive action from 'deny' to something else,\n# you must use SecRuleUpdateActionByID directives AFTER the CRS rules\n# are configured, for instance in the RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf file.\n#\n# These actions only apply when using Anomaly Mode.\n#\n# Default action: block with error 403\n# (No configuration needed in this file if you want the default behavior.)\n#\n\n# Example: redirect back to the homepage on blocking\n#\n# SecRuleUpdateActionById 949110
ルールセット自体の読込みをやめる or ルールを除外するユーザ設定を追加しましょう。
ルールセットを読み込まない方法が確実ですが、その分セキュリティも下がるため、可能であれば ID を特定してルールだけを除外する方が良いです。
ルールをユーザ設定で除外するオーバーライド

cd /etc/modsecurity/
cat << EOF > user.conf
<If "%{REQUEST_METHOD} == 'POST' && (%{HTTP_REFERER} =~ /therewill\.be/ || %{HTTP_COOKIE} !~ /wordpress_logged_in_/)">
SecRuleRemoveById 949110 941100 941160 941180 941310
</If>
EOF
まとめ
ModSecurity を活用するためには、 WordPress の設定も最適化する必要があります。
まず、常に最新のWordPress バージョンを使用し、セキュリティパッチを定期的に適用することが重要です。
また、不要なプラグインやテーマを削除し、セキュリティの脆弱性を減らすことも必要です。さらに、強力なパスワードポリシーを設定し、二要素認証を有効化することも推奨されます。
これらの設定は、ModSecurity との相乗効果を生み出し、WordPress のセキュリティをより強固にします。
ModSecurity を使って Apache 上の WordPress のセキュリティを強化することは、ウェブサイトの安全性を向上させるために重要です。
本記事では、ModSecurity の導入手順やその効果、WordPress の適切な設定について説明しました。
Apache 上で WordPress を運営している場合は、是非 ModSecurity を導入してセキュリティを強化してください。
ユーザ設定が面倒なところもありますが、ウェブサイトへの攻撃から保護するために、 ModSecurity は重要なソフトウェアとなるでしょう。
コメント