Esta es la primera vez que pregunto algo en stackoverflow. Durante años he estado al acecho, pero ahora decidí finalmente registrarme. Por lo tanto, me disculpo si mi pregunta/información no está bien formateada.
Situación actual:
Poco a poco me estoy familiarizando más y más con Podman y estoy en el proceso de mover algunos de mis contenedores de docker (rootful) a podman (rootless). Estoy usando Podman 4.3.1 en Debian 11. Logré que algunos contenedores funcionaran y pude conectarme externamente a ellos. Sin embargo, el contenedor muestra la IP de cliente/origen ‘127.0.0.1’ en lugar de la IPv4 de mi cliente real. Me preguntaba si algo como lo siguiente es posible.
Situación ideal:
Asignación de un IPv4 específico al contenedor (rootless). Uso de nftables/iptables para reenviar paquetes desde la red del host a los contenedores ipv4 (por ejemplo, 192.168.1.12). Ser capaz de ver el IPv4 del cliente real en el contenedor para poder seguir usando fail2ban, etc.
Como puede notar, todavía estoy en el proceso de aprender cómo funciona la creación de contenedores y específicamente para la creación de redes. No quiero usar la red de hosts para mi contenedor por razones de seguridad. Si algo no te queda claro, dímelo y trataré de explicarme mejor.
Gracias por tomarte un tiempo para leer esto 🙂
Cuando está ejecutando Podman como un usuario no raíz, el virtual toque el dispositivo que representa el contenedor eth0
La interfaz no se puede conectar directamente a un dispositivo puente. Esto significa que no es posible usar reglas de netfilter para dirigir el tráfico al contenedor; en cambio, Podman se basa en un proceso de proxy.
Hay algunas notas sobre esta configuración. aquí.
De forma predeterminada, Podman utiliza el rootlessport
proxy, que reemplaza la ip de origen de la conexión con una ip interna del espacio de nombres del contenedor. Sin embargo, puede solicitar explícitamente a Podman que utilice slirp4netns
como el controlador de puerto, que voluntad preservar la dirección de origen a expensas de algún rendimiento.
Por ejemplo, si inicio un contenedor como este:
podman run --name darkhttpd --rm -p 8080:8080 docker.io/alpinelinux/darkhttpd
Y luego conéctese a esto desde algún lugar:
curl 192.168.1.200:8080
Veré en el registro de acceso:
10.0.2.100 - - [12/Feb/2023:15:30:54 +0000] "GET / HTTP/1.1" 200 354 "" "curl/7.85.0"
Dónde 10.0.2.100
es de hecho la dirección del contenedor:
$ podman exec darkhttpd ip a show tap0
2: tap0: <BROADCAST,UP,LOWER_UP> mtu 65520 qdisc fq_codel state UNKNOWN qlen 1000
link/ether 26:77:5b:e8:f4:6e brd ff:ff:ff:ff:ff:ff
inet 10.0.2.100/24 brd 10.0.2.255 scope global tap0
valid_lft forever preferred_lft forever
inet6 fd00::2477:5bff:fee8:f46e/64 scope global dynamic flags 100
valid_lft 86391sec preferred_lft 14391sec
inet6 fe80::2477:5bff:fee8:f46e/64 scope link
valid_lft forever preferred_lft forever
Pero si pido explícitamente slirp4nets
como el controlador de puerto:
podman run --name darkhttpd --rm -p 8080:8080 --network slirp4nets:port_handler=slirp4netns docker.io/alpinelinux/darkhttpd
Luego, en el registro de acceso, veré la IP de origen real de la solicitud:
192.168.1.97 - - [12/Feb/2023:15:32:17 +0000] "GET / HTTP/1.1" 200 354 "" "curl/7.74.0"
En la mayoría de los casos, no desea confiar en la dirección IP de origen para fines de autenticación/autorización, por lo que el comportamiento predeterminado tiene sentido.
Si necesita la IP remota para fines de registro, la opción que se presenta aquí funcionará, o también puede considerar ejecutar un proxy front-end en el espacio de nombres global que coloca la IP del cliente en el X-Forwarded-For
encabezado y utilícelo para sus registros.
Erik Sjolund
Aquí hay una solución alternativa que no se menciona en la buena respuesta de @larsks.
Activación de enchufe
Cuando usas activación de socket de contenedoresla IP de origen está disponible para el contenedor.
El soporte para la activación de socket aún no está muy extendido, pero por ejemplo, la imagen del contenedor docker.io/library/mariadb admite activación de socket. La imagen del contenedor docker.io/library/nginx también admite la activación de socket (aunque de una manera no estándar, ya que nginx usa su propia variable de entorno en lugar de usar la variable de entorno systemd estándar LISTEN_FDS
)
Escribí una demostración mínima de cómo usar run docker.io/library/nginx con Podman y activación del zócalo:
https://github.com/eriksjolund/podman-nginx-socket-activación