正确的 Docker 容器网络隔离

问题描述 投票:0回答:1

简介 我对 Docker 世界还很陌生,除了舒适之外,容器化的巨大优势是服务隔离。然而,令我完全惊讶的是,这既不是默认设置,也似乎不方便实现。

我的场景实际上是一个很常见的场景,反向代理(例如traefik)和一些容器化服务,其中一些需要互联网访问。 虽然设置很容易,但通常的指南建议在 A B C P(反向代理)之间使用共享桥接网络。

动机 然而,从安全角度来看,这意味着所有服务都能够在网络上互相看到对方。如果使用具有前向身份验证的中间件(例如 authelia)进行身份验证,则一个受感染的服务很容易冒充另一服务上的另一个用户,例如通过

container-a$ curl -H "Remote-User: admin" http://container-b:8080

借助诸如 arp 缓存欺骗之类的技术,一个受感染的容器甚至有可能捕获用于另一容器的所有网络流量。

目标 我的目标是以这样一种方式设置我的容器,即使一个容器受到损害,即攻击者在该容器中具有 shell 访问权限,所有其他服务仍然是安全的。因此

  • 服务不应该能够相互通信
  • 服务不应该能够访问本地以太网
  • docker主机应该能够访问本地以太网(我不想将整个主机与我的以太网隔离)
  • 但服务应该能够访问互联网

反向代理,以及每个服务都有自己独立的设置

docker-compose.yml

当前解决方案 我首先禁用容器间通信 (

enable_icc: false
),但这并不能阻止容器访问其他容器已发布的端口。 经过一番实验,我终于通过为每个服务创建一个单独的自定义桥接网络(即 P<->A、P<->B 和 P<->C)来实现我的目标,例如

docker network create proxy_A -o com.docker.network.bridge.name=br-a

并将其连接到反向代理和服务。所以反向代理的 docker-compose 看起来像这样

services:
  revproxy:
    networks:
      - proxy_A
      - proxy_B
      - proxy_C
[...]
networks:
  proxy_A:
    driver: bridge
    external: true
  proxy_B:
    driver: bridge
    external: true
  proxy_C:
    driver: bridge
    external: true

只要容器不发布任何端口,它们不需要被反向代理访问,这就将它们全部分开并允许互联网访问。 如果该服务不需要互联网访问,则只需将网络标记为

--internal
即可完成。 但是,如果确实如此,非内部网络也允许访问我的本地以太网。为了阻止这个问题,我为所有容器添加了以下自定义 iptables 规则,例如

# deny access to ethernet
iptables -I DOCKER-USER -i br-a -d 192.168.0.0/16 -j DROP # or probably better REJECT
# except for DNS
iptables -I DOCKER-USER -i br-a -d 192.168.1.1 -p udp --dport 53 -j ACCEPT
iptables -I DOCKER-USER -i br-a -d 192.168.1.1 -p tcp --dport 53 -j ACCEPT

虽然这有效,但我不是很高兴,因为它需要为每个服务进行大量的手动配置工作:为新服务创建网络,将反向代理连接到它并设置 iptables 规则。 我能想出的唯一能稍微改善这种情况的解决方案是创建另一个

docker-compose.yml
,它使用
include
来设置代理、所有服务和相应的网络。

version: '3'

include:
  - A/docker-compose.yml
  - B/docker-compose.yml
  - C/docker-compose.yml

networks:
  proxy_A:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-a
  [...]

但特别是关于 iptables 规则,我期望有某种方法将它们添加到 docker-compose 文件中,但我没有找到任何方法。

问题

  • 是否有合适的位置来放置特定于容器的 iptables 规则,以便在启动相应容器时始终加载它们?
  • 是否有更好的方法来实现我的目标,最好全部在服务的
    docker-compose.yml
    内,而不需要任何进一步的修改,例如编辑反向代理docker-compose文件,
    docker network connect
    iptables
    ?正如使用 traefik 的 docker 提供程序通常可以(无需隔离)一样,我想启动新的服务容器并能够通过反向代理访问它。
docker docker-compose reverse-proxy
1个回答
0
投票

我只能回答1个问题:

有没有更好的方法来实现我的目标[...]。

是的,有。然而,这不在 Docker 中。您应该使用 Kubernetes 或其他容器管理器。这些本质上是更安全的。 Docker 以 root 身份运行其容器。 (除非您使用 Podman)。这意味着,如果容器逃逸成功,它们将成为整个服务器的根。

Docker 非常手动,像 Kubernetes(或使用 helmcharts)这样的管理器会给你很大帮助! (他们也更注重安全)。

希望这对您有一点帮助!

© www.soinside.com 2019 - 2024. All rights reserved.