Cloudflareプロキシ有効時でも使える!Synology NASでacme.sh(DNS-01)を使った証明書自動更新 | masao-Tec-blog

Cloudflareプロキシ有効時でも使える!Synology NASでacme.sh(DNS-01)を使った証明書自動更新

Synology NAS 応用

Synology NAS で Web サーバを運用している場合、DSM に標準で用意されている Let’s Encrypt 証明書取得機能を利用して HTTPS 化している方も多いと思います。
しかし、Cloudflare を DNS プロバイダとして利用し、さらに Cloudflare のプロキシ(オレンジ雲)を有効化 して運用しようとすると、Synology 標準の証明書更新が正常に行えなくなるという問題に直面します。
これは、DSM の Let’s Encrypt 実装が HTTP-01 チャレンジのみに対応しており、Cloudflare のプロキシ経由では認証が成立しない ためです。
Cloudflare には Origin Certificate という選択肢もありますが、これは Cloudflare とオリジンサーバ間の通信専用であり、ローカル環境やプロキシを介さない直接アクセスでは利用できません。
本記事では、これらの問題を解決する方法として、DNS-01 チャレンジに対応した ACME クライアント「acme.sh」 を Synology NAS に導入し、Cloudflare DNS を利用して Let’s Encrypt 証明書を自動取得・更新する手順を解説します。
この構成により、Cloudflare のプロキシを有効化した状態でも、オリジンサーバ(Synology NAS)側で正規の証明書を維持できるようになります。

以下の記事で、Synology NASで構築したWebサイトのDDNSをCloudflareのDNSで実現する設定方法について紹介しています。

参考 Synology NASで構築したWebサイトのDDNSをCloudflareのDNSで実現する設定方法

上記記事では、IP アドレスが変動する環境でも独自ドメインの Web サイトを安定して公開できるよう、Cloudflare の DNS を DDNS サービスとして利用する構成を紹介しています。この構成により、Synology NAS 上で Web サービスを公開するための基本的な土台は整います。

次のステップとして検討したくなるのが、Cloudflare のプロキシ機能を有効化した運用です。Cloudflare プロキシを有効にすると、オリジンサーバである Synology NAS を直接インターネットに晒さずに済むようになり、セキュリティや運用面で多くのメリットが得られます。

しかし、Cloudflare プロキシを有効にした状態では、Synology DSM 標準の Let’s Encrypt 証明書取得・更新の仕組み(HTTP-01 チャレンジ)が正常に動作しなくなるという問題があります。

本記事ではこの問題に対する解決策として、acme.sh を用いて Cloudflare の DNS と連携し、DNS-01 チャレンジによる Let’s Encrypt 証明書の取得および自動更新を Synology NAS 上で構成する方法を解説します。

前提 本記事でのDSM(OS)バージョンはSynology DSM 7.3を用いています。

スポンサーリンク

1.acme.shとは

こちらのサイトで開発されています。

acme.sh は、シェルスクリプトのみで実装された軽量な ACME クライアントであり、Let’s Encrypt をはじめとする各種認証局から証明書の取得・更新・インストールを行うことができます。

Synology DSM が標準で対応していない DNS-01 チャレンジ方式 に対応している点が大きな特徴で、Cloudflare の DNS API を利用することで、DNS レコード(TXT)を自動的に操作しながら証明書を取得できます。

これにより、Cloudflare のプロキシ設定を有効にした状態でも、オリジンサーバ(Synology NAS)側で問題なく証明書の取得・更新が可能となります。

更に、ポート80を開放する必要性がなくなるため、ポート80をFirewallやホームゲートウェイ機器で閉じることができるので、セキュリティ面も大幅に向上します。

スポンサーリンク

2.Synology NASにおけるacme.shのセットアップ方法

2-1.acme.shのインストール

gitコマンドでcloneしてから、インストールコマンドを実行する方法を説明します。
注意 gitコマンドは予めパッケージセンターでGit Serverパッケージをインストールしておく必要があります。

管理者ユーザで、任意のディレクトリ(ホームディレクトリ推奨)で以下を実行します。

