Amazon linux 2 の場合はこちら
EC2にssh接続しているとします。
まず、certbotをクローンします。
cd /usr/local
sudo git clone https://github.com/certbot/certbot
cd certbot
次に、証明書の作成を申請します。
申請するにあたって、Let's Encryptが認証するためのディレクトリを作成します。
(他の記事では/var/www/html
などとしている場合が多いですが、Amazon Linuxではデフォルトでそのようなディレクトリはないので、新たに作成します。)
# ディレクトリ名は自由ですが、今回は letsencrypt-webroot とします。
sudo mkdir /var/www/letsencrypt-webroot
さらに、nginxの設定を追加します。
# 【】は置き換えてください
sudo vi 【nginxの設定ファイルのパス(例:/etc/nginx/conf.d/myconf.conf)】
server {
listen 80;
...
# 以下を追加(^~は前方一致です)
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt-webroot;
}
}
その後、nginxを再起動します。
sudo service nginx restart
次に、以下のコマンドで認証可能かどうかを確認します。
(認証申請が1時間に5回Failすると、一定時間申請できなくなります(Rate Limits - Let's Encrypt - Free SSL/TLS Certificates)。そのため、先に認証可能かどうかを確認します。)
# 【】の所は置き換えてください
/usr/local/certbot/certbot-auto certonly --webroot --agree-tos --debug -m 【メールアドレス(例:○○@○○.com)】 -d 【ドメイン名(例:○○.com)】 -w /var/www/letsencrypt-webroot --dry-run
以下が出たら認証可能です。
IMPORTANT NOTES:
- The dry run was successful.
上のコマンドの--dry-run
を外して認証申請をします。
(登録されたメールアドレスには、Let's Encryptからの通知(認証の有効期限が近づいてきた時の通知など)が届きます。)
/usr/local/certbot/certbot-auto certonly --webroot --agree-tos --debug -m 【メールアドレス(例:○○@○○.com)】 -d 【ドメイン名(例:○○.com)】 -w /var/www/letsencrypt-webroot
以下が出たら認証成功です。
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/○○.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/○○.com/privkey.pem
Your cert will expire on 2019-07-30. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again. To non-interactively renew *all* of your certificates, run
"certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
証明書が発行されたかを確認します。
# 【】は置き換えてください。
sudo ls -lrth /etc/letsencrypt/live/【ドメイン名(例:○○.com)】/
以下が表示されればOKです。
total 4.0K
-rw-r--r-- 1 root root 692 May 1 11:41 README
lrwxrwxrwx 1 root root 51 May 1 11:41 privkey.pem -> ../../archive/【ドメイン名(例:○○.com)】/privkey1.pem
lrwxrwxrwx 1 root root 53 May 1 11:41 fullchain.pem -> ../../archive/【ドメイン名(例:○○.com)】/fullchain1.pem
lrwxrwxrwx 1 root root 49 May 1 11:41 chain.pem -> ../../archive/【ドメイン名(例:○○.com)】/chain1.pem
lrwxrwxrwx 1 root root 48 May 1 11:41 cert.pem -> ../../archive/【ドメイン名(例:○○.com)】/cert1.pem
次に、nginxの設定ファイルをSSL用に更新します。
# 【】は置き換えてください
sudo vi 【nginxの設定ファイルのパス(例:/etc/nginx/conf.d/myconf.conf)】
# 【】は置き換えてください。
# 1. server{}の中を以下の様に書きかえてください。
server {
# listenを80から443に変更
# listen 80;
listen 443 ssl;
location @app {
...
# 以下を追記
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
# 以下を追記
ssl_certificate /etc/letsencrypt/live/【ドメイン名(例:○○.com)】/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/【ドメイン名(例:○○.com)】/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
# 2. 以下を追加してください。
server {
listen 80;
server_name 【ドメイン名(例:○○.com)】;
return 301 https://$host$request_uri;
}
nginxを再起動します。
sudo service nginx restart
以上でSSLの設定は完了です。
ブラウザからこのサイトにアクセスしてみましょう。https接続になるはずです。
また、http://
として接続した場合でも、自動でhttps接続になるはずです。
Let's Encryptの有効期間は3カ月と短いです。
自動で更新されるように、crontabで設定しておきましょう。
sudo crontab -e # rootでcrontabを編集すれば、設定コマンド内でsudoを使わなくて済みます。
0 4 * * * /usr/local/certbot/certbot-auto renew --no-self-upgrade --debug --post-hook "service nginx restart"
※ --no-self-upgrade
を付ける事で、自動でバージョアップするのを防いでいます。(AWSドキュメントより)
※ --debug
を付けているのは、下記のエラーが出ないようにするためです。
※ --post-hook
で証明書更新後にNginxも再起動する様にしています。
FATAL: Amazon Linux support is very experimental at present...
if you would like to work on improving it, please ensure you have backups
and then run this script again with the --debug flag!
Alternatively, you can install OS dependencies yourself and run this script
again with --no-bootstrap.
この例では、毎日午前4時に自動で更新チェックがかかるようになります。
設定後、cronデーモンを再起動します。
sudo service crond restart
Amazon Linux 2の場合
上記の方法では Amazon Linux 2 でエラーが出ます。この場合は、こちらを行なったあと、Nginxの設定ファイルに以下の追記をしてください。( 【ドメイン名(例:○○.com)】
は置き換えてください。)その後、sudo service nginx restart
をしてください。
server {
# listen 80 のようになっていると思います。これを以下のように変えてください。
listen 443 ssl;
# ドメイン名は変更してください!
server_name 【ドメイン名(例:○○.com)】;
location @app {
...
# 以下を追記 ------------------------------------
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# ---------------------------------------------
}
# 以下を追記 ------------------------------------
# ドメイン名は変更してください!(2箇所)
ssl_certificate /etc/letsencrypt/live/【ドメイン名(例:○○.com)】/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/【ドメイン名(例:○○.com)】/privkey.pem
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ---------------------------------------------
}
# 以下を追記 ------------------------------------
# httpでのアクセスをhttpsに転送する設定です。
# ドメイン名は変更してください!
server {
listen 80;
server_name 【ドメイン名(例:○○.com)】;
return 301 https://$host$request_uri;
}
# ----------------------------------------------
追記
上記の参照サイトでのcrontabの設定は、以下のように書き換えても良いかもしれません。root
を消して(私の環境では動かなかったため)、service nginx restart
を追加しています。
# before
0 0,12 * * * root certbot renew --no-self-upgrade
# after
0 0,12 * * * certbot renew --no-self-upgrade && service nginx restart
追記
crontabのコマンドをさらに改変しても良いでしょう。
-
0,12 時に実行
→4時に実行
(1回で十分なので) -
post-hook
としてservice nginx restart
を設定して、証明書の更新が行われた時だけNginxも更新する様にする。
0 4 * * * certbot renew --no-self-upgrade --post-hook "service nginx restart"
参考
Nginx Rails unicorn HTTPS SSL 対応 - Qiita
【Ruby on Rails】Nginxとunicornを使ってHTTPS(SSL)対応する方法 | Y-hilite
Let's Encrypt で Nginx にSSLを設定する - Qiita