ブログ

SSL/TLS証明書の有効期限短縮について

SSL/TLS証明書の最大有効期限の段階的な短縮スケジュールについて以前弊社ブログで紹介させていただきました。今回はそのブログに関連する内容となりますので、まだご覧になられていない方は、まず下記のブログを参照いただけると幸いです。

上記ブログでは、SSL/TLS証明書の最大有効期間の短縮スケジュールおよびACMEの紹介、F5の3つのプロダクトにおける証明書有効期限短縮に関する対応状況についての紹介を行いました。

本執筆時点(2026年4月)ではすでに段階的な証明書有効期限の短縮が進み、有効期限は最長で200日(2026年3月15日~)となっています。すでに期限短縮の対応を済ませたお客様も多い一方で、対応方針を検討中の方もいらっしゃるのではないでしょうか。

そんなお客様に向けて、NGINX Plusの証明書自動更新モジュールについて、動作を踏まえた解説を行っていきます。

NGINX Plus における
ACMEのサポート状況

NGINX Plusはモジュール型アーキテクチャを採用しています。モジュールをインストール、ロードすることで、新しい機能を簡単に使い始めることができます。

Dynamic Modules
https://docs.nginx.com/nginx/admin-guide/dynamic-modules/dynamic-modules/

このモジュールの一つに、今回紹介するACMEモジュールがあります。

ACMEモジュール
https://docs.nginx.com/nginx/admin-guide/dynamic-modules/acme/
ACME の概要については以前のブログで解説しているため、本記事では省略します

なお、ACMEモジュールがサポートされるのはNGINX Plus R35以降となります。

NGINX Plus Release 35
https://docs.nginx.com/nginx/releases/#r35
---
Automated Certificate Management Environment (ACME) protocol support.
---

R36ではTLS-ALPN-01チャレンジのサポートなどの機能追加も行われており、今後も機能拡張が行われることが期待されます。

NGINX Plus Release 36
https://docs.nginx.com/nginx/releases/#r36
---
ACME enhancements for certificate automation: support for ACME challenges and keys for external account authorization.
---

R36ACMEモジュールはHTTP-01 / TLS-ALPN-01ACMEチャレンジタイプをサポートしております。

ACMEモジュール challenge
https://nginx.org/en/docs/http/ngx_http_acme_module.html#challenge

ACMEチャレンジとは、証明書更新対象のドメイン所有の確認を行う方法です。本ブログではデフォルト設定のHTTP-01での動作をご紹介します。HTTP-01は、Webサーバ / 認証局間でHTTP通信により特定の応答を返せるかどうかで、ドメイン所有していることを証明する方式です。

NGINX Plus ACMEモジュールの利用方法

NGINX ACMEモジュールの公式ドキュメントは下記で公開されています。

https://docs.nginx.com/nginx/admin-guide/dynamic-modules/acme/

そのため、基本的には上記のガイドに従って設定を行うことで、ACME モジュールを利用できます。

なお、本ブログではFirewalldSELinuxなどのOSに関する設定はすでに実施済みであることを前提とします。

セットアップ作業としては、大きく分けて下記2つの工程から成ります。
ACMEモジュールのインストール作業
NGINXコンフィグの設定作業

インストール作業では、NGINX Plusをインストール済みのホストにACME モジュールのインストールを行い、ACME を利用するための環境を構築します。設定作業では、サーバブロックの定義ファイル作成など、証明書の発行および更新に必要な設定を行います。

それでは各作業を実際に行っていきましょう。

ACMEモジュールのインストール作業

実施する内容は下記となります。

NGINX Plusバージョン確認
ACMEモジュールのインストール
ACMEモジュールの有効化

上記の流れに則り、実際の設定内容を確認していきましょう。

    NGINX Plusバージョン確認

繰り返しにはなりますが、ACMEモジュールはNGINX Plus R35からサポートされているため、まずはNGINX Plusのバージョンを確認します。

本検証では現時点(20264)の最新リリースであるR36を利用します。
また、今回利用するLinuxディストリビューションはAlmaLinuxとなります。

# nginx -v
nginx version: nginx/1.29.3 (nginx-plus-r36-p2)
#
# cat /etc/os-release
NAME="AlmaLinux"
VERSION="9.7 (Moss Jungle Cat)"

ACMEモジュールのインストール