git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install --force -m yourmailaddres@mail.com
  • -mで指定するメールアドレスは、認証局(Let’s Encrypt)に登録される連絡先です。
  • --force は、Synology DSM では cron が標準では使用できないため、警告エラーを無視してインストールを続行する目的で指定しています。

上記を実行すると、管理者ユーザのホームディレクトリ配下に以下のディレクトリが作成されます。

.acme.sh

(ちょっとややこしいですが、先頭にピリオドがついた隠しディレクトリが作成されます。管理者ユーザのホームディレクトリ直下にgit cloneでacme.shをクローンした場合、それとは別に「.acme.sh」が作成されます)

2-2.初期セットアップ

スクリプトディレクトリに移動

cd ~/.acme.sh

デフォルト認証局をLet’s Encrypt に設定

./acme.sh --set-default-ca --server letsencrypt

ACME アカウント登録

./acme.sh --register-account --accountemail yourmailaddres@mail.com

インストール時に -m オプションでデフォルトのメールアドレスを設定している場合、--register-account 実行時に --accountemail を省略しても問題ありません。acme.sh は account.conf に保存されたメールアドレスを自動的に使用します。

通知設定(SMTP)

証明書更新の成功・失敗をメールで受け取れるよう、SMTP 通知を設定します。以下はgmailでの通知設定例となります。

$export SMTP_TLS=1
$export SMTP_FROM=yourmailaddres@mail.com
$export SMTP_PASSWORD=googleのアプリパスワード
$export SMTP_HOST=smtp.gmail.com
$export SMTP_TO=yourmailaddres@mail.com
$export SMTP_USERNAME=yourmailaddres@mail.com
$export SMTP_PORT=587
$./acme.sh --set-notify --notify-hook smtp --notify-level 2 --notify-source yourhostname
  • gmailで予めアプリパスワードを取得しておく必要があります。
  • 赤文字の部分は自環境に適宜読み替えてください。
  • 問題なければテストメールが送信されますので、メール受信を確認してください。
  • 設定内容は.acme.sh/account.confに保存されます。

2-3.DNS-01チャレンジによる証明書取得

Cloudflare API トークンの設定

Cloudflare の API トークンを環境変数として設定します。

export CF_Token="API Token"
export CF_Account_ID="CloudflareのアカウントID"

Cloudflare API Token については以下の記事に記載している「DNS編集に必要な最小権限のトークン」を使用します。

証明書取得

./acme.sh --issue -d ドメイン名 --dns dns_cf

ワイルドカード証明書の例

./acme.sh --issue -d example.com -d *.example.com --dns dns_cf

証明書取得に成功すると、証明書や更新設定などの情報が .acme.sh 配下に保存されます。

2-4.証明書の初回デプロイ(DSMへの反映)

以下の作業はrootユーザで実行します。(sudo -i)

export SYNO_USE_TEMP_ADMIN=1
export SYNO_CREATE=1
export SYNO_CERTIFICATE="ドメイン名"

ACME_HOME="/var/services/homes/管理者ユーザのホームディレクトリ/.acme.sh"
cd $ACME_HOME

./acme.sh --home $ACME_HOME \
  --deploy -d ドメイン名 \
  --deploy-hook synology_dsm
  • 赤文字の部分は自環境に適宜読み替えてください。
  • 証明書が DSM に自動登録されます。
  • DSM の コントロールパネル > セキュリティ > 証明書 で更新されていることを確認してください。
  • 初回デプロイ時に、以降の自動更新に必要な設定情報が保存されます。

2-5.自動更新設定(タスクスケジューラ)

DSM のタスクスケジューラに以下のタスクを登録します。

タスク設定

  • タスク名(例):acme_cert_update
  • ユーザー:root
  • スケジュール:毎日
  • 開始時刻:03:00

ユーザー指定のスクリプト

#!/bin/bash
ACME_HOME="/var/services/homes/管理者ユーザのホームディレクトリ/.acme.sh"
cd $ACME_HOME
./acme.sh --cron --home "$ACME_HOME"

このタスクにより、証明書の有効期限チェック、必要に応じた更新、および DSM への再デプロイまでが自動で実行されます。

3.Synology 標準の証明書更新との関係について

