Ich betreibe Discourse hinter Traefik in einem benutzerdefinierten Setup – Discourse eine eigene VM zu geben, ist hier keine Option.
Mein Discourse hat keine SSL/Let’s Encrypt-Vorlagen aktiviert, da Traefik keine reinen HTTP-Anfragen an den Container lässt – es ist so eingestellt, dass HTTP-Anfragen zu HTTPS umgeleitet werden.
Ich habe Probleme bei der Einrichtung von DiscourseConnect, denn da die Anfrage Traefik -> nginx[Discourse] über unverschlüsseltes HTTP gesendet wird (weil nginx keine SSL-Einrichtung hat), bewirkt die Regel in /etc/nginx/conf.d/discourse.conf, die versucht, das Protokoll beizubehalten, muss im http-Kontext stehen, dass Discourse (die Rails-App) eine unverschlüsselte HTTP-Anfrage erhält und somit eine unverschlüsselte HTTP-Umleitung zu /session/sso zurückgibt – auch wenn ich force_https aktiviert habe.
Ich glaube, das ist der Fehler: Unabhängig von meinem Setup sollte Discourse mit aktiviertem force_https immer HTTPS-URLs generieren – was es nicht tut.
Ich glaube, der problematische Code ist application_controller#redirect_to_login, aber ich habe den Discourse-Quellcode noch nicht so tief durchforstet, um sicher zu sein.
Ist das im Code selbst lösbar?
Als Workaround versuche ich, eine Regel hinzuzufügen, die die discourse.conf von nginx patcht, um diese Regel zu entfernen.
Am einfachsten war es für mich, ein zusätzliches Label in Discourse’s app.yml zu setzen, um meinem Traefik mitzuteilen, dass es einen X-Forwarded-Proto: https Header hinzufügen soll, aber dann überschrieb nginx diesen Parameter mit seiner eigenen Version.
Und Discourse’s nginx-Konfiguration spielt hier eine Rolle:
Dort versucht Discourse, das Protokoll aus der ursprünglichen Anfrage zu erraten (die in meinem Setup immer Plain-Text ist, da das Traefik sendet). Und verwendet dies dann, um den X-Forwarded-Proto mehrmals zu setzen.
Am Ende habe ich meine containers/app.yml bearbeitet, um diese Header auf https zu fixieren:
run:
- exec: echo "Beginning of custom commands"
## Wenn Sie die 'Von'-E-Mail-Adresse für Ihre erste Registrierung festlegen möchten, kommentieren Sie die Zeile aus und ändern Sie sie:
## Nachdem Sie die erste Registrierungs-E-Mail erhalten haben, kommentieren Sie die Zeile wieder aus. Sie muss nur einmal ausgeführt werden.
# - exec: rails r "SiteSetting.notification_email='no-reply@forum.cabana.network'"
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: /# attempt to preserve the proto, must be in http context\nmap \$http_x_forwarded_proto \$thescheme {\n default \$scheme;\n "~https$" https;\n}/\n
to: |
# force https scheme so Discourse generates HTTPs links and redirects (ie, `/login`)
- replace:
filename: "/etc/nginx/conf.d/discourse.conf"
from: "$thescheme"
global: "true"
to: "https"
- exec: echo "End of custom commands"
Noch einmal, ich denke, wenn es eine force_https-Einstellung gäbe, sollte Discourse-the-rails-app diese respektieren, unabhängig davon, was der Reverse-Proxy oder andere Parteien handhaben oder nicht.
So machen wir das auf unserer Hosting-Plattform; wir haben eine Load-Balancer-Schicht, die X-Forwarded-Proto für das nachgelagerte Nginx+Discourse setzt, damit es diese Informationen verbrauchen kann.
Wir brauchen keine zusätzlichen Tricksereien, damit es funktioniert - ich bin mir nicht sicher, was bei Ihnen schiefgeht.