Let’s Encrypt で nginx に HTTPS を設定 (TLS 証明書を発行)

Let's Encrypt

Let's Encrypt とは、TLS 証明書を無料で発行する証明書認証局です。

certbot というツールを利用し、Let's Encrypt の認証局から TLS 証明書を発行します。

本記事では、これらを利用して、Web サーバー (nginx) を HTTPS 化します。

関連記事:サーバー
スポンサーリンク

Let's Encrypt (certbot) の使い方

本記事の前提条件は以下のとおりです。

事前準備

sudo yum install nginx -y
sudo vim /etc/nginx/nginx.conf

server_name ディレクティブで TLS 証明書を発行するドメイン名を指定します。(ドメイン名 (example.com) は、あなたのドメイン名に置き換えてください

    server {
        listen       80;
        listen       [::]:80;
        #server_name  _; #変更前
        server_name  example.com;#変更後
sudo systemctl start nginx

certbot のインストール

sudo yum install -y certbot python-certbot-nginx

certbot で Let's Encrypt から TLS 証明書を発行・設定

以下の certbot のコマンドで TLS 証明書の発行から、nginx の設定までが自動で行われます。

nginx の設定ファイルを手動で変更したい場合は、代わりに「sudo certbot certonly --nginx」コマンドを利用します。

sudo certbot --nginx --agree-tos
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): hoge@foo.bar(#メールアドレス)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N (#あなたにメール送りたいけどいい?)

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1(#HTTPS 化する server_name の番号を選択)

動作確認

アクセスするドメイン名は発行した証明書のドメイン名に置き換えてください。

curl https://example.com -I
HTTP/1.1 200 OK

Let's Encrypt の TLS 証明書を自動更新

cron を利用して、TLS 証明書の更新コマンド「certbot renew --no-self-upgrade」を自動で実行します。

sudo vim /etc/crontab
0      12    *       *       *       root    certbot renew --no-self-upgrade
sudo systemctl restart crond
スポンサーリンク

Docker + Let's Encrypt + nginx

Docker を利用した Certbot では、nginx に手動で証明書をインストールする必要があります。

Because Certonly cannot install the certificate from within Docker, you must install the certificate manually according to the procedure recommended by the provider of your webserver.

https://eff-certbot.readthedocs.io/en/stable/install.html#running-with-docker

そのため、/etc/nginx/nginx.conf に HTTPS の設定を手動でする必要があり、面倒です。

そこで、Certbot と https-portal の2つの方法を紹介します。

Certbot 証明書を取得

export DOMAIN=example.com

赤線箇所は自身のドメイン名に置き換えてください。

version: "3"
services:
  nginx:
    image: nginx:alpine
    restart: always
    container_name: nginx
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
      - html:/usr/share/nginx/html/
    ports:
      - "80:80"

  certbot:
    image: certbot/certbot:v1.7.0
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
      - html:/usr/share/nginx/html/
    depends_on:
      - nginx
    entrypoint: ["certbot", "certonly", "-d $DOMAIN", "-m hoge@foo.bar", "--agree-tos","--webroot", "-w","/usr/share/nginx/html/"]

volumes:
  html:
test_certbot_1 exited with code 0

exit status が 0 なら証明書作成が成功です。Ctrl + C でコンテナを終了します。
(既に /etc/letsencrypt に証明書がある場合は、docker-compose.yml で別のパスを指定してください。)

sudo ls /etc/letsencrypt/live/

https-portal で証明書の取得と HTTPS の設定

https-portal は、クライアントと HTTPS を行うプロキシです。

https-portal コンテナ側の nginx で HTTPS が終端します。
(nginx コンテナ側の /etc/nginx/nginx.conf を変更するわけではありません。)

export DOMAIN=example.com

赤線箇所は自身のドメイン名に置き換えてください。

version: "3"
services:
  nginx:
    image: nginx:alpine
    restart: always
    container_name: nginx
    ports:
      - "80"

  https-portal:
    image: steveltn/https-portal:1
    ports:
      - "80:80"
      - "443:443"
    links:
    - nginx
    restart: always
    environment:
      DOMAINS: "$DOMAIN -> http://nginx"
      STAGE: 'production'
      HSTS_MAX_AGE: 60 # 秒。次のアクセスから HTTPS を強制する
      CLIENT_MAX_BODY_SIZE: 10M # アップロード制限
    volumes:
      - /tmp/cert/:/var/lib/https-portal
https-portal_1  | [services.d] done.

「https-portal_1  | [services.d] done.」が表示されるまでしばらく待ちます。

curl "https://$DOMAIN"

別の端末で curl をする場合は、"$DOMAIN" 環境変数に、あなたのドメインが設定されていることを確認してください。

なお、証明書は「ホスト側:/tmp/cert/」、「コンテナ側:/var/lib/https-portal/」にあります。

スポンサーリンク

関連記事

関連記事:サーバー

参考資料

ドキュメント - Let's Encrypt - フリーな SSL/TLS 証明書
Let's Encryptは、非営利団体の Internet Security Research Group (ISRG) が提供する自動化されたフリーでオープンな認証局です。