Difyサーバーを安全に運用するために、通信の暗号化(HTTPS化)は必須です。HTTPS化されていないサイト(HTTP)では、ログインパスワードやAPIキー、チャット内容が傍受されるリスクがあります。
この記事では、無料でSSL/TLS証明書を発行できる「Let’s Encrypt」と、その証明書の発行・更新を自動化するクライアント「Certbot」を使い、Nginxで動作するDifyサーバーをHTTPS化する手順を解説します。
前提条件
- Ubuntu/Debian系サーバー: これまでの記事で構築した環境を想定します。
- Nginxがインストール済み: DifyのDockerコンテナの前段に、リバースプロキシとしてNginxが設定されていることを前提とします。
- ドメイン取得済み:
dify.example.comのような、Difyで使用するドメイン名を取得していること。 - DNS設定済み: 取得したドメインのAレコード(と、設定していればAAAAレコード)が、DifyサーバーのIPアドレスを正しく指していること。
- ファイアウォールの開放: サーバーのファイアウォール(
firewalldまたはufw)で、ポート 80 (HTTP) と ポート 443 (HTTPS) が開いていること。(ポート 80 は、Let’s Encryptがドメインの所有権を確認するため(HTTP-01チャレンジ)に必要です)
ステップ1: Certbot のインストール (snap版)
現在、Certbotのインストールは snap を使用する方法が公式に推奨されています。
snapdのインストール 古いapt版のCertbotが入っている場合は、先に削除しておきます。# もし古いcertbotがあれば削除 sudo apt-get remove certbot # snapd(snapの管理ツール)をインストール sudo apt update sudo apt install snapd- Certbot のインストール
snapを使ってcertbotの最新版をインストールします。sudo snap install --classic certbot - シンボリックリンクの作成
certbotコマンドをシステム上のどこからでも使えるように、リンクを作成します。sudo ln -s /snap/bin/certbot /usr/bin/certbot - バージョン確認 正しくインストールされたか確認します。
certbot --version # 例: certbot 2.11.0
ステップ2: SSL証明書の取得 (Nginxプラグイン)
CertbotにはNginx用のプラグインがあり、Nginxの設定を解析して自動で証明書を取得・設定できますが、ここではDifyの複雑な設定(リバースプロキシ)を壊さないよう、証明書の取得のみを行う certonly コマンドを使います。
# [dify.example.com] と [admin@example.com] はご自身のドメインとメールアドレスに置き換えてください
sudo certbot certonly --nginx \
--agree-tos \
-d dify.example.com \
-m admin@example.com
certonly: 証明書の取得のみ行い、Nginxの設定は変更しません(手動で設定します)。--nginx: Nginxの設定を読み取ってドメインの検証(HTTP-01チャレンジ)を行います。※HTTP-01チャレンジとは、Webサーバーの所有権を証明するために、認証局(CA)が要求する特定のファイルを、証明書を取得したいドメインの指定されたURLに配置し、CAがそのHTTPアクセスによってファイルを確認する認証方式です。この方式は、Webサーバーに直接アクセスできる環境で、SSL/TLS証明書の発行を自動化する際に、最も一般的に使用されます。

