Gelegentliche OAuth-Fehler

Wir verwenden externes OAuth für die Benutzerauthentifizierung. Gelegentlich erhalten Benutzer den Fehler 500, wenn sie auf die Plattform zugreifen: Ausschnitt aus dem Fehlerprotokoll:

Started GET "/auth/oauth2_basic/callback?code=[coderemoved]&state=[stateremoved]" for [IP] at [timestamp]
(oauth2_basic) Setup endpoint detected, running now.
(oauth2_basic) Callback phase initiated.
Faraday::TimeoutError (Timeout::Error)
lib/final_destination/resolver.rb:31:in `block in lookup'
lib/final_destination/resolver.rb:8:in `synchronize'
lib/final_destination/resolver.rb:8:in `lookup'
lib/final_destination/ssrf_detector.rb:127:in `lookup_ips'
lib/final_destination/ssrf_detector.rb:95:in `lookup_and_filter_ips'
lib/final_destination/http.rb:13:in `connect'
lib/middleware/omniauth_bypass_middleware.rb:43:in `call'
lib/middleware/content_security_policy.rb:12:in `call'
lib/middleware/anonymous_cache.rb:387:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/request_tracker.rb:233:in `call'

Wenn der Benutzer die Seite einfach neu lädt, funktioniert alles, mit folgenden Protokollinformationen:

Started GET "/auth/oauth2_basic/callback?code=[coderemoved]&state=[stateremoved]" for [IP] at [timestamp]
(oauth2_basic) Setup endpoint detected, running now.
(oauth2_basic) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#complete as HTML
  Parameters: {"code"=>"[coderemoved]", "state"=>"[stateremoved]", "provider"=>"oauth2_basic"}
Deprecation notice: `SiteSetting.anonymous_posting_min_trust_level` has been deprecated. Please use `SiteSetting.anonymous_posting_allowed_groups` instead. (removal in Discourse 3.3) 
At /var/www/discourse/lib/site_setting_extension.rb:160:in `public_send`
start
Redirected to https://[pageremoved]
Completed 302 Found in 83ms (ActiveRecord: 0.0ms | Allocations: 11138)

Leider keine Schritte zur Reproduktion. Es passiert tendenziell bei Benutzern, die längere Zeit inaktiv waren, aber ich kann dies nicht mit Sicherheit bestätigen. Es ist möglich, dass seit ihrem letzten Besuch ein Plattform-Upgrade stattgefunden hat.
Haben Sie Vorschläge oder zusätzliche Informationen, die ich bereitstellen könnte?

Ich pushe das mal hoch. Ich habe genau die gleichen Probleme.

Timeout-Fehler deutet auf ein Netzwerkproblem hin. Könnte nur eine Netzwerkstörung sein.

Ich habe das auch gedacht, aber der Fehler tritt viel zu schnell auf, als dass es sich um ein normales Verhalten handeln könnte. Ich frage mich, ob irgendwo ein übermäßig aggressiver DNS-Lookup-Timeout vorliegt:

  1. Der Fehler liegt in „resolver.rb“.
  2. Er wird vorübergehend durch Aktualisieren behoben – wenn der DNS-Lookup zwischengespeichert würde.
  3. Aus einem völlig unerklärlichen Grund kann ich das OIDC-Discovery-Dokument von keiner URL lesen, die unser selbst gehostetes DNS beinhaltet. Dies, obwohl ich die Datei manuell aus der Docker-Instanz heraus mit curl abrufen kann. Ich habe viele verschiedene Variablen ausgeschlossen und das DNS scheint der einzige gemeinsame Nenner zu sein.

Wichtig ist, dass der Discourse-Server mit dem OIDC-Server kommunizieren kann, auch wenn er wie hier fehlschlägt. Aus den Zugriffsprotokollen geht hervor, dass es eine Anfrage gibt:

21/Jan/2024:23:10:21 +0000] "POST /application/o/token/ HTTP/1.1" 200 7998 "-" "Faraday v2.9.0"

wenn es fehlschlägt, und zwei Anfragen:

[21/Jan/2024:23:21:03 +0000] "POST /application/o/token/ HTTP/1.1" 200 7998 "-" "Faraday v2.9.0"
[21/Jan/2024:23:21:05 +0000] "GET /application/o/userinfo/ HTTP/1.1" 200 5254 "-" "Faraday v2.9.0"

wenn es erfolgreich ist. Unabhängig davon dauert es nie länger als 5 Sekunden. Ich muss noch einen Proxy für den OIDC-Server einrichten, der Cloudflare DNS verwendet, aber das wird mein nächster Schritt sein.

Der Volksmund sagt, es liegt immer am DNS.

Nun, es ist definitiv DNS. Anstatt einen Proxy einzurichten, habe ich meinen OIDC-Server zur hosts-Datei im Docker-Container hinzugefügt und es scheint jetzt zu funktionieren. Dies ist jedoch eine fragile und suboptimale Lösung; Ich denke, die Entwickler müssen das Timeout beheben, damit es etwas Sinnvolles ist. Dieser Fall erinnert mich an die 500-Meilen-E-Mail-Geschichte.

Sie können Dinge zu Ihrer app.yml hinzufügen, um /etc/hosts bei einem Rebuild zu aktualisieren. Schauen Sie sich andere Vorlagen als Beispiele an.

Könnte sein, aber nicht viele Leute haben Probleme. Könnte Ihr selbst gehosteter DNS-Server manchmal überlastet sein?

Ich weiß nicht, wo ich das Timeout ändern soll. Ich erinnere mich nicht, es jemals getan zu haben.

In meinem Fall befinden sich die IdP- und Discourse-VMs nebeneinander und obwohl niemand Netzwerkprobleme vollständig ausschließen kann, hat kein anderer Dienst Probleme.