Docker Swarm und Netfilter

Docker Swarm und Netfilter

Ich habe auf meinem VPS einen Docker Swarm-Server bereitgestellt, um eine Asp.Net Core-Anwendung zu verwalten. Ich möchte diese App über einen Nginx-Webserver bereitstellen.

Nehmen wir an, meine Web-App ist eine Vanilla-App, die ich mit dem .Net Core CLI-Befehl erstellt habe:

dotnet new webapp mywebapp

Dockerfile (vereinfacht):

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

Meines docker-compose.ymlsieht so aus (vereinfacht):

version: '3'

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

Meine Nginx-Konfiguration sieht folgendermaßen aus:

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;
}

Wie Sie sehen, verwende ich Nginx als Reverse-Proxy-Server und leite den gesamten HTTP/HTTPS-Verkehr von den Ports 80 und 443 auf den lokalen Port 9000 um, den Docker Swarm dem Port 80 innerhalb des Containers zuordnet, auf dem ein Kestrel-Server ausgeführt wird.

Auf https://myservername.comläuft alles einwandfrei. Aber hier ist das Problem: Leute können auch auf auf meine Web-App zugreifen http://myservername.com:9000! Das möchte ich nicht.

Ich schätze, ich muss die Firewall so konfigurieren, dass ich nur Datenverkehr zu den Ports 80 und 443 zulasse (und dabei darauf achten, dass Port 22 für SSH usw. frei bleibt). Ich habe einige Tutorials gelesen, um zu erfahren, wie das geht, aber Docker Swarm kümmert sich auch um die Firewall!

Wenn ich starte 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            

Wie soll ich die Firewall so konfigurieren, dass sie nicht mit Docker Swarm interagiert? Ich habe einige Teile der Antworten gefunden:

Ich finde es jedoch ziemlich kompliziert und bin erstaunt, dass es in den Docker-Blogs keine offizielle Antwort auf dieses Problem gibt.

Versionen:

  • VPS: Debian 10.2
  • Docker-Engine: 19.03.5
  • Nginx: 1.16.1
  • Iptables: 1.8.2

Vielen Dank für Ihre Hilfe.

Antwort1

Sie könnten versuchen, localhost anstelle der Standardadresse 0.0.0.0 zu binden:

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

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

verwandte Informationen