Debian/UbuntuでApacheを使用してmod_securityを設定する方法
プレリュード
Modセキュリティは、Apache、Nginx、IISで動作する無料のWebアプリケーションファイアウォール(WAF)です。 シンプルで複雑な操作を実行するための柔軟なルールエンジンをサポートし、SQLインジェクション、クロスサイトスクリプティング、トロイの木馬、悪意のあるユーザーエージェント、セッションハイジャック、その他多くのエクスプロイトのルールを含むコアルールセット(CRS)が付属しています。 Apacheの場合、これはインストールと構成を簡単にする追加モジュールです。
このチュートリアルを完了するには、サーバーにLAMPがインストールされている必要があります。
mod_securityのインストール
ModsecurityはDebian/Ubuntuリポジトリで利用できます。
apt-get install libapache2-modsecurity
mod_securityモジュールがロードされているかどうかを確認します。
apachectl -M | grep --color security
名前の付いたモジュールが表示されます security2_module (shared)
これは、モジュールがロードされたことを示します。
Modsecurityのインストールには、名前を変更する必要がある推奨構成ファイルが含まれています。
mv /etc/modsecurity/modsecurity.conf{-recommended,}
Apacheをリロードします
service apache2 reload
mod_securityの新しいログファイルはApacheログディレクトリにあります。
root@droplet:~# ls -l /var/log/apache2/modsec_audit.log
-rw-r----- 1 root root 0 Oct 19 08:08 /var/log/apache2/modsec_audit.log
mod_securityの構成
箱から出して、modsecurityはルールが機能する必要があるため、何もしません。 デフォルトの構成ファイルはDetectionOnlyに設定されており、ルールの一致に従ってリクエストをログに記録し、何もブロックしません。 これは、編集することで変更できます modsecurity.conf
ファイル:
nano /etc/modsecurity/modsecurity.conf
この行を見つける
SecRuleEngine DetectionOnly
次のように変更します。
SecRuleEngine On
実稼働サーバーでこれを試している場合は、すべてのルールをテストした後でのみ、このディレクティブを変更してください。
変更する別のディレクティブは SecResponseBodyAccess
. これにより、応答本文がバッファリングされるかどうかが構成されます(つまり、 modsecurityによって読み取られます)。 これは、データ漏洩の検出と保護が必要な場合にのみ必要です。 したがって、 On のままにすると、ドロップレットリソースが使い果たされ、ログファイルのサイズも大きくなります。
これを見つける
SecResponseBodyAccess On
次のように変更します。
SecResponseBodyAccess Off
次に、Webアプリケーションに投稿できる最大データを制限します。 2つのディレクティブがこれらを構成します。
SecRequestBodyLimit
SecRequestBodyNoFilesLimit
The SecRequestBodyLimit
ディレクティブは、最大POSTデータサイズを指定します。 クライアントからそれより大きいものが送信された場合、サーバーは 413 Request Entity TooLargeエラーで応答します。 Webアプリケーションにファイルのアップロードがない場合、この値を大幅に減らすことができます。
構成ファイルに記載されている値は
SecRequestBodyLimit 13107200
これは12.5MBです。
これに似ているのは SecRequestBodyNoFilesLimit
指令。 唯一の違いは、このディレクティブがPOSTデータからファイルのアップロードを差し引いたサイズを制限することです。この値は「実用的な範囲で」低くする必要があります。
構成ファイルの値は次のとおりです。
SecRequestBodyNoFilesLimit 131072
これは128KBです。
これらのディレクティブに沿って、サーバーのパフォーマンスに影響を与えるもう1つのディレクティブがあります。 SecRequestBodyInMemoryLimit
. このディレクティブはほとんど自明です。 これは、メモリ(RAM)に保持する「要求本文」データ(POSTデータ)の量を指定します。それ以上のものはハードディスクに配置されます(スワッピングのように)。 ドロップレットはSSDを使用するため、これはそれほど問題にはなりません。 ただし、RAMに余裕がある場合は、これを適切な値に設定できます。
SecRequestBodyInMemoryLimit 131072
これは、構成ファイルで指定された値(128KB)です。
SQLインジェクションのテスト
ルールの構成を進める前に、SQLインジェクションに対して脆弱なPHPスクリプトを作成し、試してみます。 これは基本的なPHPログインスクリプトであり、セッション処理は行われないことに注意してください。 データベースに接続するように、以下のスクリプトのMySQLパスワードを必ず変更してください。
/var/www/login.php
<html>
<body>
<?php
if(isset($_POST['login']))
{
$username = $_POST['username'];
$password = $_POST['password'];
$con = mysqli_connect('localhost','root','password','sample');
$result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
if(mysqli_num_rows($result) == 0)
echo 'Invalid username or password';
else
echo '<h1>Logged in</h1><p>A Secret for you....</p>';
}
else
{
?>
<form action="" method="post">
Username: <input type="text" name="username"/><br />
Password: <input type="password" name="password"/><br />
<input type="submit" name="login" value="Login"/>
</form>
<?php
}
?>
</body>
</html>
このスクリプトはログインフォームを表示します。 適切なクレデンシャルを入力すると、「ASecretforyou」というメッセージが表示されます。
データベースにクレデンシャルが必要です。 MySQLデータベースとテーブルを作成してから、ユーザー名とパスワードを挿入します。
mysql -u root -p
これはあなたをに連れて行きます mysql>
促す
create database sample;
connect sample;
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('jesin','pwd');
insert into users values('alice','secret');
quit;
ブラウザを開き、に移動します http://yourwebsite.com/login.php
正しいクレデンシャルのペアを入力します。
Username: jesin
Password: pwd
ログインが成功したことを示すメッセージが表示されます。 ここに戻って、間違ったクレデンシャルのペアを入力します。無効なユーザー名またはパスワードというメッセージが表示されます。
スクリプトが正しく機能していることを確認できます。 次の仕事は、ログインページをバイパスするためにSQLインジェクションを試してみることです。 usernameフィールドに次のように入力します。
' or true --
後にスペースが必要であることに注意してください --
この注入は、そのスペースがないと機能しません。 password フィールドを空のままにして、ログインボタンを押します。
出来上がり! スクリプトは、認証されたユーザー向けのメッセージを表示します。
ルールの設定
あなたの生活を楽にするために、mod_securityと一緒にすでにインストールされている多くのルールがあります。 これらはCRS(コアルールセット)と呼ばれ、
root@droplet:~# ls -l /usr/share/modsecurity-crs/
total 40
drwxr-xr-x 2 root root 4096 Oct 20 09:45 activated_rules
drwxr-xr-x 2 root root 4096 Oct 20 09:45 base_rules
drwxr-xr-x 2 root root 4096 Oct 20 09:45 experimental_rules
drwxr-xr-x 2 root root 4096 Oct 20 09:45 lua
-rw-r--r-- 1 root root 13544 Jul 2 2012 modsecurity_crs_10_setup.conf
drwxr-xr-x 2 root root 4096 Oct 20 09:45 optional_rules
drwxr-xr-x 3 root root 4096 Oct 20 09:45 util
ドキュメントは次のURLで入手できます。
root@droplet1:~# ls -l /usr/share/doc/modsecurity-crs/
total 40
-rw-r--r-- 1 root root 469 Jul 2 2012 changelog.Debian.gz
-rw-r--r-- 1 root root 12387 Jun 18 2012 changelog.gz
-rw-r--r-- 1 root root 1297 Jul 2 2012 copyright
drwxr-xr-x 3 root root 4096 Oct 20 09:45 examples
-rw-r--r-- 1 root root 1138 Mar 16 2012 README.Debian
-rw-r--r-- 1 root root 6495 Mar 16 2012 README.gz
これらのルールをロードするには、Apacheにこれらのディレクトリを調べるように指示する必要があります。 編集します modsecurity.conf
ファイル。
nano /etc/apache2/mods-enabled/modsecurity.conf
次のディレクティブを内部に追加します <IfModule security2_module> </IfModule>
:
Include "/usr/share/modsecurity-crs/*.conf"
Include "/usr/share/modsecurity-crs/activated_rules/*.conf"
The activated_rules
ディレクトリはApacheのものに似ています mods-enabled
ディレクトリ。 ルールはディレクトリで利用できます。
/usr/share/modsecurity-crs/base_rules
/usr/share/modsecurity-crs/optional_rules
/usr/share/modsecurity-crs/experimental_rules
シンボリックリンクは、 activated_rules
これらをアクティブ化するディレクトリ。 SQLインジェクションルールをアクティブにしましょう。
cd /usr/share/modsecurity-crs/activated_rules/
ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf .
ルールを有効にするには、Apacheをリロードする必要があります。
service apache2 reload
次に、前に作成したログインページを開き、ユーザー名フィールドでSQLインジェクションクエリを使用してみます。 変更した場合 SecRuleEngine
On へのディレクティブでは、 403Forbiddenエラーが表示されます。 DetectionOnly オプションのままにした場合、インジェクションは成功しますが、試行はログに記録されます。 modsec_audit.log
ファイル。
独自のmod_securityルールを作成する
このセクションでは、特定の「スパム」単語がHTMLフォームに入力された場合に、リクエストをブロックするルールチェーンを作成します。 まず、テキストボックスから入力を取得してユーザーに表示するPHPスクリプトを作成します。
/var/www/form.php
<html>
<body>
<?php
if(isset($_POST['data']))
echo $_POST['data'];
else
{
?>
<form method="post" action="">
Enter something here:<textarea name="data"></textarea>
<input type="submit"/>
</form>
<?php
}
?>
</body>
</html>
カスタムルールは、任意の構成ファイルに追加したり、modsecurityディレクトリに配置したりできます。 ルールを別の新しいファイルに配置します。
nano /etc/modsecurity/modsecurity_custom_rules.conf
このファイルに以下を追加します。
SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"
ファイルを保存し、Apacheをリロードします。 開ける http://yourwebsite.com/form.php
ブラウザで、これらの単語のいずれかを含むテキストを入力します:ピル、保険、ロレックス。
403ページとログエントリ、またはに基づくログエントリのみが表示されます SecRuleEngine
設定。 SecRuleの構文は次のとおりです。
SecRule VARIABLES OPERATOR [ACTIONS]
ここでは、 chain アクションを使用して、変数REQUEST_FILENAMEとform.php、REQUEST_METHODとPOST、および[ X155X] REQUEST_BODY と正規表現( @rx )文字列(pills | Insurance | rolex)。 ?i:は、大文字と小文字を区別しない一致を行います。 これら3つのルールすべてが正常に一致すると、ACTIONはdenyおよびlogに「スパムが検出されました」というメッセージが表示されます。 chain アクションは、3つのルールすべてに一致する論理積をシミュレートします。
ホストとディレクトリを除く
phpMyAdmin などのアプリケーションをmodsecurityとして実行していて、SQLクエリをブロックする場合は、特定のディレクトリまたはドメイン名を除外することが理にかなっている場合があります。 WordPressのようなCMSアプリケーションの管理バックエンドを除外することもお勧めします。
完全なVirtualHostのmodsecurityを無効にするには、次のように配置します
<IfModule security2_module>
SecRuleEngine Off
</IfModule>
中 <VirtualHost>
セクション。
特定のディレクトリの場合:
<Directory "/var/www/wp-admin">
<IfModule security2_module>
SecRuleEngine Off
</IfModule>
</Directory>
modsecurityを完全に無効にしたくない場合は、 SecRuleRemoveById
IDを指定して特定のルールまたはルールチェーンを削除するディレクティブ。
<LocationMatch "/wp-admin/update.php">
<IfModule security2_module>
SecRuleRemoveById 981173
</IfModule>
</LocationMatch>
参考文献
公式のmodsecurityドキュメントhttps://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual