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

Dify環境構築

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

※EPEL リポジトリが未導入の場合は下記を参考に入れてください。

ConoHa API を介して認証用コードを自動的に設定してくれるスクリプトなのですが、オリジナルでは tyo2 リージョンに対応していなかったので、フォークされたものを使用しました。(https://github.com/tsukumijima/letsencrypt-dns-conoha

git コマンドで一式をダウンロードします。

Let’s Encrypt ディレクトリ内で完結させたいので、/etc/letsencrypt にファイル一式を移動します。

スクリプトファイルに実行権限を付与します。

設定ファイル(.env)をリネームします。

ConoHa コントロールパネルから API のタブに移動し、API のユーザーネームとパスワード、テナント ID を確認します。また、エンドポイントの URL からリージョン(tyo1 か tyo2)もあわせて確認します。

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

※API ユーザーが設定されていない場合は作成してください。パスワードを設定するだけで、ユーザー名は自動的に割り当てられます。

上記の内容を、letsencrypt-dns-conoha の設定ファイルに記載します。

また、スクリプト内で jq コマンドを使用しますので、インストールしておきます。

以上で、準備は完了しました。

 

証明書の自動更新設定

以前は Cron で月に一回程度 certbot renew を実行するのが一般的でした。

最近では certbot をインストールすると一緒に導入される certbot-renew が自動的に更新してくれるため、cron を設定する必要はありません。

certbot-renew.service は certbot-renew.timer によって呼び出され、定期的に実行されます。

証明書が更新された際に、自動的にサービスを再起動して反映させるためには /etc/letsencrypt/renewal-hooks/deploy/ の中にスクリプトを設置します。

以上で Let’s Encrypt のワイルドカード SSL 証明書を自動運用する事ができるようになりました。

 

まとめ

今回は、無料で証明書を導入する手順を説明しました。
httpのサイトは警告がでてしまったりと何かと都合が悪いので、きちんとと暗号化するべきです。

コメント

error: Content is protected !!