NGINX Plusリポジトリにアクセスするため、MyF5 Customer Portalからnginx-repo.crtファイルとnginx-repo.keyファイルを入手し、/etc/ssl/nginx/ディレクトリに配置します。
NGINX Plusインストール時に配置・利用したものが残っている場合はそちらを利用いただけます。

# ls /etc/ssl/nginx/nginx-repo.crt
/etc/ssl/nginx/nginx-repo.crt
# ls /etc/ssl/nginx/nginx-repo.key
/etc/ssl/nginx/nginx-repo.key
#

パッケージおよびCA証明書の更新を行います。

# sudo dnf update && \
sudo dnf install ca-certificates
~略~
Complete!
#

NGINX Plus ACMEモジュールをインストールします。これで、ACMEモジュールのインストールは完了です。

# sudo dnf update && \
sudo dnf install nginx-plus-module-acme
Last metadata expiration check: 3:26:23 ago on Thu Mar 19 12:19:13 2026.
Dependencies resolved.
Nothing to do.
Complete!
~略~
Installed:
nginx-plus-module-acme-1:36+0.3.1-1.el9.ngx.x86_64

Complete!
#

参考:AlmaLinuxの場合、インストールしたモジュールは下記に書き込まれます。

# ls /usr/lib64/nginx/modules/
ngx_http_acme_module-debug.so ngx_http_acme_module.so
#

ACMEモジュールの有効化

NGINX PlusACMEモジュールを動的に読み込ませるために、/etc/nginx/nginx.conf を編集します。
編集内容としては、”load_module modules/ngx_http_acme_module.so;”を追記するのみです。
今回はACMEモジュールに関わる設定以外はデフォルトのままとしており、設定後のnginx.conf設定とデフォルトのnginx.confとの差分は下記のみとなります。

# head -5 /etc/nginx/nginx.conf
load_module modules/ngx_http_acme_module.so;

user nginx;
worker_processes auto;

#
# diff nginx.conf nginx.conf_bk
1d0
< load_module modules/ngx_http_acme_module.so;
12a12
>
#

設定を検証し、問題がなければモジュールを有効にするために設定の再読み込みを実施します。

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
#
# nginx -s reload
#

これで、ACMEモジュールの有効化は完了です。

NGINXコンフィグの設定作業

ACMEモジュールでSSL/TLS証明書を発行する設定ファイルの作成を行います。
ACMEモジュールを有効にするために、acme_issuerディレクティブで必要な設定を行います。

acme_issuer hoge {
uri https://<ACMEサーバのディレクトリURL>;
ssl_verify off;
# contact admin@example.test;
state_path /var/cache/nginx/acme-hoge;
accept_terms_of_service;

}

上記の設定内容について簡単に解説します。

uri

ACMEサーバのディレクトリURLを指定します。
本設定は必須項目です。

ssl_verify

ACMEサーバとHTTP-01チャレンジにおいてHTTPSで通信する際のサーバ証明書検証の有効/無効を指定します。
※デフォルトでは有効(on)ですが、本検証ではACMEサーバをIPアドレスで指定するため、サーバ証明書検証を無効としています。

state_path

アカウントキー、発行済み証明書、秘密鍵などの機密情報を保存するディレクトリを指定します。

accept_terms_of_service

ACMEサーバの利用規約に同意します。
利用規約は通常、ACMEサーバのWebサイトに掲載されていますので、ご利用になるACMEサーバの規約を確認ください。

上記の各ディレクティブの詳細や、その他ACMEモジュールで設定可能なディレクティブについては下記のメーカードキュメントをご確認ください。

Module ngx_http_acme_module
https://nginx.org/en/docs/http/ngx_http_acme_module.html

今回はHTTP-01チャレンジによるドメイン所有の確認を行うため、ポート80serverブロックを定義します。

server {
     
# listener on port 80 is required to process ACME HTTP-01 challenges
    listen 80;

    location / {
        
#Serve a basic 404 response while listening for challenges
        return 404;
    }
}

次に、ポート443serverブロックを定義します。
serverブロック内のacme_certificateディレクティブを使用して、SSL/TLS 証明書の発行/更新を自動化します。server_nameで定義するFQDNに対する証明書がacme_certificateの設定に従い、発行・更新されます。

