記事一覧
- AWS EC2でサーバを構築 1 - Amazon Linux 2 準備編
- AWS EC2でサーバを構築 2 - 各種インストール編
- AWS EC2でサーバを構築 3 - Apache + Let's Ecnrypt + PHP-FPM編 (脆弱性診断「A+」を狙う)
- AWS EC2でサーバを構築 4 - Nginx + Let's Ecnrypt + PHP-FPM編 (脆弱性診断「A+」を狙う)
- AWS EC2でサーバを構築 5 - MySQL + phpMyAdmin
- AWS EC2でサーバを構築 6 - PostfixとDovecot (SSL対応とSPAM対策)
- AWS EC2でサーバを構築 7 - セキュリティ対策
概要
ウェブサーバにNginxを使用する場合、本記事は読み飛ばしてください。
Apache (Event MPM) とSSL (Let's Ecnrypt)、PHP-FPMを設定します。
脆弱性診断結果
結論から書いてしまいますが、以下の設定でSSL Labsの脆弱性診断を行ったところ最高の「A+」となりました。
当初は「A」でしたが、設定を見直して「A+」を達成できました。以下の通りの設定で「執筆時点では」「A+」になるはずです。
Apahce
管理者メールアドレス等、お決まりの項目は除いて説明します。以下は気をつける部分です。
/etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
...
#Options Indexes FollowSymLinks
Options FollowSymLinks ExecCGI MultiViews
#AllowOverride None
AllowOverride All
#AddHandler cgi-script .cgi
AddHandler cgi-script .cgi
バーチャルホスト
バーチャルホスト用に公開ディレクトリを作成しておきます。
mkdir -p /var/www/html/www.example1.com/public_html
mkdir -p /var/www/html/www.example2.com/public_html
chown -R apache. /var/www/html
Let's Ecnryptが80/tcpを使用するため、それを待ち受ける仮設定をしておきます。
/etc/httpd/conf.d/vhosts.conf
<VirtualHost *:80>
ServerName www.example1.com
ServerAlias example1.com
DocumentRoot /var/www/www.example1.com/public_html
CustomLog logs/www.example1.com.access_log combined
ErrorLog logs/www.example1.com.error_log
</VirtualHost>
<VirtualHost *:80>
ServerName www.example2.com
DocumentRoot /var/www/www.example2.com/public_html
CustomLog logs/www.example2.com.access_log combined
ErrorLog logs/www.example2.com.error_log
</VirtualHost>
Apacheを起動しておきます。
systemctl start httpd
SSL証明書取得
Let's Ecnryptの証明書を取得します。
certbot certonly --webroot -w /var/www/html/www.example1.com/public_html/ -d example1.com -m root@example1.com
certbot certonly --webroot -w /var/www/html/www.example1.com/public_html/ -d www.example1.com -m root@example1.com
certbot certonly --webroot -w /var/www/html/www.example2.com/public_html/ -d www.example2.com -m root@example2.com
証明書の自動更新
月曜と木曜の4時0分に自動更新されるようにします。
Let's Ecnrypt証明書の期限は3ヶ月です。更新は週に5回までの制限があります。
crontab -e
0 4 * * 1,4 certbot renew --post-hook "systemctl restart httpd php-fpm postfix dovecot"
バーチャルホスト (SSL対応)
証明書取得後のバーチャルホスト設定を行います。
常時SSL化(ポート80へのアクセスを443に301リダイレクト)の設定も行っておきます。
ドメイン正規化 (wwwあり/なし) は.htaccess
で行う想定です。このファイル内で行うことも可能です。
/etc/httpd/conf.d/vhosts.conf
<VirtualHost *:80>
ServerName www.example1.com
ServerAlias example1.com
Redirect permanent / https://www.example1.com/
</VirtualHost>
<VirtualHost *:80>
ServerName www.example2.com
DocumentRoot /var/www/html/www.example2.com/public_html
# Redirect permanent / https://www.example2.com/
</VirtualHost>
<VirtualHost *:443>
ServerName www.example1.com
ServerAlias example1.com
DocumentRoot /var/www/www.example1.com/public_html
CustomLog logs/www.example1.com.access_log combined
ErrorLog logs/www.example1.com.error_log
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.example1.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example1.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.example1.com/chain.pem
</VirtualHost>
<VirtualHost *:443>
ServerName www.example2.com
DocumentRoot /var/www/html/www.example2.com/public_html
CustomLog logs/www.example2.com.access_log combined
ErrorLog logs/www.example2.com.error_log
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.example2.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.example2.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.example2.com/chain.pem
</VirtualHost>
セキュリティ設定
脆弱性診断対策として古い暗号プロトコルや暗号スイートを排除します。
以下を末尾に追記します。上の方に同じ項目がありますが、そこを変えてもバーチャルホスト側で有効になりません。
/etc/httpd/conf.d/ssl.conf
SSLProtocol -all +TLSv1.2
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!3DES:!RC4:!DH
SSLHonorCipherOrder on
Header set Strict-Transport-Security "max-age=315360000;
CAAレコード追加
脆弱性診断への対策のため、DNSサーバ (ネームサーバ) でCAAレコードを追加します。
できない場合やわからない場合は読み飛ばしてください。ただし診断結果に若干影響する可能性があります。
example1.com. 3600 IN CAA 0 issue "letsencrypt.org"
example2com. 3600 IN CAA 0 issue "letsencrypt.org"
MPM変更
ApacheのMPMを古いPreforkからEventに切り替えます。
/etc/httpd/conf.modules.d/00-mpm.conf
# LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
LoadModule mpm_event_module modules/mod_mpm_event.so
チューニング
パフォーマンスチューニング設定です。環境に合わせて調整してください。
テストの結果、結局コア数に揃えるのが良いという情報を見たため以下のようにしています。
/etc/httpd/conf.d/mpm.conf
<IfModule mpm_event_module>
StartServers 4
MinSpareThreads 4
MaxSpareThreads 4
ThreadsPerChild 4
MaxRequestWorkers 4
MaxConnectionsPerChild 0
</IfModule>
モジュール版PHP廃止
PHP-FPM (FastCGI) を動かすため、mod_php(モジュール版)を使用しないよう設定します。
この設定は不要な場合があります。筆者の環境では下記ファイルは無く、作業不要でした。
mod_phpが読み込まれているかどうかはhttpd -M | grep php
で確認できます。
/etc/httpd/conf.modules.d/15-php.conf
<IfModule !mod_php5.c>
<IfModule prefork.c>
# LoadModule php7_module modules/libphp7.so
</IfModule>
</IfModule>
<IfModule !mod_php5.c>
<IfModule !prefork.c>
# LoadModule php7_module modules/libphp7-zts.so
</IfModule>
</IfModule>
PHP-FPMとのソケット通信を行う設定を追記します。SetHandlerに後述するソケットのパスを指定します。
/etc/httpd/conf.d/php.conf
<IfModule !mod_php5.c>
<IfModule !mod_php7.c>
# Enable http authorization headers
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
<FilesMatch \.(php|phar)$>
SetHandler "proxy:unix:var/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
</IfModule>
</IfModule>
Apacheが起動しない場合
以下のコマンドで起動時のエラー内容を表示できます。
systemctl status httpd
Apacheの設定内容が正しいかどうか、以下のコマンドで確認できます。
httpd -t
PHP-FPM
まずはPHPそのものの設定を行います。環境に合わせて調整してください。
/etc/php.ini
;expose_php = On
expose_php = Off
; max_execution_time = 30
max_execution_time = 120
; memory_limit = 128M
memory_limit = 256M
; post_max_size = 8M
post_max_size = 128M
; upload_max_filesize = 2M
upload_max_filesize = 128M
;date.timezone =
date.timezone = Asia/Tokyo
; session.gc_maxlifetime = 1440
session.gc_maxlifetime = 86400
ソケット通信
ユーザーとグループ、ソケット通信を行うための設定を行います。
user = apache
group = apache
; listen = 127.0.0.1:9000
listen = /var/run/php-fpm/www.sock
listen.owner = apache
listen.group = apache
;listen.acl_users = apache,nginx
チューニング
パフォーマンスチューニングの設定を行います。環境によって調整してください。
/etc/php-fpm.d/www.conf
; pm = dynamic
pm = static
; pm.max_children = 50
pm.max_children = 12
; pm.start_servers = 5
pm.start_servers = 4
; pm.min_spare_servers = 5
pm.min_spare_servers = 4
; pm.max_spare_servers = 35
pm.max_spare_servers = 4
ApacheとPHP-FPMを再起動します。
systemctl restart httpd php-fpm
これで正常に起動しない場合、各種設定の見直しをしてください。
詳細な動作状態は<?php phpinfo(); ?>
と書いたPHPファイルで確認できます。
参考:Composer
Laravel等で使用するcomposerをインストールしておきます。
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
参考:BASIC認証
www.example2.com全体をBASIC認証で保護する想定です。
生成サービスを利用してパスワードファイルを作成しておきます。
/var/www/html/www.example2.com/.htpasswd
{ユーザー名}:{暗号化されたパスワード}
.htaccessでBASIC認証を有効にします。
/var/www/html/www.example2.com/public_html/.htaccess
AuthType Basic
AuthName "Enter your ID and password"
AuthUserFile /var/www/html/www.example2.com/.htpasswd
require valid-user
chown -R dev. /var/www/html/www.example2.com