thumbnail

【SSL】ec2 + nginx + certbot

2022/06/22

certbotによるSSL通信設定。 作業量自体は大したことないですが、毎回手順を調べて無駄に時間がかかることが多かったので備忘録としてまとめてみました。

尚、domainの取得とルーティング設定は終わってる前提です。

手順まとめ

コマンドだけ知りたい人(自分)向けに、先に全手順をまとめておきます。 各コマンドの説明は後半に書いているので、詳細を知りたい場合はそちらをご参考ください。

nginxのインストール

$ sudo amazon-linux-extras install nginx1
$ nginx -v
nginx version: nginx/1.20.0

nginxの起動およびインスタンス起動時のnginx起動有効化

$ sudo systemctl enable --now nginx
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since 土 2022-06-18 09:07:59 UTC; 5s ago

サードパーティ製のリポジトリepel (Extra Packages for Enterprise Linux)をインストール後 certbot本体、certbotのnginx設定用ライブラリをインストール

$ sudo amazon-linux-extras install -y epel
$ sudo yum install -y certbot python2-certbot-nginx

nginx.confserver_nameを登録したドメインに変更

nginx.conf
    server {
        # ↓のserver_nameを登録したdomainに変更
        server_name  _;
        root         /usr/share/nginx/html;

        # port forwardingしたい場合は↓を追加
        location / {
                proxy_set_header Host $http_host;
                proxy_pass http://localhost:<PORT>;
        }

certbotを実行、質問に答えて証明書を取得 (python2-certbot-nginxによりSSLも自動的に設定される)

$ sudo certbot --nginx

証明書自動更新後のnginx reloadのために/etc/sysconfig/certbotを編集

$ sudo vim /etc/sysconfig/certbot
/etc/sysconfig/certbot
POST_HOOK="--post-hook 'systemctl reload nginx'"

証明書自動更新サービスを有効化

 sudo systemctl enable --now certbot-renew.timer

自動更新サービスの次回実行日時を確認

$ sudo systemctl list-timers
NEXT                         LEFT     LAST                         PASSED UNIT                         ACTIVATES
日 2022-06-19 04:05:51 UTC  15h left n/a                          n/a    certbot-renew.timer          certbot-renew.service
日 2022-06-19 05:01:01 UTC  16h left 土 2022-06-18 05:01:01 UTC  7h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

以上でnginx + certbotの設定は完了です。

各手順の内容

nginxのインストール、起動

nginxはAWSがAmazon Linux用のパッケージを用意してくれているので、amazon-linux-extrasからnginxをインストールします(Amazon Linux出ない場合は普通にyumaptでインストールします)。

$ sudo amazon-linux-extras install nginx1
$ nginx -v
nginx version: nginx/1.20.0

nginxをインストールできたらsystemctl enable --nowでnginxを起動します。 ※ systemctl enableは通常、インスタンス起動時に実行すサービスを登録するためのコマンドですが、--nowオプションを使用することで同時にサービスを起動してくれます。

$ sudo systemctl enable --now nginx
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since 土 2022-06-18 09:07:59 UTC; 5s ago

この時点で以下のようにhttp通信はできるようになっていると思います。

nginx-http

certbotのインストール

certbotはサードパーティ製のリポジトリepel (Extra Packages for Enterprise Linux)で管理されているので、先にepelをinstallしておきます。

$ sudo amazon-linux-extras install -y epel

epelをインストールできたら、certbot本体とcertbotのnginx設定用ライブラリpython2-certbot-nginxをインストールします。

$ sudo yum install -y certbot python2-certbot-nginx

python2-certbot-nginxをインストールしておくことで、certbot実行時にnginx.confにSSL通信の設定が自動で追加されます。

certbotによるSSL通信の有効化

certbotを用いた証明書の取得を行う際に、自動でnginxの設定がカスタマイズされるようにまずはnginxの初期設定を行っておきます。 初期設定といっても、これから取得する証明書に利用するドメインをserver_nameに記載しておくだけです。

nginx.conf
    server {
        # ↓のserver_nameを登録したdomainに変更
        server_name  _;
        root         /usr/share/nginx/html;

        # port forwardingしたい場合は↓を追加
        location / {
                proxy_set_header Host $http_host;
                proxy_pass http://localhost:<PORT>;
        }

nginx.confが設定できたら、certbotを実行します。 実行後メールアドレスやドメインを聞かれるので、それに答えると証明書が発行されます。

$ sudo certbot --nginx

このとき、証明書発行後certbotによってnginx.confにSSL設定が追加されます。 certbotによって追加された項目には# managed by Certbotのコメントがついています。

nginx.conf
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot

自分でnginx.confを弄くりたい場合はcertonlyをつけることで、証明書発行のみが行われます。

$ sudo certbot certonly --nginx

この時点で、https通信が可能になっていると思います。

証明書更新の自動化

最後にLet's Encryptの証明書は3ヶ月で切れるので、自動更新を有効化します。

certbot内部には、「certbot-renew.timer」というserviceファイルが入っているのでそれを有効化することで自動更新が行われるようになります。

ただし、証明書の自動更新後はnginxのreloadを行う必要があるので、/etc/sysconfig/certbotPOST_HOOKにnginx reloadを先に設定しておきます。

$ sudo vim /etc/sysconfig/certbot
/etc/sysconfig/certbot
POST_HOOK="--post-hook 'systemctl reload nginx'"

これによりcertbot-renew.timerによる証明書更新後にnginxがreloadされるようになります。

POST_HOOKの設定ができたら、systemctl enable --nowでcertbot-renew.timerサービスを有効化します。

 sudo systemctl enable --now certbot-renew.timer

サービス有効化後は以下のコマンドで、次回証明書更新の実行日時を確認できます。

$ sudo systemctl list-timers
NEXT                         LEFT     LAST                         PASSED UNIT                         ACTIVATES
日 2022-06-19 04:05:51 UTC  15h left n/a                          n/a    certbot-renew.timer          certbot-renew.service
日 2022-06-19 05:01:01 UTC  16h left 土 2022-06-18 05:01:01 UTC  7h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

上記の例では、2022-06-19に実行される予定になっています。

※ certbot-renew.timerを使わない場合はcronで自動証明書更新を行うことも可能です。その場合はcrontab -eで以下のようにcronを設定します。

cron
0 0 * * * root /usr/bin/certbot renew --post-hook "/bin/systemctl reload nginx.service"
author picture

Mitsuru Takahashi

京都市内にてフリーランスエンジニアとして活動しています。

detail

Profile

author picture

Mitsuru Takahashi

京都市内にてフリーランスエンジニアとして活動しています。

detail

© 2022 mitsuru takahashi