$acme_certificateおよび$acme_certificate_key変数は、ACMEで発行、更新したSSL 証明書と鍵情報を渡す動的変数です。ssl_certificate_cacheは変数で指定されたSSL 証明書と秘密鍵を格納するキャッシュの定義を行います。ここではキャッシュ内要素の最大数を2に設定しています。これにより、同時に2世代までの証明書をメモリにキャッシュします。

server {
    listen 443 ssl;
    server_name hoge.tmxlabs.com;

    acme_certificate hoge;

    ssl_certificate              $acme_certificate;
    ssl_certificate_key     $acme_certificate_key;

    # do not parse the certificate on each request
    ssl_certificate_cache max=2;
}

最後に、設定ファイル(hoge.tmxlabs.com.conf)の内容をまとめます。
ACMEモジュールを動作させるための最小限の構成となります。

resolver 127.0.0.1:53;

acme_issuer hoge {
    uri                 https://<ACMEサーバのディレクトリURL>;
    ssl_verify     off;
    
# contact         admin@example.test;
    state_path   /var/cache/nginx/acme-hoge;
    accept_terms_of_service;
}

acme_shared_zone zone=acme_shared:1M;

server {
    listen  443 ssl;

    server_name hoge.tmxlabs.com;

    acme_certificate hoge;


    ssl_
certificate             $acme_certificate;
    ssl_
certificate_key    $acme_certificate_key;

    #
do not parse the certificate on each request
    ssl_
certificate_cache max=2;
}

server {
    #
listener on port 80 is required to process ACME HTTP-01 challenges
    listen
80;
    #
server_name hoge.tmxlabs.com;

    location
/ {
            #
Serve a basic 404 response while listening for challenges
            return 404;
    }
}

resolver設定は必須となります。
https://github.com/nginx/nginx-acme?tab=readme-ov-file#how-to-use

resolver設定の詳細については下記をご確認ください。
https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver

NGINX Plus ACMEモジュールの動作確認

本動作検証ではSmallstep CAコンテナをACMEサーバとして利用します。本ブログではACMEサーバについての説明は省略いたします。
BIG-IP ACMEDevCentral(メーカコミュニティサイト)にはなりますが、Smallstep CAコンテナの設定手順が公開されておりますので、実際に動作させてみたい方はこちらをご参考にコンテナを用意頂ければと思います。

Automating ACMEv2 Certificate Management on BIG-IP
https://community.f5.com/kb/technicalarticles/automating-acmev2-certificate-management-on-BIG-IP/328935
ACMEv2 Server Setup

それでは早速動作設定を確認していきます。
作成した設定ファイルhoge.tmxlabs.com.confを配置、設定の再読み込みを実行します。

# ls /var/cache/nginx/acme-hoge
account.key account.url hoge.tmxlabs.com-8c189dcde5958748.crt hoge.tmxlabs.com-8c189dcde5958748.key
#

ACMEモジュールによる証明書発行が行えることは確認できましたので、次はこれが動的に更新されるかを見ていきたいと思います。なお、現時点では NGINX ACME では証明書更新のスケジュールを明示的に設定することはできず、証明書の有効期間の2/3の期間±ジッタ(ゆらぎ)の間隔で更新が行われます。
Smallstep CAがデフォルトで発行する証明書は有効期限が1日の短期証明書となります。有効期限が24時間なので、2/3である16時間±ジッタの間隔で更新されることになります。

Smallstep CAのログから証明書発行・更新が行われたタイミングを確認します。

Smallstep CAログ抜粋

time="2026-03-30T08:02:06Z" ~~ issuer=subca.f5labs.com method=POST ~~ request-id=0ea0ed1f-b809-4053-97e8-df6d1e9a0182 sans="map[dns:[hoge.tmxlabs.com]]"
time="2026-03-31T00:17:04Z" ~~ issuer=subca.f5labs.com method=POST ~~ request-id=342d348d-4543-4c98-8ef1-e8f76ff5e0bf sans="map[dns:[hoge.tmxlabs.com]]"
time="2026-03-31T15:57:40Z" ~~ issuer=subca.f5labs.com method=POST ~~ request-id=0186adf1-56fb-4228-af24-5ea4f32a437f sans="map[dns:[hoge.tmxlabs.com]]"
time="2026-04-01T07:55:49Z" ~~ issuer=subca.f5labs.com method=POST ~~ request-id=66f30feb-cee9-4b84-bdb5-7bb14fa2bde1 sans="map[dns:[hoge.tmxlabs.com]]"
time="2026-04-02T00:05:57Z" ~~ issuer=subca.f5labs.com method=POST ~~ request-id=65b50f53-9923-4c44-9f0d-6a6013b26c80 sans="map[dns:[hoge.tmxlabs.com]]"