◆フロー
- CertMgr は ACME CA サーバーを使用してアカウント (C) を作成します
- CertMgr は鍵ペアを作成し、CertStore (A) に書き込みます
- CertMgr は CSR を作成し、ACME CA サーバーに送信します
- CertMgr は受信したチャレンジ (B) を CertStore に保存します
- ACME CA サーバーは、ドメインの所有権を確認するために、ポート 80 でチャレンジを要求します
- Domino HTTP は、CertStore からのチャレンジ (B) で応答します
- CertMgr は証明書チェーンを受け取り、CertStore (A) に書き込みます
- HTTP (および INET タスク) は CertStore (A) から証明書と鍵を読み取ります
--agree-tos: Let’s Encryptの利用規約に同意します。-d: 証明書を発行するドメイン名。-m: 有効期限の通知などを受け取るメールアドレス。
実行すると、Nginxの既存の設定ファイル(ポート80)を利用して一時的に検証用ファイルが配置され、Let’s Encryptのサーバーがそこにアクセスしてドメインの所有権が確認されます。
成功すると、以下のようなメッセージが表示されます。
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/[dify.example.com/fullchain.pem](https://dify.example.com/fullchain.pem)
Key is saved at: /etc/letsencrypt/live/[dify.example.com/privkey.pem](https://dify.example.com/privkey.pem)
This certificate expires on 2025-01-21. (90日後)
これで、SSL証明書と秘密鍵がサーバーに保存されました。
ステップ3: NginxにSSL証明書を設定する
次に、Nginxの設定ファイルを編集し、DifyサーバーをHTTPS (ポート 443) で動作させ、HTTP (ポート 80) からのリクエストをすべてHTTPSにリダイレクト(転送)するようにします。
- Dify用のNginx設定ファイル(例:
/etc/nginx/sites-available/dify.example.com)を編集します。sudo vi /etc/nginx/sites-available/dify.example.com - 以下のように設定を書き換えます。
dify.example.comの部分と、DifyのDockerポート(例:5001)はご自身の環境に合わせてください。# HTTP (ポート80) の設定: すべてHTTPS (ポート443) にリダイレクト server { listen 80; # IPv6でポート80をリッスンする場合 listen [::]:80; server_name dify.example.com; # $host (dify.example.com) と $request_uri (URLのパス) を保持したままHTTPSに転送 return 301 https://$host$request_uri; } # HTTPS (ポート443) の設定: Dify本体 server { listen 443 ssl http2; # IPv6でポート443をリッスンする場合 listen [::]:443 ssl http2; server_name dify.example.com; # --- SSL証明書のパス --- ssl_certificate /etc/letsencrypt/live/[dify.example.com/fullchain.pem](https://dify.example.com/fullchain.pem); ssl_certificate_key /etc/letsencrypt/live/[dify.example.com/privkey.pem](https://dify.example.com/privkey.pem); # --- SSLセキュリティ設定 (推奨) --- ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always; # --- ここまでSSL設定 --- location / { # Difyが動作しているDockerコンテナのポート proxy_pass(http://127.0.0.1:5001); proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket (チャットなどで使用) のための設定 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }http://127.0.0.1:5001 - Nginxの設定をテストし、リロードします。
# 設定ファイルに文法ミスがないかテスト sudo nginx -t # nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # nginx: configuration file /etc/nginx/nginx.conf test is successful # OKならリロードして設定を反映 sudo systemctl reload nginx
ブラウザから https://dify.example.com にアクセスし、鍵マーク(SSLが有効)が表示されれば成功です。http:// でアクセスしても自動的に https:// に転送されることも確認してください。
ステップ4: 証明書の自動更新を確認する
Let’s Encrypt の証明書は有効期限が90日と短いため、自動更新が不可欠です。snap でインストールした Certbot は、自動で systemd timer をセットアップし、期限が切れる前に証明書を自動更新します。
- タイマーの確認
certbot.renew.timerが有効になっているか確認します。sudo systemctl list-timers | grep certbot # NEXT LEFT LAST ... # ... snap.certbot.renew.timer ... - 自動更新のテスト
--dry-run(ドライラン)オプションを付けて、更新処理が正しく動作するかテストできます。sudo certbot renew --dry-run--nginxプラグインで取得した証明書は、更新が成功すると自動的にsystemctl reload nginxが実行され、Nginxに新しい証明書が読み込まれます。
(オプション) ワイルドカード証明書について
*.example.com(ワイルドカード証明書)を取得すると、dify.example.com だけでなく api.example.com など、複数のサブドメインを1枚の証明書でカバーできます。
- 検証方法: ワイルドカード証明書は、HTTP-01チャレンジ(ポート80)では検証できず、DNS-01チャレンジ(DNSのTXTレコード)が必要です。
- 自動化: 更新のたびに手動でTXTレコードを書き換えるのは現実的ではありません。ConoHa、Cloudflare、Route 53などの主要なDNSサービスは、API経由でTXTレコードを自動操作するためのCertbotプラグイン(例:
certbot-dns-conoha,certbot-dns-cloudflare)が用意されています。 - 複雑性: 設定は複雑になりますが、一度設定すれば、非公開サーバー(ポート80を開けられないサーバー)でも証明書を取得・更新できるメリットがあります。
Difyサーバーが1つのドメインのみで運用される場合は、この記事で紹介したHTTP-01チャレンジ(--nginx)が最も簡単で確実です。
参考:Let’s Encrypt のワイルドカード証明書を ConoHa API で自動更新する
Certbot を使って Let’ Encrypt の SSL 証明書を取得するには、外部に公開されたウェブサーバーか DNS サーバーで認証する必要があります。
ConoHa VPS に検証用として RHEL9 の設定を進めているのですが、現状ではウェブサーバーを外部には公開しておらず、管理者の IP アドレスからしかアクセスできない設定になっています。
Certbot の DNS 認証を使えば、非公開のウェブサーバー用の SSL 証明書を取得でき、ワイルドカード証明書も取得できるので一石二鳥ですが、更新のたびに DNS を手動で書き換えるのは手間になります。
探してみたところ、ConoHa API を使って自動で TXT レコードを書き換えてくれるスクリプトがありましたので、これを使った設定方法を記録しておきます。
Certbot のインストール
EPEL リポジトリから Certbot をインストールします。
|
# dnf install certbot
|
※EPEL リポジトリが未導入の場合は下記を参考に入れてください。
ConoHa API を介して認証用コードを自動的に設定してくれるスクリプトなのですが、オリジナルでは tyo2 リージョンに対応していなかったので、フォークされたものを使用しました。(https://github.com/tsukumijima/letsencrypt-dns-conoha)
git コマンドで一式をダウンロードします。
|
# git clone https://github.com/tsukumijima/letsencrypt-dns-conoha.git
|
Let’s Encrypt ディレクトリ内で完結させたいので、/etc/letsencrypt にファイル一式を移動します。
|
# mv letsencrypt-dns-conoha/ /etc/letsencrypt/conoha
|
スクリプトファイルに実行権限を付与します。
|
# chmod +x /etc/letsencrypt/conoha/*.sh
|
設定ファイル(.env)をリネームします。
|
# mv /etc/letsencrypt/conoha/.env.example /etc/letsencrypt/conoha/.env
|
ConoHa コントロールパネルから API のタブに移動し、API のユーザーネームとパスワード、テナント ID を確認します。また、エンドポイントの URL からリージョン(tyo1 か tyo2)もあわせて確認します。

※API ユーザーが設定されていない場合は作成してください。パスワードを設定するだけで、ユーザー名は自動的に割り当てられます。
上記の内容を、letsencrypt-dns-conoha の設定ファイルに記載します。
|
# vi /etc/letsencrypt/conoha/.env
|
また、スクリプト内で jq コマンドを使用しますので、インストールしておきます。
|
# dnf install jq
|
以上で、準備は完了しました。
証明書の自動更新設定
以前は Cron で月に一回程度 certbot renew を実行するのが一般的でした。
|
#!/bin/sh
certbot renew —deploy–hook “systemctl restart httpd; systemctl restart postfix; systemctl restart dovecot”
|
最近では certbot をインストールすると一緒に導入される certbot-renew が自動的に更新してくれるため、cron を設定する必要はありません。
|
# systemctl status certbot-renew.service
○ certbot–renew.service – This service automatically renews any certbot certificates found
Loaded: loaded (/usr/lib/systemd/system/certbot–renew.service; static)
Active: inactive (dead) since XXX XXXX–XX–XX XX:XX:XX JST; XXh XXmin ago
TriggeredBy: ● certbot–renew.timer
Process: 269762 ExecStart=/usr/bin/certbot renew —noninteractive —no–random–sleep–on–renew $PRE_HOOK $POST_HOOK $RENEW_HOOK $DEPLOY_HOOK $CERTBOT_ARGS (code=exited, status=0/SUCCESS)
Main PID: 269762 (code=exited, status=0/SUCCESS)
CPU: 366ms
|
certbot-renew.service は certbot-renew.timer によって呼び出され、定期的に実行されます。
|
# systemctl status certbot-renew.timer
● certbot–renew.timer – This is the timer to set the schedule for automated renewals
Loaded: loaded (/usr/lib/systemd/system/certbot–renew.timer; enabled; preset: enabled)
Active: active (waiting) since XXX XXXX–XX–XX XX:XX:XX JST; X month X days ago
Until: XXX XXXX–XX–XX XX:XX:XX JST; X month X days ago
Trigger: XXX XXXX–XX–XX XX:XX:XX JST; Xh left
Triggers: ● certbot–renew.service
Notice: journal has been rotated since unit was started, output may be incomplete.
|
証明書が更新された際に、自動的にサービスを再起動して反映させるためには /etc/letsencrypt/renewal-hooks/deploy/ の中にスクリプトを設置します。
|
#!/bin/bash
systemctl restart httpd
#systemctl restart lshttpd.service
systemctl restart postfix
systemctl restart dovecot
#systemctl restart vsftpd
|
以上で Let’s Encrypt のワイルドカード SSL 証明書を自動運用する事ができるようになりました。
まとめ
今回は、無料で証明書を導入する手順を説明しました。
httpのサイトは警告がでてしまったりと何かと都合が悪いので、きちんとと暗号化するべきです。


コメント