Docker Swarm e Netfilter

Docker Swarm e Netfilter

Implantei um servidor Docker Swarm em meu VPS para lidar com um aplicativo Asp.Net Core. Quero servir este aplicativo por meio de um servidor web Nginx.

Vamos supor que meu aplicativo da web seja um aplicativo vanilla que criei por meio do comando .Net Core CLI:

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"]

Minha docker-compose.ymlaparência é assim (simplificada):

version: '3'

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

Minha configuração do nginx é assim:

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 você pode ver, eu uso Nginx como servidor proxy reverso, redirecionando todo o tráfego HTTP/HTTPS das portas 80 e 443 para a porta 9000 local, que o Docker Swarm está mapeando para a porta 80 dentro do contêiner, na qual um servidor Kestrel está sendo executado .

Em https://myservername.com, tudo está funcionando bem. Mas o problema é o seguinte: as pessoas também podem acessar meu aplicativo da web no http://myservername.com:9000! Isso é algo que eu não quero.

Acho que tenho que configurar o firewall para permitir apenas o tráfego para as portas 80 e 443 (tomando o cuidado de deixar a porta 22 para SSH, etc.). Eu li alguns tutoriais para saber como fazer isso, porém, o Docker Swarm também está cuidando do firewall!

Quando eu lançar 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            

Como devo configurar o firewall para que ele não interaja com o Docker Swarm? Encontrei algumas partes das respostas:

  • Este(desculpe, está em francês)
  • que está referenciandoEste

No entanto, acho isso bastante complicado e estou surpreso que não haja uma resposta oficial para esse problema nos blogs do Docker.

Versões:

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

Obrigado pela ajuda.

Responder1

Você poderia tentar vincular localhost em vez do endereço padrão 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

informação relacionada