¿UFW limitará Discourse también?

¿Cómo puede Discourse eludir UFW? Solo habilité el puerto 22, por lo que todos los demás puertos deberían estar cerrados. Pero un foro funcionó de todos modos. ¿Cómo es eso posible?

Gotita de DigitalOcean, pero eso no debería significar nada. Y ninguna instalación de un clic, sino la forma oficial.

Esta no es una pregunta de soporte pura, pero aquí no tenemos una categoría llamada Preguntas básicas estúpidas de principiantes :wink:

7 Me gusta

Entonces, si ejecutas ufw status verbose, ¿solo ves el sshd?

1 me gusta

Así es. Y UFW estaba habilitado.

1 me gusta

¿Qué se listó por defecto cuando ejecutaste ufw status verbose?

Para lo que creo que quieres, esperaría ver esto:
Por defecto: denegar (entrante), permitir (saliente), deshabilitado (enrutado)

Con el comportamiento que describes, esperaría ver esto:
Por defecto: permitir (entrante), permitir (saliente), deshabilitado (enrutado)

1 me gusta

¿Intentaste abrir el foro en una ventana de incógnito o en un navegador diferente? Es fácil dejarse engañar por la versión en caché que aparece. A mí mismo me ha pasado y otro desarrollador me dijo que el sitio de staging se veía bien cuando en realidad no estaba funcionando en absoluto.

1 me gusta

Solo 22/tcp (OpenSSH) ALLOW IN Anywhere como debería ser. Esas son las dos cosas que siempre hago: permitir OpenSSH y habilitar UFW.

Abro puertos solo si es necesario, como cuando instale Nginx. Pero como ese VPS era solo para Discourse, no hice nada más; olvidé UFW por completo.

Ese no puede ser el caso. Ese foro estuvo activo durante semanas.

Me desperté ante esta situación cuando conecté Nginx/Varnish a ese VPS y necesité abrir otro puerto, y me di cuenta de que el único que estaba abierto era el puerto 22.

Editar:
¿Cómo pude enviar correos electrónicos? El puerto 587 tampoco estaba abierto :flushed_face:

Esto es realmente extraño.

1 me gusta

No está claro si estás diciendo que el valor predeterminado está configurado en denegar o no. La razón por la que pregunto específicamente sobre la línea “Default” es porque es posible tener un valor predeterminado de permitir y configurar un puerto específico para permitir, aunque esto último no cambia nada en esa disposición.

Si alguien más configuró Discourse, ¿es posible que esa persona haya cambiado el valor predeterminado a permitir en lugar de permitir los puertos HTTP/HTTPS?

Supongo que esto es SMTP en otro lugar, tu servidor Discourse conectándose a ese servidor SMTP usando el puerto 587. Las conexiones salientes están permitidas en todos los puertos por defecto, por lo que UFW no interferirá con el envío de correos electrónicos a menos que cambies explícitamente la política de salida.

4 Me gusta

[quote=“Simon Manning, post:7, topic:231873, username:Simon_Manning”]La razón por la que pregunto específicamente sobre la línea “Default”
[/quote]

Mi error :man_facepalming:

Default: deny (incoming), allow (outgoing), deny (routed)

[quote=“Simon Manning, post:7, topic:231873, username:Simon_Manning”]¿es posible que esa persona haya cambiado el valor predeterminado a permitir en lugar de permitir los puertos HTTP/HTTPS?
[/quote]

No. Pero ¿allow (outgoing) permite algo saliente? Si es así, entonces volvemos a “no tenemos aquí una categoría llamada Preguntas estúpidamente básicas de principiantes” y he aprendido cosas nuevas.

Editar:

Todavía estoy perdido, pero ¿cómo es deny (incoming)?

2 Me gusta

Encontré esto:

2 Me gusta

La respuesta corta es que Discourse no puede eludir las reglas de su firewall y el lugar para hacer preguntas estúpidas sobre cosas del sistema operativo es en algún lugar como Stack Exchange. (Por favor, no piense que soy grosero. Ahí es donde residen esas respuestas. Después de ejecutar Linux desde los primeros lanzamientos, todavía voy a lugares como ese para todas mis preguntas estúpidas. ¡Todavía las tengo!)

3 Me gusta

Conozco el lugar :wink: Hay una relación señal/ruido demasiado alta. Bueno, esa fue una caracterización injusta, pero quise decir que es realmente difícil encontrar cosas relevantes allí. Es tan masivo.

