nginxで立ち上げたサイトにSSL接続する方法について、ハマったポイント

概要

Let's Encryptのcertbotの証明書を用いて、nginxにてVirtualHost + SSL対応サイトを作成するにあたり、多くのポイントでハマったので、その対応を記載する。

結論

以下のように実行すればいい

  • nginxの設定ファイルを以下のように作成

>設定ファイル

$cat /etc/nginx/sites-enabled/ドメイン
server {
    listen 80;
    listen 443 ssl; 

    server_name ドメイン;

    access_log /var/log/nginx/ドメイン/access.log;
    error_log /var/log/nginx/ドメイン/error.log;
        
    # for Let's Encrypt
        location ^~ /.well-known/ {
            root /var/www/certbot/ドメイン;
            }

    location / {
        root var/www/nginx/ドメイン/public/; #/srv以下に置く場合もある
        index index.html;
        }
    }

$ sudo certbot certonly --webroot -w /var/www/certbot/ドメイン -d ドメイン
  • 発行された証明書と秘密鍵に基づき、nginxの設定ファイルを以下のように修正

>設定ファイル

$cat /etc/nginx/sites-enabled/ドメイン
server {
    listen 80;
    listen 443 ssl; 

    server_name ドメイン;

    ssl_certificate      /etc/letsencrypt/live/ドメイン/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/ドメイン/privkey.pem;

    ssl_protocols        SSLv3 TLSv1 TLSv1.2 TLSv1.3;
    ssl_ciphers          HIGH:!aNULL:!MD5;

    ssl_prefer_server_ciphers   on;
    
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;

    access_log /var/log/nginx/ドメイン/access.log;
    error_log /var/log/nginx/ドメイン/error.log;
        
    # for Let's Encrypt
        location ^~ /.well-known/ {
            root /var/www/certbot/ドメイン;
            }

    location = /favicon.ico {
        access_log off;
        empty_gif;
        expires 30d;
        }

    location / {
        root var/www/nginx/ドメイン/public/; #/srv以下に置く場合もある
        index index.html;
        }
    }

詳細

環境

サーバのOS: Debian 11.9

openssl version: 1.1.1w

opensslの対応している暗号スイート: SSLv3, TLSv1, TLSv1.2, TLSv1.3

インストールしたLet's Encryptのcerbot: My HTTP website is running Nginx on Debian 10

目的

Nginxで作成したVirtualHostのサイトをSSL対応したい。そのため、Let's Encryptのcerbotにて証明書と秘密鍵を発行してもらい、Nginxの設定にその二つを反映。最終的にhttps://ドメインで接続時にエラーが出ないことを目指す。

注意点

証明書発行前のnginxの設定ファイルと注意点

証明書発行前に以下の記述が設定ファイルが無いとエラーが発生する。

# for Let's Encrypt
location ^~ /.well-known/ {
root /var/www/certbot/ドメイン;
}

具体的には

$ sudo certbot certonly --webroot -w /var/www/certbot/ドメイン -d ドメイン
Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
  Domain: ドメイン
  Type:   unauthorized
  Detail: IPアドレス: Invalid response from http://ドメイン/.well-known/acme-challenge/X76XrlQfm_JipU1R1VBUpadovI_ENSzM2Zb_1Mf_gno: 404

Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot. Ensure that the listed domains serve their content from the provided --webroot-path/-w and that files created there can be downloaded from the internet.

Some challenges have failed.

というエラーが発生する。certbotは初めてHTTPS 証明書を発行する場合, http://ドメイン/.well-known/acme-challenge/ にアクセスすることで認証を行う。そのため、先のアドレスに接続したときに403エラー(閲覧禁止)が出ないように、404エラーを返すようにする設定が必要である。

参考:

Let’s EncryptによるSSLサーバー証明書の取得、自動更新設定(2021年3月版) | 稲葉サーバーデザイン

Let’s Encrypt で証明書を発行して運用するための nginx の設定 - ymyzk’s blog

証明書発行後のnginxの設定ファイルと注意点

二点注意点がある。

SSLv3とTLSv1では接続不可

以下の設定において、TLSv1.2 TLSv1.3を削除すると、接続に失敗する。これは現在のChromeがTLS1.1未満に対応していないからである。

ssl_protocols        SSLv3 TLSv1 TLSv1.2 TLSv1.3;
ssl_ciphers          HIGH:!aNULL:!MD5;

参考:

TLS 1.0/1.1サイトは完全にブロック ~「Google Chrome 98」安定版がリリース - 窓の杜

favicon設定が必要

以下のようなfaviconを設定しておかないと、エラーログでエラーが出てしまう。以下は、空の図形を返すようにしている。

 location = /favicon.ico {
        access_log off;
        empty_gif;
        expires 30d;
        }

参考:

Nginxで適当なfaviconを設定する #nginx - Qiita

その他の注意点

httpsサイトとして問題ないかチェック

以下のサイトで立ち上げたサイトをチェックする。

Ready to check - Nu Html Checker

ディレクトリ構成を意識する

logファイルなどは/var以下に置くなど、Linuxディレクトリ構成を意識して配置する。

参考: Debian公式リファレンス https://www.debian.org/releases/bookworm/amd64/apcs02.en.html https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04.html#purpose18 https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05.html#purpose31

Linuxディレクトリ構造 #Linux - Qiita

Linux のディレクトリ構造 #Linux - Qiita