El firewall sin complicaciones (UFW) no bloquea nada cuando se usa Docker

44

Esta es la primera vez que configuro un servidor Ubuntu (14.04 LTS) y tengo problemas para configurar el firewall (UFW).

Solo necesito sshy http, así que estoy haciendo esto:

sudo ufw disable

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp

sudo ufw enable
sudo reboot

Pero aún puedo conectarme a bases de datos en otros puertos de esta máquina . ¿Alguna idea de lo que estoy haciendo mal?

EDITAR : estas bases de datos están en contenedores Docker. ¿Podría esto estar relacionado? ¿está anulando mi configuración ufw?

EDIT2 : salida desudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)
ESala
fuente
que base de datos cual puerto? ¿Estás seguro de que esta es la misma máquina? cual es la salida de ufw status
solsTiCe
@solsTiCe sí, estoy seguro de que es la misma máquina. La base de datos es InfluxDB (en un contenedor acoplable) con puertos 8083y 8086. Agregué el ufw status verboseresultado en la pregunta. Gracias.
ESala

Respuestas:

64

El problema era usar la -pbandera en los contenedores.

Resulta que Docker realiza cambios directamente en su iptables, que no se muestran con ufw status.

Las posibles soluciones son:

  1. Deja de usar la -pbandera. Utilice la conexión de docker o las redes de docker en su lugar.

  2. Ate los contenedores localmente para que no queden expuestos fuera de su máquina:

    docker run -p 127.0.0.1:8080:8080 ...

  3. Si insiste en usar la -pbandera, dígale a Docker que no toque la iptablessuya deshabilitándolas /etc/docker/daemon.jsony reiniciando:

    { "iptables" : false }

Recomiendo la opción 1 o 2. Tenga en cuenta que la opción 3 tiene efectos secundarios , como que los contenedores no puedan conectarse a Internet.

ESala
fuente
8
Esto es muy útil: me estaba volviendo loco al poder acceder a puertos que no había permitido en ufw. Sin embargo, el uso de iptables = false rompe mucho, como que los contenedores se vuelvan accesibles en localhost, por ejemplo, para proxy inverso. Es mejor asegurarse de que el contenedor escuche correctamente, no use -p 80:80 pero use -p 127.0.0.1:80:80 o un puerto diferente como 127.0.0.1:3000:80 para proxy inverso con nginx o apache y sin puerto choques
Andreas Reiff
2
@AndreasReiff tienes razón, pero últimamente he encontrado lo mejor para evitar -plo máximo posible. Por ejemplo, en el caso de un proxy inverso, no asigno ningún puerto para los contenedores de trabajo, y luego pongo nginx en su propio contenedor con -p 80:80y --linka los demás. De esta forma no puede haber ningún conflicto de puertos y el único punto de acceso es a través de nginx.
ESala
1
¡También revise esta publicación para ver una tercera precaución que debe tomar! svenv.nl/unixandlinux/dockerufw
Henk
1
Importante : /etc/default/dockeres un archivo de configuración utilizado por la configuración inicial. Si ha pasado del sistema de arranque al sistema, este archivo no se utilizará.
orshachar
@ESala Debería pensar en desmarcar esta respuesta como correcta ya que está fechada.
ctbrown
8

16.04 presenta nuevos desafíos. Hice todos los pasos como se muestra Ejecutando Docker detrás del firewall ufw PERO NO pude hacer que Docker más UFW funcionara en 16.04. En otras palabras, no importa lo que hice, todos los puertos acoplables quedaron expuestos globalmente a Internet. Hasta que encontré esto: Cómo configurar Docker 1.12+ para que NO interfiera con IPTABLES / FirewallD

Tuve que crear el archivo /etc/docker/daemon.jsony poner lo siguiente en:

{
    "iptables": false
}

Entonces emití sudo service docker stopentonces sudo service docker startFINALMENTE ventana acoplable está simplemente siguiendo las reglas apropiadas en UFW.

Datos adicionales: ¡ Docker anula UFW!

Hal Jordan
fuente
Con Ubuntu 16.04 y Docker versión 17.09, esta solución interrumpe la conexión saliente de los contenedores. Consulte la respuesta askubuntu.com/a/833363/262702 y askubuntu.com/a/954041/262702
ctbrown el
5

Si está utilizando el sistema init de systemd (Ubuntu 15.10 y posterior) edite el /etc/docker/daemon.json(puede que necesite crearlo si no existe), asegúrese de que tenga la iptablesclave configurada:

{   "iptables" : false }

