サーバ構築・管理

AWS EC2でサーバを構築 3 – Apache + Let’s Ecnrypt + PHP-FPM編 (脆弱性診断「A+」を狙う)

AWSのEC2でセキュアなサーバ構築をするシリーズその3です。ApacheとLet’s Ecnrypt、PHP-FPMを設定します(Nginxへ移行しました)。

記事一覧

  1. Amazon Linux 2 準備編
  2. 各種インストール編
  3. Apache + Let's Ecnrypt + PHP-FPM編 (脆弱性診断「A+」を狙う)
  4. Nginx + Let's Ecnrypt + PHP-FPM編 (脆弱性診断「A+」を狙う)
  5. MySQL + phpMyAdmin
  6. PostfixとDovecot (SSL対応とSPAM対策)
  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
ABOUT ME
りゅう・д・
愛知のWeb系エンジニア/クリエイターです。 サーバ構築・管理からシステム開発、Webデザイン、WordPress構築からヘルプデスクまで、割と手広く手掛けています。

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です