0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-04-14

記事一覧

概要

ウェブサーバにApacheを使用する場合、本記事は読み飛ばしてください。

Nginx、SSL (Let's Ecnrypt)、PHP-FPMの設定を行います。また脆弱性診断で最高の「A+」を狙います。

Apacheを設定済みの場合は削除するか、systemctl disable httpdしておいてください。削除を推奨します。

脆弱性診断結果

結論から書いてしまいますが、以下の設定でSSL Labsの脆弱性診断を行ったところ最高の「A+」となりました。

20200413_131134.png

当初は「A」でしたが、設定を見直して「A+」を達成できました。以下の通りの設定で「執筆時点では」「A+」になるはずです。

Nginx

エラー画面でバージョンを吐かないようにし、SSLに関するデフォルト設定を書いておきます。

ここが脆弱性診断「A+」のキモとなります。

注意:以下はserverではなくhttpディレクティブに追加してください。

/etc/nginx/nginx.conf

    server_tokens       off;

    ssl_protocols TLSv1.2; 
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout  1d;
    ssl_ciphers HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA:!3DES:!RC4:!DH;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

Amazon Linux 2のOpenSSLが1.0.2kなので、OpenSSL 1.1.1以降が必要となるTLSv1.3は設定できません。

バーチャルホスト

バーチャルホスト用に公開ディレクトリを作成しておきます。

Apacheとの互換を維持するため、var/wwwで始まりpublic_htmlで終わるようにしています。

mkdir -p /var/www/html/www.example1.com/public_html
mkdir -p /var/www/html/www.example2.com/public_html
chown -R nginx. /var/www/html

Let's Ecnryptの証明書取得時にはssl_certificatessl_certificate_keyの行はコメントアウトしておきます。

また設定ファイル内でドメイン正規化 (wwwありに統一) を行います。Apacheの.htaccessが使えないためです。

/etc/nginx/conf.d/www.example1.com.conf

server {
    listen      80;
    listen      443 ssl http2;
    server_name example1.com;
    return 301  https://www.$host$request_uri;

   ssl_certificate     "/etc/letsencrypt/live/example1.com/fullchain.pem";
   ssl_certificate_key "/etc/letsencrypt/live/example1.com/privkey.pem";

   include /etc/nginx/default.d/*.conf;
}

server {
    listen      80;
    server_name www.example1.com;
    root        /var/www/html/www.example1.com/public_html;
    return 301  https://$host$request_uri;
}

server {
   listen       443 ssl http2;
   server_name  www.example1.com;
   root         /var/www/html/www.example1.com/public_html;

   ssl_certificate     "/etc/letsencrypt/live/www.example1.com/fullchain.pem";
   ssl_certificate_key "/etc/letsencrypt/live/www.example1.com/privkey.pem";

   include /etc/nginx/default.d/*.conf;

   location / {
   }

   error_page 404 /404.html;
       location = /40x.html {
   }

   error_page 500 502 503 504 /50x.html;
       location = /50x.html {
   }
}

Aapcheの例と同じく、www.example2.comはBASIC認証を設定します。

生成サービスを利用して暗号化パスワードを生成しておきます。

/var/www/html/www.example2.com/.htpasswd

{ユーザー名}:{暗号化されたパスワード}

Apacheと異なり.htaccessが使えないため、設定ファイル内にBASIC認証の設定を記述します。

/etc/nginx/conf.d/www.example2.com.conf

server {
   listen      80;
   server_name www.example2.com;
   root        /var/www/html/www.example2.com/public_html;
   return 301  https://$host$request_uri;
}

server {
  listen       443 ssl http2;
  server_name  www.example2.com;
  root         /var/www/html/www.example2.com/public_html;

  ssl_certificate     "/etc/letsencrypt/live/www.example2.com/fullchain.pem";
  ssl_certificate_key "/etc/letsencrypt/live/www.example2.com/privkey.pem";

  include /etc/nginx/default.d/*.conf;

  location / {
      auth_basic "Enter your ID and Password";
      auth_basic_user_file /var/www/html/www.example2.com/.htpasswd;
  }

  error_page 404 /404.html;
      location = /40x.html {
  }
  
  error_page 500 502 503 504 /50x.html;
      location = /50x.html {
  }
}

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@example1.com

証明書の自動更新

月曜と木曜の4時0分に自動更新されるようにします。

Let's Ecnrypt証明書の期限は3ヶ月です。更新は週に5回までの制限があります。

crontab -e
0 4 * * 1,4  certbot renew --post-hook "systemctl restart nginx php-fpm postfix dovecot"

CAAレコード追加

脆弱性診断への対策のため、DNSサーバ (ネームサーバ) でCAAレコードを追加します。

できない場合やわからない場合は読み飛ばしてください。ただし診断結果に若干影響する可能性があります。

example1.com. 3600 IN CAA 0 issue "letsencrypt.org"
example2com. 3600 IN CAA 0 issue "letsencrypt.org"

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

チューニング

実行ユーザー/グループの設定とパフォーマンスチューニングの設定を行います。環境によって調整してください。

/etc/php-fpm.d/www.conf

; user = apache
user = nginx

; group = apache
group = nginx

;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

; pm.max_children = 50
pm.max_children = 30

; pm.start_servers = 5
pm.start_servers = 10

; pm.min_spare_servers = 5
pm.min_spare_servers = 10

; pm.max_spare_servers = 35
pm.max_spare_servers = 25

;pm.max_requests = 500
pm.max_requests = 30

NginxとPHP-FPMを再起動します。これは設定を変更するたびに行います。

systemctl restart nginx php-fpm

Composer

Laravel等で使用するcomposerをインストールしておきます。

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

トラブルシューティング

/var/lib/php内のセッションやキャッシュ用ディレクトリの所有グループがapacheになっている場合の対処法です。

chgrp nginx /var/lib/php/opcache
chgrp nginx /var/lib/php/session
chgrp nginx /var/lib/php/wsdlcache

セッションについては中のファイルがapache:apacheな状態になっている場合があるので修正。

chown nginx. /var/lib/php/sesion/*
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?