Docker Swarm и Netfilter

Я развернул сервер Docker Swarm на своем VPS для работы с приложением Asp.Net Core. Я хочу обслуживать это приложение через веб-сервер Nginx.

Предположим, что мое веб-приложение - это ванильное приложение, которое я создал с помощью команды .Net Core CLI:

dotnet new webapp mywebapp

Dockerfile (упрощенный):

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

Мой docker-compose. yml выглядит следующим образом (упрощенно):

version: '3'

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

Мой конфиг nginx выглядит следующим образом:

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

Как вы можете видеть, я использую Nginx в качестве обратного прокси-сервера, перенаправляя весь HTTP/HTTPS трафик с 80 и 443 портов на локальный 9000 порт, который Docker Swarm отображает на 80 порт внутри контейнера, на котором запущен сервер Kestrel.

На https://myservername.com все работает нормально. Но вот в чем дело: люди также могут получить доступ к моему веб-приложению на http://myservername.com:9000! Это то, чего я не хочу.

Думаю, мне нужно настроить брандмауэр так, чтобы разрешить трафик только на 80 и 443 порт (позаботившись о том, чтобы разрешить 22 порт для SSH и т.д.). Я прочитал несколько руководств, чтобы узнать, как это сделать, однако, Docker Swarm также управляет брандмауэром!

Когда я запускаю 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            

Как я должен настроить брандмауэр, чтобы он не взаимодействовал с Docker Swarm? Я нашел некоторые части ответов:

  • Этот (извините, что на французском)
  • который ссылается наэтот

Однако я нахожу это довольно сложным, и меня удивляет, что в блогах Docker нет официального ответа на этот вопрос.

Версии:

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

Спасибо за помощь.

0
задан 16 January 2020 в 00:45
1 ответ

Вы можете попробовать привязать localhost вместо адреса по умолчанию 0.0.0.0:

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

https://docs.docker.com/compose/compose -file / # порты

0
ответ дан 26 January 2020 в 19:36

Теги

Похожие вопросы