Docker Swarm y Netfilter

Docker Swarm y Netfilter

Implementé un servidor Docker Swarm en mi VPS para manejar una aplicación Asp.Net Core. Quiero servir esta aplicación a través de un servidor web Nginx.

Supongamos que mi aplicación web es una aplicación básica que creé mediante el comando CLI de .Net Core:

dotnet new webapp mywebapp

Dockerfile (simplificado):

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine as builder
WORKDIR /app
COPY . .
RUN dotnet publish -c Release -o publish
WORKDIR /app/publish
ENTRYPOINT ["dotnet", "MyWebApp.dll"]

Mi docker-compose.ymlaspecto es este (simplificado):

version: '3'

services:
  app:
    image: edouard/mywebapp:latest
    ports:
      - 9000:80

Mi configuración de nginx se ve así:

server {
    listen 443 ssl;
    server_name myservername.com;

    ssl_certificate     /path/to/ssl_certificate;
    ssl_certificate_key /path/to/ssl_certificate_key;

   location / {
        proxy_pass         http://localhost:9000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    } 

}
server {
    listen 80;
    server_name myservername.com;
    return 301 https://$host$request_uri;
}

Como puede ver, uso Nginx como servidor proxy inverso, redirigiendo todo el tráfico HTTP/HTTPS desde los puertos 80 y 443 al puerto local 9000, que Docker Swarm está asignando al puerto 80 dentro del contenedor, en el que se ejecuta un servidor Kestrel. .

En https://myservername.com, todo está funcionando bien. Pero aquí está la cuestión: ¡la gente también puede acceder a mi aplicación web en http://myservername.com:9000! Esto es algo que no quiero.

Supongo que tengo que configurar el firewall para que solo permita tráfico al puerto 80 y 443 (encargándome de dejar el puerto 22 para SSH, etc.). He leído algunos tutoriales para saber cómo hacer esto, sin embargo, ¡Docker Swarm también maneja el firewall!

Cuando lanzo sudo iptables -L -v:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
 3417  873K DOCKER-USER  all  --  any    any     anywhere             anywhere            
 3417  873K DOCKER-INGRESS  all  --  any    any     anywhere             anywhere            
   31  9043 DOCKER-ISOLATION-STAGE-1  all  --  any    any     anywhere             anywhere            
    0     0 ACCEPT     all  --  any    docker0  anywhere             anywhere             ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  any    docker0  anywhere             anywhere            
    0     0 ACCEPT     all  --  docker0 !docker0  anywhere             anywhere            
    0     0 ACCEPT     all  --  docker0 docker0  anywhere             anywhere            
   18  7620 ACCEPT     all  --  any    docker_gwbridge  anywhere             anywhere             ctstate RELATED,ESTABLISHED
    0     0 DOCKER     all  --  any    docker_gwbridge  anywhere             anywhere            
   13  1423 ACCEPT     all  --  docker_gwbridge !docker_gwbridge  anywhere             anywhere            
    0     0 DROP       all  --  docker_gwbridge docker_gwbridge  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  anywhere             anywhere            
   13  1423 DOCKER-ISOLATION-STAGE-2  all  --  docker_gwbridge !docker_gwbridge  anywhere             anywhere            
   31  9043 RETURN     all  --  any    any     anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  any    docker0  anywhere             anywhere            
    0     0 DROP       all  --  any    docker_gwbridge  anywhere             anywhere            
   13  1423 RETURN     all  --  any    any     anywhere             anywhere            

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 3417  873K RETURN     all  --  any    any     anywhere             anywhere            

Chain DOCKER-INGRESS (1 references)
 pkts bytes target     prot opt in     out     source               destination         
 1567  101K ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:9000
 1270  698K ACCEPT     tcp  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED tcp spt:9000
   31  9043 RETURN     all  --  any    any     anywhere             anywhere            

¿Cómo se supone que debo configurar el firewall para que no interactúe con Docker Swarm? He encontrado algunas partes de las respuestas:

  • Éste(lo siento, está en francés)
  • que hace referenciaÉste

Sin embargo, lo encuentro bastante complicado y me sorprende que no haya una respuesta oficial a este problema en los blogs de Docker.

Versiones:

  • VPS: Debian 10.2
  • Motor Docker: 19.03.5
  • Nginx: 1.16.1
  • Iptables: 1.8.2

Gracias por tu ayuda.

Respuesta1

Podrías intentar vincular localhost en lugar de la dirección predeterminada 0.0.0.0:

services:
  app:
    image: edouard/mywebapp:latest
    ports:
      - '127.0.0.1:9000:80'

https://docs.docker.com/compose/compose-file/#ports

información relacionada