EDITAR : esto puede hacer que pierda la conexión a Internet desde contenedores internos

Si tiene UFW habilitado, verifique que puede acceder a Internet desde dentro de los contenedores. si no, debe definir DEFAULT_FORWARD_POLICYcomo ACCEPTactivado /etc/default/ufwy aplicar el truco descrito aquí: https://stackoverflow.com/a/17498195/507564

orshachar
fuente
2

Una solución rápida es cuando se ejecuta Docker y se realiza la asignación de puertos. Siempre puedes hacer

docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...

para evitar que se acceda a su Docker desde el exterior.

kimy82
fuente
2

Uso de /etc/docker/daemon.jsoncon contenido

{
  "iptables": false
}

Puede sonar como una solución, pero solo funciona hasta el próximo reinicio . Después de eso, puede notar que ninguno de sus contenedores tiene acceso a Internet, por lo que no puede hacer ping a ningún sitio web. Puede ser un comportamiento no deseado.

Lo mismo se aplica al enlace de un contenedor a una IP específica. Es posible que no quieras hacer eso. La última opción es crear un contenedor y tenerlo detrás de UFW sin importar lo que pase y cómo se crea este contenedor, por lo que hay una solución:

Después de crear el /etc/docker/daemon.jsonarchivo, invoque:

sed -i -e 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload

así que configura la política de reenvío predeterminada en UFW para aceptar y usa:

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE

Si está a punto de usar docker-compose, la IP del comando anterior debe reemplazarse por la IP de la red docker-compose que se crea al ejecutarlo docker-compose up.

Describí el problema y la solución de manera más completa en este artículo

¡Espero eso ayude!

mkubaczyk
fuente
1

En mi caso, terminé modificando iptables para permitir el acceso a Docker solo desde IP específicas.

Según la respuesta de ESala :

Si usa el -pindicador en los contenedores, Docker realiza cambios directamente en iptables, ignorando el ufw.

Ejemplo de registros agregados a iptables por Docker

Enrutamiento a la cadena 'DOCKER':

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Reenvío de paquetes de la cadena 'DOCKER' al contenedor:

-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379

Puede modificar iptables para permitir el acceso a la cadena DOCKER solo desde la IP de origen especificada (por ejemplo 1.1.1.1):

-A PREROUTING -s 1.1.1.1 -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -s 1.1.1.1 ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Es posible que desee usar iptables-save > /tmp/iptables.confy iptables-restore < /tmp/iptables.confvolcar, editar y restaurar las reglas de iptables.

Mecánico AI
fuente
0

Use --network = host cuando inicie el contenedor para que Docker asigne el puerto a la red aislada de solo host en lugar de la red puente predeterminada. No veo formas legales de bloquear la red puenteada. Alternativamente, puede usar una red personalizada definida por el usuario con aislamiento.

el codificador
fuente
0
  1. Inicie sesión en su consola docker:

    sudo docker exec -i -t nombre_imagen_docker / bin / bash

  2. Y luego dentro de su consola docker:

    sudo apt-get update
    sudo apt-get install ufw
    sudo ufw allow 22
    
  3. Agregue sus reglas de ufw y habilite el ufw

    sudo ufw enable

    • Su imagen de Docker debe comenzar con --cap-add = NET_ADMIN

Para habilitar la opción Docker "NET_ADMIN":

1.Detener el contenedor:

docker detiene su contenedor; 2. Obtener id del contenedor:

docker inspeccione su contenedor; 3.Modify hostconfig.json (ruta de acceso predeterminada: / var / lib / docker, puede cambiar la suya)

vim /var/lib/docker/containers/containerid/hostconfig.json

4. Busque "CapAdd" y modifique nulo a ["NET_ADMIN"];

...., "VolumesFrom": nulo, "CapAdd": ["NET_ADMIN"], "CapDrop": nulo, .... 5. Reinicie la ventana acoplable en la máquina host;

reinicio de la ventana acoplable de servicio; 6.Inicie su recipiente;

Docker inicia su contenedor;

Stefan
fuente
0

Solía docker-composeiniciar varios contenedores y también tenía el problema de que un puerto estaba expuesto al mundo ignorando las reglas ufw.

La solución para hacer que el puerto solo esté disponible para mis contenedores docker fue este cambio en mi docker-compose.ymlarchivo:

ports:
- "1234:1234"

a esto:

ports:
- "1234"

Ahora los otros contenedores acoplables todavía pueden usar el puerto, pero no puedo acceder a él desde afuera.

TmTron
fuente