2 Me gusta

Esta es en realidad una muy buena pregunta y una que me sorprende que nadie más haya hecho todavía. La respuesta es complicada, pero hasta ahora las respuestas sobre este tema han sido desafortunadamente despectivas en tono sin responder a la pregunta.

No es que Discourse esté eludiendo ufw, sino que docker elude ufw agregando reglas que hacen que los puertos expuestos de los contenedores de docker funcionen a pesar de la presencia de ufw.

¿Qué está pasando?

Los paquetes entrantes destinados a un contenedor llegan a la tabla FORWARD, no a la tabla INPUT como se podría esperar.

Instalación previa de docker

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ufw-before-logging-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-before-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-after-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-after-logging-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-reject-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-track-forward  all  --  any    any     anywhere             anywhere

Instalación posterior de docker

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    8   416 DOCKER-USER  all  --  any    any     anywhere             anywhere            
    8   416 DOCKER-ISOLATION-STAGE-1  all  --  any    any     anywhere             anywhere            
    0     0 ACCEPT     all  --  any    docker0  anywhere             anywhere             ctstate RELATED,ESTABLISHED
    4   256 DOCKER     all  --  any    docker0  anywhere             anywhere            
    4   160 ACCEPT     all  --  docker0 !docker0  anywhere             anywhere            
    0     0 ACCEPT     all  --  docker0 docker0  anywhere             anywhere            
    0     0 ufw-before-logging-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-before-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-after-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-after-logging-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-reject-forward  all  --  any    any     anywhere             anywhere            
    0     0 ufw-track-forward  all  --  any    any     anywhere             anywhere

La razón por la que los paquetes llegan a la tabla forward se debe a las reglas que docker agrega a la tabla nat:

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  210 12734 DOCKER     all  --  any    any     anywhere             anywhere             ADDRTYPE match dst-type LOCAL

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 any     anywhere             anywhere            
    0     0 DNAT       tcp  --  !docker0 any     anywhere             anywhere             tcp dpt:https to:172.17.0.2:443
  107  6848 DNAT       tcp  --  !docker0 any     anywhere             anywhere             tcp dpt:http to:172.17.0.2:80

nat/PREROUTING se procesa antes de que se tome la decisión de enviar paquetes a través de INPUT o FORWARD.

En última instancia, el problema es que hay dos servicios en el sistema que modifican las reglas del firewall. ufw no sabe nada de esto, por lo que solo puede informar lo que él ha configurado.

Una solución

Para esto, se debe reconfigurar el firewall para que pase el tráfico destinado a docker a través de las cadenas de ufw también:

Utilizo la siguiente ligera adaptación de su trabajo, implementada antes de habilitar ufw:

# Robado de https://github.com/chaifeng/ufw-docker - parece sensato
# añadir el reenvío a ufw-user-input permite conexiones a
# puertos reenviados que hemos abierto explícitamente
cat <<EOUFW >> /etc/ufw/after.rules
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-user-input - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j ufw-user-input

-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16

-A DOCKER-USER -j RETURN
COMMIT
# END UFW AND DOCKER
EOUFW
20 Me gusta

¡Gracias! Esa fue una explicación completa.

4 Me gusta

Bienvenido, así es como me muevo :smiley:

6 Me gusta

Este tema está resuelto, pero reveló un problema menor en mi configuración. Lo explicaré si alguien busca algo similar algún día.

Tenía un VPS donde Nginx se encarga de SSL y otras cosas de todos mis sitios (muchos de ellos, el inglés es un idioma muy extraño :wink: ). Nginx envía solicitudes a Varnish. Es un proxy inverso inútil para Discourse, pero realiza cierto filtrado. Varnish envía solicitudes a otro VPS donde vive Discourse usando el puerto 83. Ambos VPS escuchan el mismo puerto y solo se permite a ambas IPs. Estaba totalmente feliz, hasta ahora.

Probé qué sucede cuando usé el puerto 443 curl -I https://forum.example.tld:443. Funcionó bien, porque todavía tengo un certificado SSL válido en el lado de Discourse (hice este cambio hace algunas semanas).

La respuesta de @supermathie explica por qué sucede esto y cómo solucionarlo. Claro, no hay problemas de seguridad debido a eso en absoluto, hasta donde sé, pero es realmente molesto :squinting_face_with_tongue:

