Help us understand the problem. What is going on with this article?

[Rails][Nginx][AWS] Let's EncryptをEC2上のRailsに入れてHttpsにする

Amazon linux 2 の場合はこちら


EC2にssh接続しているとします。
まず、certbotをクローンします。

terminal
cd /usr/local
sudo git clone https://github.com/certbot/certbot
cd certbot

次に、証明書の作成を申請します。

申請するにあたって、Let's Encryptが認証するためのディレクトリを作成します。
(他の記事では/var/www/htmlなどとしている場合が多いですが、Amazon Linuxではデフォルトでそのようなディレクトリはないので、新たに作成します。)

terminal
# ディレクトリ名は自由ですが、今回は letsencrypt-webroot とします。
sudo mkdir /var/www/letsencrypt-webroot

さらに、nginxの設定を追加します。

terminal
# 【】は置き換えてください
sudo vi 【nginxの設定ファイルのパス(例:/etc/nginx/conf.d/myconf.conf)】
nginxの設定ファイル
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)。そのため、先に認証可能かどうかを確認します。)

terminal
# 【】の所は置き換えてください
/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からの通知(認証の有効期限が近づいてきた時の通知など)が届きます。)

terminal
/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

証明書が発行されたかを確認します。

terminal
# 【】は置き換えてください。
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用に更新します。

terminal
# 【】は置き換えてください
sudo vi 【nginxの設定ファイルのパス(例:/etc/nginx/conf.d/myconf.conf)】
nginxの設定ファイル
# 【】は置き換えてください。

# 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を再起動します。

terminal
sudo service nginx restart

以上でSSLの設定は完了です。
ブラウザからこのサイトにアクセスしてみましょう。https接続になるはずです。
また、http://として接続した場合でも、自動でhttps接続になるはずです。


Let's Encryptの有効期間は3カ月と短いです。
自動で更新されるように、crontabで設定しておきましょう。

terminal
sudo crontab -e # rootでcrontabを編集すれば、設定コマンド内でsudoを使わなくて済みます。
crontab
0 4 1 * * /usr/local/certbot/certbot-auto renew --no-self-upgrade --debug && service nginx restart

--no-self-upgradeを付ける事で、自動でバージョアップするのを防いでいます。(AWSドキュメントより)

--debugを付けているのは、下記のエラーが出ないようにするためです。

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.

この例では、毎月1日午前4時に自動で更新されるようになります。

設定後、cronデーモンを再起動します。

terminal
sudo service crond restart

Amazon Linux 2の場合

上記の方法では Amazon Linux 2 でエラーが出ます。この場合は、こちらを行なったあと、Nginxの設定ファイルに以下の追記をしてください。(【ドメイン名(例:○○.com)】は置き換えてください。)その後、sudo service nginx restartをしてください。

nginxの設定ファイル
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を追加しています。

crontab
# before
0 0,12 * * * root certbot renew --no-self-upgrade

# after
0 0,12 * * *      certbot renew --no-self-upgrade && service nginx restart

参考

Nginx Rails unicorn HTTPS SSL 対応 - Qiita
【Ruby on Rails】Nginxとunicornを使ってHTTPS(SSL)対応する方法 | Y-hilite
Let's Encrypt で Nginx にSSLを設定する - Qiita

Masahiro_T
困ったときの再起動
InoueLab
確率的な情報処理について研究する研究室のリソースとサーバーを管理・保守・運用する学生団体
http://www.inoue.eb.waseda.ac.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした