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にリダイレクト(転送)するようにします。
1.Dify用のNginx設定ファイル(例: /etc/nginx/sites-available/dify.example.com)を編集します。
sudo vi /etc/nginx/sites-available/dify.example.com
2.以下のように設定を書き換えます。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](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";
}
}
3.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 をインストールします。
Certbot のインストール
| # dnf install certbot |
※EPEL リポジトリが未導入の場合は下記を参考に入れてください。
ConoHa API を介して認証用コードを自動的に設定してくれるスクリプトなのですが、オリジナルでは tyo2 リージョンに対応していなかったので、フォークされたものを使用しました。(https://github.com/tsukumijima/letsencrypt-dns-conoha)
git コマンドで一式をダウンロードします。
letsencrypt-dns-conoha のダウンロード
| # 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 を実行するのが一般的でした。
/etc/cron.monthly/certbot
| #!/bin/shcertbot renew–deploy-hook”systemctl restart httpd; systemctl restart postfix; systemctl restart dovecot” |
最近では certbot をインストールすると一緒に導入される certbot-renew が自動的に更新してくれるため、cron を設定する必要はありません。
certbot-renew.service の確認
| # systemctl status certbot-renew.service○ certbot-renew.service-Thisservice 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 agoTriggeredBy: ● certbot-renew.timer Process:269762ExecStart=/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-Thisisthe timer toset the schedule forautomated 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;XmonthXdays ago Until:XXX XXXX-XX-XX XX:XX:XX JST;XmonthXdays ago Trigger:XXX XXXX-XX-XX XX:XX:XX JST;Xh left Triggers: ● certbot-renew.serviceNotice:journal has been rotated since unit was started,output may be incomplete. |
証明書が更新された際に、自動的にサービスを再起動して反映させるためには /etc/letsencrypt/renewal-hooks/deploy/ の中にスクリプトを設置します。
/etc/letsencrypt/renewal-hooks/deploy/restart-services.sh
| #!/bin/bashsystemctl restart httpd#systemctl restart lshttpd.servicesystemctl restart postfixsystemctl restart dovecot#systemctl restart vsftpd |
以上で Let’s Encrypt のワイルドカード SSL 証明書を自動運用する事ができるようになりました。
まとめ
今回は、無料で証明書を導入する手順を説明しました。
httpのサイトは警告がでてしまったりと何かと都合が悪いので、きちんとと暗号化するべきです。
【推奨】業務システム化に有効なアイテム
生成AIを学ぶ



システム化のパートナー(ミラーマスター合同会社)



VPSサーバの選定





◆フロー
コメント