Después de actualizar a 2.5.0.beta4, veo errores CSRF en el registro de producción:
Procesando por SessionController#csrf como JSON
Completado 200 OK en 1ms (Vistas: 0.1ms | ActiveRecord: 0.0ms | Asignaciones: 351)
Iniciado POST "/session" para 127.0.0.1 el 2020-05-05 09:25:17 +0000
Procesando por SessionController#create como */*
Parámetros: {"login"=>"admin", "password"=>"[FILTRADO]", "second_factor_method"=>"1", "timezone"=>"Europe/Berlin"}
No se puede verificar la autenticidad del token CSRF.
Renderizando plantilla de texto
Renderizada plantilla de texto (Duración: 0.0ms | Asignaciones: 1)
La cadena de filtros se detuvo porque :verify_authenticity_token renderizó o redirigió
Completado 403 Forbidden en 2ms (Vistas: 0.7ms | Asignaciones: 1100)
Además, discourse doctor muestra:
========================================
Discourse 2.5.0.beta4
Versión de Discourse en forum.netzwissen.de: Discourse 2.5.0.beta4
Versión de Discourse en localhost: NO ENCONTRADO
==================== PROBLEMA DE DNS ====================
Este servidor reporta NO ENCONTRADO, pero forum.netzwissen.de reporta Discourse 2.5.0.beta4.
Esto sugiere que tienes un problema de DNS o que un proxy intermedio es el culpable.
Si estás usando Cloudflare o una CDN, es posible que esté configurada incorrectamente.
Pregunta: el servidor en sí aloja múltiples servicios con diferentes nombres DNS. Delante de Discourse tenemos un servidor haproxy para manejar la terminación SSL. No entiendo el mensaje de error:
“Versión de Discourse en localhost: NO ENCONTRADO”
¿Es posible que el error CSRF esté relacionado con este mensaje de error?
Discourse-doctor no pretende ser capaz de diagnosticar una configuración compleja como la tuya. Solo compara si el host local y el DNS devuelven el mismo valor. Para tu configuración, se espera que sean diferentes.
Sin embargo, no tengo ninguna pista sobre tu problema real. Lo siento.
Hola,
vale, he probado con otra cuenta y obtengo el mismo mensaje de error. Parece que los inicios de sesión están totalmente bloqueados ahora y el error CSRF podría ser la causa raíz…
¿Alguna idea para más depuración? Mi app.yml es bastante estándar, excepto que:
expose:
- "127.0.0.1:884:80" # http
Las solicitudes entrantes se reenvían desde un servidor haproxy al contenedor de Discourse en el puerto 884. SSL/HTTPS lo gestiona haproxy.
Al registrar un nuevo usuario mediante OAuth2 (Google), también obtengo un error de CSRF:
Renderizado common/_discourse_stylesheet.html.erb (Duración: 0.4ms | Asignaciones: 206)
Renderizado application/_header.html.erb (Duración: 0.3ms | Asignaciones: 142)
Completado 200 OK en 23ms (Vistas: 20.4ms | ActiveRecord: 0.0ms | Asignaciones: 4636)
Iniciado GET "/latest.json?order=default" para 127.0.0.1 el 2020-05-05 11:43:08 +0000
Procesado por ListController#latest como JSON
Parámetros: {"order"=>"default"}
Completado 200 OK en 30ms (Vistas: 0.1ms | ActiveRecord: 0.0ms | Asignaciones: 10224)
Iniciado GET "/u/hp.json" para 127.0.0.1 el 2020-05-05 11:43:08 +0000
Procesado por UsersController#get_honeypot_value como JSON
Completado 200 OK en 3ms (Vistas: 0.1ms | ActiveRecord: 0.0ms | Asignaciones: 1049)
Iniciado GET "/session/csrf" para 127.0.0.1 el 2020-05-05 11:43:38 +0000
Procesado por SessionController#csrf como JSON
Completado 200 OK en 1ms (Vistas: 0.2ms | ActiveRecord: 0.0ms | Asignaciones: 355)
Iniciado POST "/auth/google_oauth2" para 127.0.0.1 el 2020-05-05 11:43:38 +0000
(google_oauth2) Punto de configuración detectado, ejecutándose ahora.
(google_oauth2) Fase de solicitud iniciada.
Iniciado GET "/auth/failure?message=csrf_detected" para 127.0.0.1 el 2020-05-05 11:43:38 +0000
Procesado por Users::OmniauthCallbacksController#failure como HTML
Parámetros: {"message"=>"csrf_detected"}
Renderizando users/omniauth_callbacks/failure.html.erb dentro de layouts/no_ember
Renderizado users/omniauth_callbacks/failure.html.erb dentro de layouts/no_ember (Duración: 0.1ms | Asignaciones: 20)
Renderizado layouts/_head.html.erb (Duración: 11.7ms | Asignaciones: 3551)
Renderizado common/_discourse_stylesheet.html.erb (Duración: 0.5ms | Asignaciones: 213)
Renderizado application/_header.html.erb (Duración: 0.9ms | Asignaciones: 555)
Completado 200 OK en 19ms (Vistas: 16.4ms | ActiveRecord: 0.0ms | Asignaciones: 7652)
¿Lograste solucionar el problema? Me imagino que la actualización vino con una nueva versión de nginx (o su configuración) que provocó este problema (pero es pura hipótesis ;-)).
Intenté buscar una forma de desactivar CSRF en nginx (GitHub - gartnera/nginx_csrf_prevent: Prevent CSRF with nginx · GitHub), pero creo que nginx debe recompilarse, y no sé si necesitamos el entorno de desarrollo completo de Discourse para hacerlo.
Desafortunadamente, el problema aún no está resuelto aquí. El inicio de sesión falla con “error desconocido” y, en cada intento, veo esto en el registro:
root@develd:/var/discourse# tail -f /var/log/discourse-rails/production.log
Processing by SessionController#csrf as JSON
Completed 200 OK in 1ms (Views: 0.1ms | Allocations: 351)
Started POST "/session" for 127.0.0.1 at 2020-06-07 06:58:19 +0000
Processing by SessionController#create as */*
Parameters: {"login"=>"admin", "password"=>"[FILTERED]", "second_factor_method"=>"1", "timezone"=>"Europe/Berlin"}
Can't verify CSRF token authenticity.
Rendering text template
Rendered text template (Duration: 0.0ms | Allocations: 1)
Filter chain halted as :verify_authenticity_token rendered or redirected
Completed 403 Forbidden in 2ms (Views: 0.8ms | ActiveRecord: 0.0ms | Allocations: 1100)
Started GET "/session/csrf" for 127.0.0.1 at 2020-06-07 07:00:45 +0000
Processing by SessionController#csrf as JSON
Completed 200 OK in 1ms (Views: 0.2ms | Allocations: 351)
Started POST "/session" for 127.0.0.1 at 2020-06-07 07:00:45 +0000
Processing by SessionController#create as */*
Parameters: {"login"=>"admin", "password"=>"[FILTERED]", "second_factor_method"=>"1", "timezone"=>"Europe/Berlin"}
Can't verify CSRF token authenticity.
Rendering text template
Rendered text template (Duration: 0.0ms | Allocations: 1)
Filter chain halted as :verify_authenticity_token rendered or redirected
Completed 403 Forbidden in 2ms (Views: 0.9ms | Allocations: 1100)
El archivo app.yml tiene:
## Any custom commands to run after building
run:
- exec: echo "Beginning of custom commands"
## If you want to set the 'From' email address for your first registration, uncomment and change:
## After getting the first signup email, re-comment the line. It only needs to run once.
## - exec: rails r "SiteSetting.notification_email='noreply-discourse@netzwissen.de'"
- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
set_real_ip_from 127.0.0.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
types {
- exec: echo "End of custom commands"
Con eso pude iniciar sesión correctamente, pero ten cuidado dónde aplicas la corrección al comando proxy_pass. Solo funciona en location @discourse { .. }
ok, solo para entender: estamos hablando del nginx dentro del “zoológico de contenedores”, ¿correcto? Porque, antes de la actualización a 2.5.0beta4, no había ningún requisito para parchear esto, simplemente funcionaba sin problemas.
Hemos realizado más depuración aquí: el problema comienza en el servidor nginx dentro del contenedor. No entiende la directiva proxy_pass y, por lo tanto, parece fallar, pero ¿por qué:
root@develd:/var/discourse# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8f6103a036d local_discourse/app "/sbin/boot" 35 segundos atrás Up 32 segundos 127.0.0.1:884->80/tcp app
43406c37f403 discourse/base:2.0.20200512-1735 "ruby -e 'require 'y…" hace 2 horas Created
docker exec -it f8f6103a036d /bin/bash
root@forum:/# tail -f /var/log/nginx/error.log
2020/06/08 19:05:03 [emerg] 288#288: la directiva "proxy_pass" no está permitida aquí en /etc/nginx/conf.d/discourse.conf:10
Estoy usando esta configuración de nginx en app.yml:
## Cualquier comando personalizado para ejecutar después de la compilación
run:
- exec: echo "Inicio de comandos personalizados"
## Si deseas establecer la dirección de correo electrónico 'From' para tu primer registro, descomenta y cambia:
## Después de recibir el primer correo de registro, vuelve a comentar la línea. Solo necesita ejecutarse una vez.
## - exec: rails r "SiteSetting.notification_email='noreply-discourse@netzwissen.de'"
- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
set_real_ip_from 127.0.0.0/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
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 https; # $thescheme; <-- Lo que modifiqué
proxy_pass http://discourse;
types {
- exec: echo "Fin de comandos personalizados"
Creo que no necesitas ese proxy_pass justo ahí en tu app.yml. Mi configuración se ve así:
after_bundle_exec:
# Esto es lo mágico para transmitir las direcciones IP a Discourse
# Ver https://meta.discourse.org/t/last-ip-address-and-action-dispatch-trusted-proxies/50098/3?u=pfaffman
- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 172.18.0.0/24;
set_real_ip_from 172.17.0.0/24;
real_ip_recursive on;
real_ip_header X-Forwarded-For;
types {
Pero es posible que mi código sea anterior al cambio a Debian en los contenedores.
Podrías intentar editar directamente ese archivo dentro del contenedor y reiniciar nginx.
Solo para asegurarnos, dentro del propio contenedor, edite /etc/nginx/conf.d/discourse.conf y aplique el parche al archivo como se indicó anteriormente. Luego, reinicie nginx de la siguiente manera:
El consejo de Jays fue correcto: simplemente eliminé proxy_pass y luego funcionó. La configuración final en app.yml es:
## Cualquier comando personalizado para ejecutar después de la compilación
run:
- exec: echo "Inicio de comandos personalizados"
## Si deseas establecer la dirección de correo electrónico 'De' para tu primer registro, descomenta y modifica:
## Después de recibir el primer correo de registro, vuelve a comentar la línea. Solo necesita ejecutarse una vez.
## - exec: rails r "SiteSetting.notification_email='noreply-discourse@netzwissen.de'"
- replace:
filename: /etc/nginx/conf.d/discourse.conf
from: "types {"
to: |
set_real_ip_from 127.0.0.1/24;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
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 https; # $thescheme; <-- Lo que modifiqué
types {
- exec: echo "Fin de los comandos personalizados"