L30110
1
数ヶ月前(正確な期間は不明ですが、少なくとも数ヶ月前)から、私のDiscourseフォーラムでLet’s Encryptの更新が失敗するようになりました。長年正常に動作していたにもかかわらずです。数日前にこの問題に気づいたとき、証明書は2021年8月に期限切れでした。手動で更新を試み、nginxを再起動した後、証明書の期限が数日後に迫っていることがわかりました。もちろん、まだ現在の証明書ではありません。手動でacme.shを実行して更新を強制しようとすると(discourseコンテナ内で)、次のエラーが発生します([site]は当然ながら私のサイトアドレスです)。
[site]:Verify error:Fetching http://[site]/.well-known/acme-challenge/[long alpha challenge string]: Error getting validation data
サイトはすべてのユーザーアクセスにログインが必要であることを指摘しておくべきですが、これは長年の運用中にSSL証明書の更新で問題になったことはありませんでした。
何かアイデアはありますか?よろしくお願いします!
UPDATE:wgetを使用して検証をテストすると404が返されます。しかし、コンテナ内のDiscourseでこのデータがnginxにどのように設定されているか、またコンテナ外の関連nginxとどのように関連しているかはわかりません。
「いいね!」 2
L30110
3
こんにちは。それは関係ないはずです。なぜなら、その問題は私のケースのように期限切れのエラーではなく、ブラウザによって証明書が拒否される原因となるからです。Let’s Encryptが新しい証明書を配信するためにDiscourseとの認証ができなくなったようです。ありがとうございます。
「いいね!」 2
RGJ
(Richard - Communiteq)
4
8月に最初の有効期限が切れたのであれば、そうではありません。その後更新されているはずです。
「いいね!」 4
Benjamin_D
(Benjamin Decotte)
5
「いいね!」 2
L30110
6
こんにちは。それらは適用されないようです。404エラーが表示されており、それ以外のエラーは表示されていません。ビルドはすべて更新されており、GitHubのテンプレートはすでに私のインストールにインストールされているバージョンです。よろしくお願いします!
「いいね!」 3
pfaffman
(Jay Pfaffman)
7
オレンジ色の雲でCloudflareを使用していますか、それとも他のリバースプロキシを使用していますか?
「いいね!」 2
L30110
8
いいえ。デフォルトのDockerインストールを使用したUbuntu 18.04上のローカルホストです。
「いいね!」 3
L30110
9
(コンテナ内で) cron ジョブを手動で実行して証明書の更新を行っていますが、失敗は常に同じです。取得しようとしている\n\nhttp://[site]/.well-known/acme-challenge/[challenge-string]\n\nが「検証データの取得エラー」で失敗します。
「いいね!」 2
プロセスに慣れていないため、そのスクリプトを単独で実行した場合にコンテナがそうではない状態であることを期待している可能性がありますか?たとえば、URLへのアクセスを許可するようにnginxを準備する別のcronジョブが最初に発生することを期待しているのかもしれません。
再構築を試しましたか?(これにより、プロセス中に新しい証明書を取得しようとします。)
ローカルでホストされていると述べています。ドメイン名を使用して、ネットワーク外からインスタンスにアクセスできますか?
「いいね!」 2
L30110
11
こんにちは、はい、複数の再構築を行いました。変更はありません。Let’s Encrypt を多くの Discourse 以外のサイトで使用していますが、すべて正常に更新されています。はい、外部サイトからアクセスでき、wget を使用してテストしましたが、結果は 404 でした。質問: この場合、nginx の html ツリーは正確にどこに存在しますか。.well-known ディレクトリを含む(または含むべき)部分はどこですか。見つけられませんでした。ありがとうございます。
「いいね!」 2
cronジョブは見つかりませんでしたが、/etc/runit/1.d/letsencrypt にrunlevelスクリプトがありました。そのスクリプトは、nginxの新しいインスタンスを開始するように見えます。その設定には以下が含まれています。
location ~ /.well-known {
root /var/www/discourse/public;
allow all;
}
これにより、パスは/var/www/discourse/public/acme-challenge になると思いますが、チャレンジが実行される前に作成され、その後削除される可能性もあります。
手動で実行しようとしたスクリプトがそれである場合、nginxを停止しましたか?スクリプトが開始しようとするインスタンスはポート80でリッスンしようとするため、Discourseでnginxが既に実行されている場合、それは失敗すると思います。
「いいね!」 2
L30110
13
問題が見つかったかもしれませんが、修正方法がわかりません。httpsポート80のフォーラムへのすべてのアクセス試行が(予想通り)https 443にリダイレクトされているようです。しかし、これはLet’s Encryptが更新のために検証しようとすると、現在の証明書が期限切れになっているため失敗することを意味します。wgetでリダイレクトを確認できます。では、Let’s Encryptが検証して新しい期限切れでない証明書を取得できるように、リダイレクトを一時的に無効にするにはどうすればよいでしょうか?追加の潜在的な複雑さは、リダイレクトが301パーマネントであることです。よろしくお願いします。
「いいね!」 2
このリダイレクトは /etc/nginx/conf.d/discourse.conf にあり、nginx が停止してから、前の投稿で言及した設定で開始された場合には使用されません。
自動アップグレードの仕組みにあまり詳しくないので、コンテナを実行中に更新する適切な方法がわかりません。理論的には、コンテナを停止して開始するだけで更新されるはずですが、再構築でもうまくいかなかったとのことなので、それも同様にうまくいかないでしょう。
acme.sh には --renew-all のようなオプションがありますが、ここで正しいことを行うために他にどのようなオプションが必要かはわかりません。以下がすべて必要かもしれませんが、確実には言えません。
LE_WORKING_DIR="/shared/letsencrypt" /root/acme.sh/acme.sh --renew-all
「いいね!」 2
L30110
15
そして、これは確かにLet’s Encryptがリダイレクトなしでアクセスすることを可能にしますが、探しているファイルは存在しないため、結局同じ検証エラーになります。
「いいね!」 2
mbronstein
(Mark Bronstein)
16
私も同じ問題を抱えています。問題を修正するための明確な手順を誰かが把握しましたか?
「いいね!」 2
L30110
17
これで証明書を正常に取得しようとしています。curl が検証トークンを取得しているようですが、acme.sh は毎回検証に失敗すると宣言しています。まだダウンしています。
「/shared/letsencrypt」/acme.sh --renew-all --force --insecure --home 「/shared/letsencrypt」–debug
「いいね!」 2
griffin
(Jonathan Griffin)
18
こんにちは @L30110 
私はLet’s Encryptコミュニティの常連の一人です。@JimPasさんにこのスレッドを見るように言われましたので、昼食から戻り次第確認します。
「いいね!」 3
griffin
(Jonathan Griffin)
19
多くのACMEクライアント(acme.shなど)では、nginxが認証方法として指定されている場合、http-01チャレンジ ファイルは、Webルートディレクトリ内の.well-known/acme-challenge ディレクトリ構造に直接ではなく、nginxサーバー構成における例外/リダイレクトに基づいた特定のディレクトリに作成されます。多くの場合、このリダイレクトはチャレンジ検証の期間中のみ一時的に存在し、チャレンジファイル自体も同様です。
したがって:
賢明なご指摘です。適切に記述された更新スクリプトであれば、nginxを停止する必要はありません。通常、nginxはチャレンジファイルを配信するために使用され、その後、新しい証明書が取得されると、nginx -s reload のようなコマンドでWebサーバー/プロキシを正常にリロードします。
いいえ。
Challenge Types - Let's Encrypt によると:
HTTP-01チャレンジの実装は、最大10回の深いリダイレクトに従います。リダイレクトは「http:」または「https:」のみを受け入れ、ポート80または443のみを受け入れます。IPアドレスへのリダイレクトは受け入れません。HTTPS URLにリダイレクトする場合、証明書は検証しません(このチャレンジは有効な証明書をブートストラップすることを目的としているため、途中で自己署名または期限切れの証明書に遭遇する可能性があります)。
通常、このような問題が発生する場合、以下のいずれかが原因であることがほとんどです:
- ファイアウォールが、チャレンジファイルを配信しているWebサーバー/プロキシへのトラフィックを許可していない。
- ルーター/プロキシのマッピング/構成が不適切で、Boulder(Let’s EncryptのCAサーバー)からのチャレンジ検証リクエストが、誤ったWebサーバーまたはディレクトリからファイルを取得しようとしている。
- 何らかの書き換え/リダイレクト(例:Apacheの
.htaccessファイル)が、Webサーバー/プロキシが正しい場所からチャレンジファイルを配信するのを妨げている。
- 非標準ポートの使用、通常は不適切なマッピングを伴う。
- ACMEクライアントを実行しているコンテナが、Webサーバー/プロキシ(例:nginx)が配信しない場所にチャレンジファイルを作成している。Dockerが関与している場合、これはほぼ常に問題となります。
「いいね!」 2
L30110
20
こんにちは。ご提示いただいた項目の中で、いくつか私には明らかに当てはまらないものがあります。ファイアウォールの問題ではありません。Docker Discourseアプリの内部、Dockerコンテナ外のホストシステム、および関連システムから、wgetやcurlを使って手動でトークンにアクセスできます。
これらの手動の場合、Discourseが自動的にHTTPSにリダイレクトする際に期限切れの証明書を回避するために --ignore または -k を指定すると、期待される場所からトークンコンテンツを取得できます。
Discourseが作成したnginxの設定は、DiscourseのDockerコンテナ内外で一切変更していません。nginxのコピーは実行しておらず、Apacheはローカル使用のためだけに完全に別のポートで動作しています。これらすべてが2年以上正常に機能しており、証明書の更新も定期的に行われ、他のアプリの変更もなかったことを付け加えておきます。非常に安定したボックスです。
異常なポートはありません。
手動でトークンコンテンツを取得できるので、場所が間違っているとは考えにくいです。ただし…
テストのために手動でnginxを停止していませんでした。現在停止しましたが、大きな違いはありませんでした。acme.shからは同じエラー(現在再びエラー56)が発生します。コンテナ内でnginxを停止すると、ホスト上でrunsv nginxインスタンスが表示されますが、ワーカープロセスやキャッシュプロセスはありません。コンテナ内でnginxを再起動すると、ホスト上でワーカープロセスとキャッシュプロセスが、残っていたrunsv nginxとともに再表示されます。コンテナ内の sv start/stop nginx コマンドは、それらのアクションの期待される確認応答を返します。
しかし、上記で言及されている懸念事項が他にあります。そして、これまで長期間正常に機能していたのに、なぜこれが突然問題になるのか理解できません。
ローカルネットワーク外から使用されるフォーラムの静的IPアドレスは、ISPが静的IPアドレスを提供する方法の複雑さにより、そのマシンが自身に接続するために使用することはできません。私は通常、/etc/hosts ファイルにエントリを追加して、それらの名前のローカルネットワークIPアドレスを提供しています。そのため、同じマシン(コンテナ内または外、どちらもフォーラムの /etc/hosts に追加されています)でcurlを使用してテストする場合、外部サイトがDNS経由で名前を検索する場合とは異なる(ローカルの)IPアドレスが使用されます。これが関連する可能性はありますか?よろしくお願いします。
「いいね!」 2