nginx と dehydrated の組み合わせで ACME クライアントを用いたお手軽 ssl 対応 web サーバの構築 IPv6専用


FreeBSD 11.2-RELEASE が前提ですが、執筆時点では 10.4-RELEASE や 12-current でも適応可能です。
また本記事は FreeBSD 経験者を対象に書いているので、事細かい配慮はされていません。

下準備

OS は最新のパッチが当たっていることと、ports skeleton もなるべく最新のものに同期していること。
IPv6 でインターネット接続されていること。

アプリケーションの導入

ports から以下のパッケージをインスコする。

  • www/nginx
  • security/dehydrated

ACME クライアント取得用アカウント作成

以下のコマンドを実行して ACME アカウントを発行します。

# dehydrated --register --accept-terms --ipv6 --domain %%HOSTNAME%% --ocsp --challenge http-01

%%HOSTNAME%% の箇所は今後使用予定の web サーバアドレスで、実際にインターネット網からアクセス出来るアドレスである事。
これが出来てないとこの先には進めないので注意。
また、%%HOSTNAME%% は全て半角小文字である事に注意。
日本語ドメインで利用する場合は自動変換しないので、予め IDN で Punycode 化したドメイン名を指定する事。

ACME クライアントの認証用に用いる特定ディレクトリの設定

nginx の設定で server 節内に以下の alias を追記します。

nginx.conf
        location ^~ /.well-known/acme-challenge/ {
            alias /usr/local/www/dehydrated/;
        }

証明書発行作業

# dehydrated --cron --ipv6 --domain %%HOSTNAME%% --ocsp --challenge http-01

問題が無ければ以下のディレクトリに証明書と個人鍵などが作成されているはずです。

/usr/local/etc/dehydrated/certs/%%HOSTNAME%%/

作成されるファイル名 (実際は静的リンク)

  • cert.csr
  • cert.pem
  • chain.pem
  • fullchain.pem
  • privkey.pem

nginx に作成された証明書を書き入れて ssl の準備

先ほど server 節内に追記した箇所とは別に、新しく server 節を書き足します。

nginx.conf
    server {
        listen [::]:443 ssl http2;
        ssl_certificate /usr/local/etc/dehydrated/certs/%%HOSTNAME%%/fullchain.pem;
        ssl_certificate_key /usr/local/etc/dehydrated/certs/%%HOSTNAME%%/privkey.pem;
        ssl_trusted_certificate /usr/local/etc/dehydrated/certs/%%HOSTNAME%%/cert.pem;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_protocols tlsv1.1 tlsv1.2 tlsv1.3;
        ssl_prefer_server_ciphers on;
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
        resolver [2001:4860:4860::8844] [2001:4860:4860::8888] valid=60s ipv6=on;
        resolver_timeout 5s;
    }

nginx の再起動

# service nginx reload

証明書の有効期限を自動更新

毎週定期的に更新 script を実行させる設定をする。

/etc/periodic.conf.local
weekly_dehydrated_enable="YES"
weekly_dehydrated_flags="--ipv6 --domain %%HOSTNAME%%"

証明書の自動更新後、nginx にも伝えてあげないと古い証明書を握ったままなので、デプロイスルクリプトを作成して、nginx の config をリロードさせる。

/usr/local/etc/dehydrated/deploy.sh
#!/bin/sh
/usr/local/sbin/nginx -s reload

当然、シェルスクリプトなので、実行権限も与えておくことを忘れないように。

chmod +x /usr/local/etc/dehydrated/deploy.sh

先ほど編集した periodic.conf.local にもこのデプロイスクリプトを指定させておく。

/etc/periodic.conf.local
weekly_dehydrated_deployscript="/usr/local/etc/dehydrated/deploy.sh"

おしまい🙌