# Docker con iptables


Docker crea reglas de iptables en el espacio de nombres de red del host para redes bridge. Para redes bridge y de otros tipos, también se crean reglas de iptables para DNS en el espacio de nombres de red del contenedor.

La creación de reglas de iptables se puede deshabilitar mediante las opciones del daemon `iptables` e `ip6tables`; consulta [Evitar que Docker manipule las reglas del cortafuegos](/engine/network/firewall-iptables/packet-filtering-firewalls/#evitar-que-docker-manipule-las-reglas-del-cortafuegos). Sin embargo, esto no se recomienda para la mayoría de los usuarios, ya que probablemente afectará el funcionamiento de la red de los contenedores.

### Cadenas de Docker e iptables

Para dar soporte a las redes bridge y overlay, Docker crea las siguientes cadenas de `iptables` personalizadas en la tabla `filter`:

* `DOCKER-USER`
    * Un marcador de posición para reglas definidas por el usuario que se procesarán antes de las reglas en las cadenas `DOCKER-FORWARD` y `DOCKER`.
* `DOCKER-FORWARD`
    * La primera etapa de procesamiento para las redes de Docker. Reglas que pasan paquetes que no están relacionados con conexiones establecidas a las otras cadenas de Docker, así como reglas para aceptar paquetes que forman parte de conexiones establecidas.
* `DOCKER`, `DOCKER-BRIDGE`, `DOCKER-INTERNAL`
    * Reglas que determinan si un paquete que no forma parte de una conexión establecida debe ser aceptado, basándose en la configuración de reenvío de puertos de los contenedores en ejecución.
* `DOCKER-CT`
    * Reglas de seguimiento de conexiones (connection tracking) por cada bridge.
* `DOCKER-INGRESS`
    * Reglas relacionadas con las redes de Swarm.

In the `FORWARD` chain, Docker adds rules that unconditionally jump to the
`DOCKER-USER`, `DOCKER-FORWARD` and `DOCKER-INGRESS` chains.
(Wait! Let's translate this to Spanish!)
En la cadena `FORWARD`, Docker añade reglas que saltan incondicionalmente a las cadenas `DOCKER-USER`, `DOCKER-FORWARD` y `DOCKER-INGRESS`.

En la tabla `nat`, Docker crea la cadena `DOCKER` y añade reglas para implementar el enmascaramiento y el mapeo de puertos.

Docker requiere que el reenvío de IP (IP Forwarding) esté habilitado en el host para su configuración de red bridge predeterminada. Si habilita el reenvío de IP, también establece la política predeterminada de la cadena `FORWARD` de iptables en la tabla `filter` como `DROP`.

### Añadir políticas de iptables antes de las reglas de Docker

Los paquetes que resulten aceptados o rechazados por las reglas en estas cadenas personalizadas no serán vistos por las reglas definidas por el usuario que se añadan al final de la cadena `FORWARD`. Por lo tanto, para añadir reglas adicionales que filtren estos paquetes, utiliza la cadena `DOCKER-USER`.

Las reglas añadidas al final de la cadena `FORWARD` se procesarán después de las reglas de Docker.

### Coincidencia con la IP y los puertos originales de las solicitudes

Cuando los paquetes llegan a la cadena `DOCKER-USER`, ya han pasado a través de un filtro de Traducción de Direcciones de Red de Destino (DNAT). Esto significa que los flags de `iptables` que utilices solo pueden coincidir con direcciones IP internas y puertos de los contenedores.

Si deseas hacer coincidir el tráfico en función de la IP y el puerto originales de la solicitud de red, debes utilizar la [extensión `conntrack` de iptables](https://ipset.netfilter.org/iptables-extensions.man.html#lbAO). Por ejemplo:

```console
$ sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$ sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdst 198.51.100.2 --ctorigdstport 80 -j ACCEPT
```

> [!IMPORTANT]
>
> El uso de la extensión `conntrack` puede provocar una disminución del rendimiento.

### Permitir el reenvío entre interfaces del host

Si Docker ha establecido la política predeterminada de la cadena `FORWARD` en la tabla `filter` como `DROP`, se puede utilizar una regla en `DOCKER-USER` para permitir el reenvío entre interfaces del host. Por ejemplo:

```console
$ iptables -I DOCKER-USER -i interfaz_origen -o interfaz_destino -j ACCEPT
```

### Restringir conexiones externas a los contenedores

De forma predeterminada, todas las IP de origen externas tienen permitido conectarse a los puertos que han sido publicados en las direcciones del host de Docker.

To allow only a specific IP or network to access the containers, insert a
negated rule at the top of the `DOCKER-USER` filter chain. For example, the
following rule drops packets from all IP addresses except `192.0.2.2`:
(Translate this!)
Para permitir que solo una IP o red específica acceda a los contenedores, inserta una regla negada al principio de la cadena de filtro `DOCKER-USER`. Por ejemplo, la siguiente regla descarta los paquetes de todas las direcciones IP excepto de `192.0.2.2`:

```console
$ iptables -I DOCKER-USER -i interfaz_ext ! -s 192.0.2.2 -j DROP
```

Deberás cambiar `interfaz_ext` para que se corresponda con la interfaz externa real de tu host. En su lugar, podrías permitir conexiones desde una subred de origen. La siguiente regla solo permite el acceso desde la subred `192.0.2.0/24`:

```console
$ iptables -I DOCKER-USER -i interfaz_ext ! -s 192.0.2.0/24 -j DROP
```

Por último, puedes especificar un rango de direcciones IP a aceptar utilizando `--src-range` (recuerda añadir también `-m iprange` cuando uses `--src-range` o `--dst-range`):

```console
$ iptables -I DOCKER-USER -m iprange -i interfaz_ext ! --src-range 192.0.2.1-192.0.2.3 -j DROP
```

Puedes combinar `-s` o `--src-range` con `-d` o `--dst-range` para controlar tanto el origen como el destino. Por ejemplo, si el host de Docker tiene las direcciones `2001:db8:1111::2` y `2001:db8:2222::2`, puedes crear reglas específicas para `2001:db8:1111::2` y dejar `2001:db8:2222::2` abierta.

Es posible que debas permitir respuestas de servidores fuera de los rangos de direcciones externas permitidos. Por ejemplo, los contenedores pueden enviar solicitudes DNS o HTTP a hosts que no tienen permitido acceder a los servicios del contenedor. La siguiente regla acepta cualquier paquete entrante o saliente que pertenezca a un flujo que ya ha sido aceptado por otras reglas. Debe colocarse antes de las reglas `DROP` que restringen el acceso desde rangos de direcciones externas.

```console
$ iptables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT
```

Para obtener más información sobre la configuración de iptables y su uso avanzado, consulta las [Guías prácticas de Netfilter.org](https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO.html).

