さくらVPS上でLAMP環境を構築した際の覚書です。
すでに、VPS上でUbuntu Server 18.04がインストールされた直後、という条件で設定をしていきます。
今回は、Apache2.4のインストールと、関連する部分の設定をします。
ゴール
- Apache2.4を使用する
- 各種セキュリティ設定を実施する
- デフォルトのサイトでSSLを使用(https)
- 80番ポートへのアクセス(http)は、全てhttpsへリダイレクトする
- 証明書は、デフォルトでインストールされている証明書(自己認証証明書)を仮に使用する
Apacheのインストール
Ubuntuのパッケージからインストールします。
$ sudo apt install apache2
セキュリティの設定
ApacheとOSのバージョン情報を隠蔽する
Apacheと、OSのバージョン情報が外部からは見えないようにします。
$sudo vi /etc/apache2/conf-enabled/security.conf
ServerSignature Off
ServerTokens Prod
IndexesとFollowSymLinksオプションを無効に
インストール直後は有効になっている、Indexes
と FollowSymlinks
の2つのオプションを無効にします。
Indexes
オプションは、有効なページがなかった場合に、そのディレクトリのファイルやディレクトリの一覧を表示するので、全体でOffにし、FollowSymLinks
は、個別のロケーションで有効にします。
$ sudo vi /etc/apache2/apache2.conf
<Directory /var/www/>
Options -Indexes -FollowSymLinks
AllowOverride None
Require all granted
</Directory>
mod_securityを利用する
https://www.linode.com/docs/web-servers/apache-tips-and-tricks/configure-modsecurity-on-apache/
オープンソースのウェブアプリケーションファイアウォール (WAF) である、mod_security
をインストールします。
$ sudo apt install libapache2-mod-security2 -y
$ sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
$ sudo vi /etc/modsecurity/modsecurity.conf
SecRuleEngine On
デフォルトのルールセットを、GitHubから取得する
- 既存のディレクトリの名前を変更する
$ sudo mv /usr/share/modsecurity-crs /usr/share/modsecurity-crs.bk
- 新しいルールセットをGitHubからクローン
$ sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/share/modsecurity-crs
- サンプルのコンフィグファイルをコピー
$ sudo cp /usr/share/modsecurity-crs/crs-setup.conf.example /usr/share/modsecurity-crs/crs-setup.conf
- これらのコンフィグを有効にするために、
/etc/apache2/mods-enabled/security2.conf
に、次の項目を追加する
IncludeOptional /usr/share/modsecurity-crs/*.conf
IncludeOptional /usr/share/modsecurity-crs/rules/*.conf
- Apacheを再起動させる
$ sudo systemctl restart apache2
テスト
/etc/apache2/sites-enabled/000-default.conf
を編集して、次の <IfModule security2_module>...</IfModule>
を追加する。
$ sudo vi /etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
:
<IfModule security2_module>
# test
SecRule ARGS:testparam "@contains test" "id:1234,deny,status:403,msg:'Our test rule has triggered'"
</IfModule>
:
</VirtualHost>
- Apacheを再起動させる
$ sudo systemctl restart apache2
curl
のインストール
$ sudo apt install curl
curl
で次のように実行し、レスポンスに403が返ってくるか確認。
$ curl http://localhost?testparam=test
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.<br />
</p>
</body></html>
また、/var/log/apache2/errors.log
に次のようなログが残っていることを確認する。
[Wed Feb 13 11:59:10.081578 2019] [:error] [pid 14878] [client ::1:60478] [client ::1] ModSecurity: Access denied with code 403 (phase 2). String match "test" at ARGS:testparam. [file "/etc/apache2/sites-enabled/default-ssl.conf"] [line "28"] [id "1234"] [msg "Our test rule has triggered"] [hostname "localhost"] [uri "/"] [unique_id "XGOH-kekkqfvPiKDe2Vz0AAAAAM"]
再度、curl
で次のように実行し、同じく403が返ってくるのを確認。
$ curl http://localhost/index.html?exec=/bin/bash
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /index.html
on this server.<br />
</p>
</body></html>
また、/var/log/apache2/errors.log
には次のように記録されます。
[Wed Feb 13 12:14:18.788207 2019] [:error] [pid 14878] [client ::1:60488] [client ::1] ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "86"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=5,PHPI=0,HTTP=0,SESS=0): Remote Command Execution: Unix Shell Code Found; individual paranoia level scores: 5, 0, 0, 0"] [tag "event-correlation"] [hostname "localhost"] [uri "/index.html"] [unique_id "XGOLikekkqfvPiKDe2Vz0QAAAAM"]
一通りテストができたら、000-default.conf
の <IfModule security2_module>...</IfModule>
は、削除しておいてください。
mod_evasiveを利用する
mod_evasive は、Apacheのモジュールで、DDoS/DoS 攻撃やブルートフォース攻撃を回避するための機能を提供しています。また、そういった攻撃を検知した場合、メールやsyslogで報告されます。
mod_evasive のインストール
$ sudo apt install libapache2-mod-evasive
途中、Postfix Configuration
の画面が出てきたときは、[[No configuration]]を選択。
- 動作を確認
$ sudo apachectl -M | grep evasive
evasive20_module (shared)
/etc/apache2/mods-available/evasive.conf
を編集し、コメントを解除します。
$ sudo vi /etc/apache2/mods-available/evasive.conf
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 300
DOSEmailNotify you@yourdomain.com
#DOSSystemCommand "su - someuser -c '/sbin/... %s ...'"
DOSLogDir "/var/log/mod_evasive"
</IfModule>
- ログを保存するディレクトリを作成
$ sudo mkdir /var/log/mod_evasive
$ chown www-data /var/log/mod_evasive
- Apacheを再起動する
$ sudo systemctl restart apache2
各項目の説明
- DOSHashTableSize
- ハッシュテーブルのサイズ。大きければパフォーマンスがアップする代わりに、メモリ消費が多くなります。
- DOSPageCount
- PageIntervalの間に、同じページやURIにリクエストした回数の閾値。閾値を超えると、クライアントのIPアドレスがブロックリストに追加されます。
- DOSSiteCount
- SiteIntervalの間に、同じリスナーの同じクライアントによるリクエストの総数の閾値です。閾値を超えると、クライアントのIPアドレスがブロックリストに追加されます。
- DOSPageInterval
- ページカウントの閾値のための間隔。デフォルトは1秒
- DOSSiteInterval
- サイトカウントの閾値のための間隔。デフォルトは1秒
- DOSBlockingPeriod
- ブロックされたクライアントが接続をブロックされる期間(秒)。ブロックされている間は、403を返します。ブロック中に再度リクエストするとタイマーはさらに、指定された秒数にリセットされます。
- DOSSystemCommand
- IPアドレスがブラックリストに登録される度に、ここで指定されたコマンドを実行します。
- DOSEmailNotify
- IPアドレスがブラックリストに登録される度に、指定されたメールアドレスにメールを送信します。
- DOSLogDir
- ログの保存先。デフォルトは
/tmp
- DOSWhitelist
- 信頼されているクライアントのIPアドレス。
テスト
ネットで調べたとおりにテストを実行してみます。テストには、test.pl
を使用します。
$ cd /usr/share/doc/libapache2-mod-evasive/examples/
$ sudo chmod +x test.pl
$ perl test.pl
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
HTTP/1.1 400 Bad Request
:
HTTP/1.1 400 Bad Request
ところが、このように期待した結果が出ません。
本来は、HTTP/1.1 200 OK
が何行か表示された後に、HTTP/1.1 403 Forbidden
が連続して表示されるのですが、この場合は 400 Bad Request
となっています。
以下のようにするとテストできます(https://qiita.com/crazyhacks/items/2cfc36be38846d1406cf)。
$ yes 'exec 4<>/dev/tcp/127.0.0.1/80; printf "GET / HTTP/1.0\r\n\r\n" >&4; head -1 <&4' | head -100 | bash
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
:
HTTP/1.1 403 Forbidden
最初に数回は、ステータス200番を返していたものが、途中から403番に変わっています。
次に、ブロックした際に作成されたログファイルを確認します。
$ ls -al /var/log/mod_evasive/
total 12
drwxr-xr-x 2 www-data www-data 4096 Feb 13 20:41 .
drwxrwxr-x 8 root syslog 4096 Feb 13 20:09 ..
-rw-r--r-- 1 www-data www-data 4 Feb 13 20:41 dos-127.0.0.1
このようにdos-IPアドレス
という形で残っています。
念の為、localhostからのアクセスは拒否しないように、/etc/apache2/mods-available/evasive.conf
に
DOSWhitelist 127.0.0.1
を追加しておきます。
TRACE リクエストの無効化
Cross-Site Tracing(XST) 対策のためにTRACEメソッドを無効にします。
sudo vi /etc/apache2/conf-enabled/security.conf
TraceEnable
がOff
か確認する(デフォルトでOffのはずです)。
TraceEnable off
- Apacheを再起動させる
- TRACEが無効になっているのを確認
HTTPの場合は、curl -v -X TRACE [URL]
HTTPSの場合は、curl --insecure -v -X TRACE [URL]
$ curl --insecure -v -X TRACE https://www.example.jp/
:
:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>405 Method Not Allowed</title>
</head><body>
<h1>Method Not Allowed</h1>
<p>The requested method TRACE is not allowed for the URL /.</p>
</body></html>
Method Not Allowed
と出ていればOK
クリックジャッキング対策
mod_headers
を有効にする。
$ sudo a2enmod headers
/etc/apache2/conf-available/security.conf
のHeader set X-Frame-Options:
の値を"sameorigins"
にする(コメントを解除する)。
Header set X-Frame-Options: "sameorigin"
apache2 を再起動
$ sudo systemctl restart apache2
SSLを有効に
httpの通信をSSL/TLSで暗号化された経路でのみ受け付けるようにします。
モジュールを有効に
mod_rewirte
$ sudo a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
systemctl restart apache2
mod_ssl
$ sudo a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Module socache_shmcb already enabled
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
systemctl restart apache2
httpへのリクエストをhttpsにリダイレクト
80番ポートへのhttpリクエストをすべて、443番にリダイレクトします。
/etc/apache2/sites-available/000-default.conf
に、次のように変更する。
$ sudo vi /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
ここでは、RewriteEngine On
でmod_rewriteモジュールを有効にしてURLの書き換えをできるようにしています。
意味は:
RewriteCond %{HTTPS} off
で「コネクションがSSL/TLSを利用していない場合」に次の行に処理を渡します。
次の行、RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
では、すべてのリクエスト(^(.*)$
)を、R=301
、要するにリダイレクトし、リダイレクト先を元のリクエストURLのhttp
の部分を https
に書き換えたURLにして、L
で処理を終了、と読みます。
証明書とキーの指定
/etc/apache2/sites-available/default-ssl.conf
の次の項目に、証明書とキーのファイルを指定します。
$ sudo vi /etc/apache2/sites-available/default-ssl.conf
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
ここでは、インストール時に付属してくる自己認証の証明書とキーを使用していますが、本番サイトでは、正式な認証局から取得した証明書とキーを使用します。 |
サイトを有効化
000-default.conf
と、default-ssl.conf
を有効にする。( 000-default.conf
はすでに有効になっているはず)
$ sudo a2ensite 000-default.conf
Site 000-default already enabled
$ sudo a2ensite default-ssl.conf
Enabling site default-ssl.
To activate the new configuration, you need to run:
systemctl reload apache2
apacheを再起動します。
$ sudo systemctl restart apache2
リダイレクトをテスト
curl -I http://localhost/
として確認。
$ curl -I http://localhost/
HTTP/1.1 301 Moved Permanently
Date: Wed, 13 Feb 2019 04:22:09 GMT
Server: Apache
Location: https://localhost/
Content-Type: text/html; charset=iso-8859-1
HTTP/1.1 301 Moved Permanetly
と表示されていればOK。
実際にリダイレクト出来たかどうかを確認する場合は、curl -IL --insecure http://localhost
とします。
$ curl -IL --insecure http://localhost
HTTP/1.1 301 Moved Permanently
Date: Wed, 13 Feb 2019 10:54:10 GMT
Server: Apache/2.4.29 (Ubuntu)
Location: https://localhost/
Content-Type: text/html; charset=iso-8859-1
HTTP/1.1 200 OK
Date: Wed, 13 Feb 2019 10:54:10 GMT
Server: Apache/2.4.29 (Ubuntu)
Last-Modified: Wed, 13 Feb 2019 10:45:17 GMT
ETag: "2aa6-581c43cd62071"
Accept-Ranges: bytes
Content-Length: 10918
Vary: Accept-Encoding
Content-Type: text/html
で、まずhttpによるアクセスで、301 Moved Permanetry
でリダイレクトされ、その次に 200 OK
と出ています。
自己認証局の証明書等を使用している場合、curl はエラーを吐いて止まるので、--insecure オプションを付けて下さい |
ファイアウォールの設定
ポートの 80/tcp
と 443/tcp
を開放します。
$ sudo ufw allow http
Rule added
Rule added (v6)
$ sudo ufw allow https
Rule added
Rule added (v6)
$ sudo ufw status
Status: active
To Action From
-- ------ ----
60022 ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
60022 (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
最後に、実際のURLに接続してApache2 Ubuntu Default Pageが表示されるか確認します。
0件のコメント