timestampUTC表記のため、JSTに変換すると下記になります。

2026-03-30 17:02:06 JST
2026-03-31 09:17:04 JST
2026-04-01 00:57:40 JST
2026-04-01 16:55:49 JST
2026-04-02 09:05:57 JST

更新間隔がおおよそ16時間前後となっており、ACMEの設計通りに更新されていることが確認できます。

最後に、ACMEモジュールで発行された証明書を利用したHTTPS通信が可能かを確認してみましょう。
HTTPSレスポンス用にlocationを追加します。

server {
        listen
443 ssl;
        server_name hoge.tmxlabs.com;

        acme_certificate hoge;

        ssl_certificate             $acme_certificate;
        ssl_certificate_key    $acme_certificate_key;

        # do not parse the certificate on each request
        ssl_certificate_cache max=2;

        location / {
               return 200 "NGINX-ACME TLS ACCESS Hoge OK\n";
        }

}

使用される証明書の有効期限は下記となります。

# ls -ln /var/cache/nginx/acme-hoge
total 16
-rw-r--r--. 1 0 0 241 Apr 6 09:42 account.key
-rw-rw-rw-. 1 996 993 75 Apr 6 09:42 account.url
-rw-rw-rw-. 1 996 993 2214 Apr 6 09:44 hoge.tmxlabs.com-8c189dcde5958748.crt
-rw-rw-rw-. 1 996 993 241 Apr 6 09:44 hoge.tmxlabs.com-8c189dcde5958748.key
#
# openssl x509 -text -noout -in /var/cache/nginx/acme-hoge/hoge.tmxlabs.com-8c189dcde5958748.crt | grep GMT
                        Not Before: Apr 6 00:43:12 2026 GMT
                        Not After : Apr 7 00:44:12 2026 GMT
#

この状態で、外部クライアントからアクセスした結果が下記となります。

# curl -vk https://hoge.tmxlabs.com/ --resolv hoge.tmxlabs.com:443:xx.xx.xx.xx
* Added hoge.tmxlabs.com:443: xx.xx.xx.xx to DNS cache
* Hostname hoge.tmxlabs.com was found in DNS cache
*      Trying xx.xx.xx.xx...
* Connected to hoge.tmxlabs.com (xx.xx.xx.xx) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*     CAfile: /etc/pki/tls/certs/ca-bundle.crt
    CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*               subject: CN=hoge.tmxlabs.com
*               start date: Apr 6 00:43:12 2026 GMT
*               expire date: Apr 7 00:44:12 2026 GMT
*               issuer: CN=subca.f5labs.com
*               SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
> GET / HTTP/1.1
> Host: hoge.tmxlabs.com
> User-Agent: curl/7.47.1
> Accept: */*
>
HTTP/1.1 200 OK
< Server: nginx/1.29.3
< Date: Mon, 06 Apr 2026 04:45:03 GMT
< Content-Type: application/octet-stream
< Content-Length: 30
< Connection: keep-alive
<
NGINX-ACME TLS ACCESS Hoge OK
* Connection #0 to host hoge.tmxlabs.com left intact
#

Server certificate:に表示される証明書の有効期限がACMEモジュールで発行された証明書の有効期限と合致していることが確認できます。また、locationで設定した内容で応答していることが確認できます。

おわりに

今回はNGINX PlusSSL/TLS証明書更新自動化ソリューションとして、ACMEモジュールについて紹介しました。本ブログの内容が、NGINXでの証明書更新の自動化を検討しているお客様の参考になることを願っております。

本記事をご覧いただき、F5社でも証明書自動化に向けた取り組みが進められていることをご認識いただければ幸いです。

最後になりますが、弊社ではこれ以外にも様々なソリューションを取り扱っております。
もし気になるソリューションがございましたら、ぜひ弊社へお問い合わせください。

CONTACT

ITインフラに関してお悩みの方は
お気軽にご相談ください

ご不明な点はお気軽に
お問い合わせください。
ITインフラに関するお役立ち資料は
こちらよりダウンロードできます。

人気記事ランキング

タグ一覧