2 Me gusta

¡Vaya! ¡Eso es una locura! Gracias.

Supongo que no se pregunta porque no es frecuente que alguien instale discourse y quiera que no funcione, así que cuando docker lo hace funcionar cuando has configurado el firewall de tal manera que no debería, la mayoría de la gente no se queja. :wink:

Es un problema muy interesante, pero parece un poco esotérico, y no es un problema de Discourse, sino una peculiaridad de docker. La pregunta se reduce a “¿cómo puedo configurar mi firewall para evitar que discourse funcione?”. Intentaré recordar lo de la preruta.

¡Si supiera la respuesta, no habría sido despectivo! ¡Gracias por salvar el día en este asunto!

6 Me gusta

Ciertamente no intentaba ser despectivo, sino solucionar problemas… aunque evidentemente partía de una posición de ignorancia sobre lo que Docker estaba haciendo. ¡Toda esa información es muy útil, gracias por responder!

Si el OP o alguien más puede cambiarlo, podría valer la pena cambiar la solución marcada.

Si bien es más un problema de Docker, puedo ver algunas hipótesis de Discourse que se derivan de esto. Por ejemplo, podría tener un servidor de oficina accesible desde el exterior, pero quiero configurar UFW para restringir Discourse a que solo sea accesible desde el interior de la oficina. Las adiciones de Docker impedirían esa configuración.

Aunque en ese escenario en particular, lo configuraría en un firewall de hardware/hipervisor en lugar de UFW en el host de todos modos.

5 Me gusta

Acabo de llegar al mismo repositorio de git que encontraste, investigando un problema de ufw/docker, me hizo pensar en este tema.

¿Qué cambiaste exactamente (quiero decir, puedo ver las líneas añadidas, pero qué significa?) y estos cambios son específicamente para Discourse?

Usé el código predeterminado en el repositorio y mi problema de UFW pareció solucionarse después de eso.

EDITAR: Cuando uso tu código editado, en el primer momento en que ejecuto ufw reload obtengo el siguiente error:

ERROR: No se pudieron cargar las reglas de registro

1 me gusta

En realidad, lo resolví después de un tiempo y escribí este script de bash para hacerlo en instalaciones de Discourse.

Restablece tu firewall, instala ufw-docker-util (que edita el archivo after.rules), luego agrega los puertos 443 y 80 a tu lista de permitidos. Listo.

También permite el puerto 22 desde cualquier IP para asegurarte de no quedarte fuera. Después de que todo funcione, vuelve a asegurar el puerto 22.

EDITAR: el script funciona pero reconstruir Discourse después de usarlo fallará: fatal: unable to access 'https://github.com/discourse/discourse.git/': Could not resolve host: github.com - así que NO uses el script a menos que sepas cómo resolver esto.

EDITAR 2: Funciona en Ubuntu, ¡pero no en CentOS!

3 Me gusta

La última vez que hice un script de bash, cambié el propietario de todos los directorios a www-data:www-data, ¡así que para mí un trabajo como este me facilita la vida! :wink:

Pero en general, me gustaría ver que Docker siga completamente UFW/iptables. Solo porque uso GeoIP-blocking a través de ipables (sí, lo sé, UFW es solo una interfaz minimalista para iptables).

Claro, ya no estamos en Discourse, pero aquí podemos ver por qué los programadores y los usuarios finales no siempre se entienden tan bien: los programadores ven el mundo como bloques lógicos y construcciones if/then/else, pero los usuarios finales lo ven con contexto completo. Significa que, como uso Discourse, aunque funcione dentro de Docker, desde mi punto de vista es Discourse el que no sigue mis reglas :rofl:

Esto debería ir a Praise, pero cambié la URL del foro hace unas semanas. Y conseguí que todos los script kiddies del mundo y bots de SEO inútiles me visitaran. Conseguí en un VPS de 2 GB/1 vCPU de DigitalOcean 3000 agentes de usuario diferentes por hora y Discourse simplemente no se preocupó. Cualquier instalación de WordPress sería lenta/caída después de ese tipo de rush tipo ddos.

Entonces, no necesito forzar a Discourse (bueno, a Docker) a seguir las prohibiciones de Fail2ban y mis reglas, pero odio tanto a esos bots.

3 Me gusta