すでに Synology DSM 標準の Let’s Encrypt 機能(HTTP-01 チャレンジ)を用いて証明書を管理している状態で、acme.sh を用いて同一ドメインの証明書を取得し、synology_dsmデプロイフックで DSM に登録した場合、
DSM の証明書管理画面上では 既存の DSM 標準 Let’s Encrypt 証明書が実質的に置き換えられる形になります。

  • acme.sh により取得された証明書は既存の同一ドメインの証明書スロットに上書き登録される
  • その結果、DSM はその証明書を「DSM 標準の Let’s Encrypt 管理対象」とは認識しなくなる
  • 以降、そのドメインに対してDSM 標準の Let’s Encrypt 自動更新(HTTP-01)は実行されない

つまり、
「DSM 標準の証明書と acme.sh の証明書が並行して併存・更新される」
という挙動にはなりません。

3-1.Synology 標準の証明書更新に戻したい場合

Synology 標準の証明書更新に戻したい場合は、一旦acme.shで取得した証明書を削除し、Synology DSM 標準の Let’s Encrypt 機能で証明書を取得しなおせば、Synology 標準の証明書更新に戻ります。

4.なぜ Cloudflare プロキシ有効時に DSM 標準の証明書更新は失敗するのか

ここまでで、acme.sh を導入すると証明書の更新主体が DSM から acme.sh に切り替わることを説明しました。
では、そもそもなぜ DSM 標準の Let’s Encrypt 証明書更新では不十分なのかを整理します。

4-1.DSM 標準の証明書取得方式は HTTP-01 チャレンジのみ

Synology DSM に標準で搭載されている Let’s Encrypt 証明書取得・更新機能は、HTTP-01 チャレンジ方式のみに対応しています。

HTTP-01 チャレンジでは、認証局(Let’s Encrypt)が以下の流れで検証を行います。

  1. http://example.com/.well-known/acme-challenge/ にアクセス
  2. その URL から特定のトークンが取得できるかを確認
  3. 応答できれば「そのドメインを管理している」と判断

この方式は、

  • クライアントが 直接オリジンサーバへ HTTP 接続できる
  • 認証リクエストが 途中で改変されない

ことが前提条件になります。

4-2.Cloudflare プロキシ有効時に起きる問題

Cloudflare で DNS レコードの プロキシ(オレンジ雲)を有効化すると、ドメインへの HTTP/HTTPS アクセスは以下のように変化します

Let’s Encrypt ⇒ Cloudflare(エッジ)⇒ Synology NAS(オリジン)

この構成では、

  • Let’s Encrypt からの HTTP-01 チャレンジは Cloudflare までしか到達しない
  • Cloudflare は ACME チャレンジ用のリクエストを オリジンサーバへ透過転送しない
  • 結果として Let’s Encrypt は正しいトークンを取得できない

そのため、Cloudflare プロキシ有効にすると、DSM 標準の Let’s Encrypt(HTTP-01)証明書取得・更新に失敗する状態となります。

4-3.DNS-01 チャレンジならプロキシの影響を受けない

acme.shで証明書を取得する方式であるDNS-01 チャレンジでは、検証方法が根本的に異なります。

  • HTTP/HTTPS アクセスは一切使用しない
  • DNS に一時的な TXT レコードを追加することで所有確認を行う

そのため、

  • Cloudflare プロキシが有効かどうかは無関係
  • オリジンサーバへの到達性も不要

となり、Cloudflare プロキシと完全に共存可能です。

5.まとめ

Cloudflare プロキシを有効にした環境では、Synology DSM 標準の Let’s Encrypt 証明書取得方式(HTTP-01 チャレンジ)は動作しません。本記事で紹介したように、acme.sh を用いて DNS-01 チャレンジに切り替えることで、HTTP 経路に依存せず、Cloudflare プロキシを有効にしたままでも証明書を自動更新できる構成を実現できます。

acme.sh で取得した証明書は DSM の証明書管理にデプロイされ、以降の更新は acme.sh が担うため、DSM 標準の仕組みと競合することなく安定した運用が可能です。Cloudflare を活用した構成で Synology NAS を公開する場合、本記事の方法は現実的かつ安全な選択肢となるでしょう。