MENU

DifyのためのLinux設定:Let’s Encrypt (Certbot) で無料SSL化する手順

当ページのリンクには広告が含まれています。

Difyサーバーを安全に運用するために、通信の暗号化(HTTPS化)は必須です。HTTPS化されていないサイト(HTTP)では、ログインパスワードやAPIキー、チャット内容が傍受されるリスクがあります。

この記事では、無料でSSL/TLS証明書を発行できる「Let’s Encrypt」と、その証明書の発行・更新を自動化するクライアント「Certbot」を使い、Nginxで動作するDifyサーバーをHTTPS化する手順を解説します。

目次

前提条件

  1. Ubuntu/Debian系サーバー: これまでの記事で構築した環境を想定します。
  2. Nginxがインストール済み: DifyのDockerコンテナの前段に、リバースプロキシとしてNginxが設定されていることを前提とします。
  3. ドメイン取得済み: dify.example.com のような、Difyで使用するドメイン名を取得していること。
  4. DNS設定済み: 取得したドメインのAレコード(と、設定していればAAAAレコード)が、DifyサーバーのIPアドレスを正しく指していること。
  5. ファイアウォールの開放: サーバーのファイアウォール(firewalld または ufw)で、ポート 80 (HTTP)ポート 443 (HTTPS) が開いていること。(ポート 80 は、Let’s Encryptがドメインの所有権を確認するため(HTTP-01チャレンジ)に必要です)

ステップ1: Certbot のインストール (snap版)

現在、Certbotのインストールは snap を使用する方法が公式に推奨されています。

  1. snapd のインストール 古い apt 版のCertbotが入っている場合は、先に削除しておきます。 # もし古いcertbotがあれば削除 sudo apt-get remove certbot # snapd(snapの管理ツール)をインストール sudo apt update sudo apt install snapd
  2. Certbot のインストール snap を使って certbot の最新版をインストールします。 sudo snap install --classic certbot
  3. シンボリックリンクの作成 certbot コマンドをシステム上のどこからでも使えるように、リンクを作成します。 sudo ln -s /snap/bin/certbot /usr/bin/certbot
  4. バージョン確認 正しくインストールされたか確認します。 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証明書の発行を自動化する際に、最も一般的に使用されます。◆フロー
    1. CertMgr は ACME CA サーバーを使用してアカウント (C) を作成します
    2. CertMgr は鍵ペアを作成し、CertStore (A) に書き込みます
    3. CertMgr は CSR を作成し、ACME CA サーバーに送信します
    4. CertMgr は受信したチャレンジ (B) を CertStore に保存します
    5. ACME CA サーバーは、ドメインの所有権を確認するために、ポート 80 でチャレンジを要求します
    6. Domino HTTP は、CertStore からのチャレンジ (B) で応答します
    7. CertMgr は証明書チェーンを受け取り、CertStore (A) に書き込みます
    8. 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 をセットアップし、期限が切れる前に証明書を自動更新します。

    1. タイマーの確認 certbot.renew.timer が有効になっているか確認します。
    2. sudo systemctl list-timers | grep certbot # NEXT LEFT LAST ... # ... snap.certbot.renew.timer ...
    3. 自動更新のテスト --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)もあわせて確認します。

    ConoHa コントロールパネルの API 画面

    ※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サーバの選定

    よかったらシェアしてね!
    • URLをコピーしました!
    • URLをコピーしました!

    コメント

    コメントする

    目次