使用 EasyTier 解决 Docker 绕过 UFW 的问题

前言

在日常折腾中,我们经常需要让多台公网服务器之间进行通信。例如,服务器 A 可能需要连接服务器 B 上 Docker 容器中的数据库服务,或者作为反向代理服务器转发 B 上某个容器的请求。然而,Docker 默认会修改 iptables 规则,如果将容器映射到公网,这导致 UFW (Uncomplicated Firewall) 难以有效阻止来自其他服务器的连接,从而产生安全隐患。

对于许多mjj来说,手动编辑 iptables 规则以精确控制网络访问并非易事。本文将介绍如何利用 EasyTier 这个强大的工具来优雅地解决这个问题,实现 Docker 容器服务仅通过内网访问,避免不必要的公网暴露。

问题分析与解决思路

Docker 自动修改 iptables 规则的行为虽然方便了用户,但也带来了安全风险。我们的目标是在允许 Docker 操作 iptables 的同时,增强网络隔离性。EasyTier 提供了一个绝佳的解决方案:创建一个虚拟内网,然后只将容器映射到内网IP,让服务器 A 和服务器 B 能够安全地进行点对点通信。

EasyTier 安装与配置

EasyTier 的官方仓库,如果该教程对您有用,请为repo点个Star并给我加个鸡腿
EasyTier文档

我们将使用 Docker Compose 来部署 EasyTier,这样可以简化安装过程并方便后续的维护。

在服务器 A 和 B 上安装 EasyTier

  1. 确保 Docker 和 Docker Compose 已安装

    这是前提条件,我假设大家已经具备这个基础环境。

  2. 创建 EasyTier 的 Docker Compose 配置

    在服务器 A 上创建 docker-compose.yml 文件:

    version: "3.8"
    services:
      watchtower: #用于自动更新easytier镜像,不同版本之间的easytier有兼容性问题,因此使用watchtower保持镜像为最新
        image: containrrr/watchtower
        container_name: watchtower
        command: --interval 3600 --cleanup --label-enable
        environment:
          - TZ=Asia/Shanghai
          - WATCHTOWER_NO_STARTUP_MESSAGE=true
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        restart: always
    
      easytier:
        image: easytier/easytier:latest
        container_name: easytier
        hostname: easytier
        restart: always
        privileged: true
        network_mode: host
        volumes:
          - /etc/easytier:/root
        environment:
          - TZ=Asia/Shanghai
        command: -i 10.144.144.1 --network-name mynet --network-secret mysecret
        labels:
          - com.centurylinklabs.watchtower.enable=true
    

    服务器 B 的配置类似,但需要添加 peers 参数:

    # ... (其他配置相同)
      easytier:
        # ... (其他配置相同)
        command: -i 10.144.144.2 --network-name mynet --network-secret mysecret --peers tcp://SERVER_A_PUBLIC_IP:11010
    

    注意替换 SERVER_A_PUBLIC_IP 为服务器 A 的实际公网 IP。另外,务必修改networkname和secret,以免被别人加入内网

  3. 启动 EasyTier

    在启动 EasyTier 之前,需要确保 UFW 允许 11010 端口的通信:

    sudo ufw allow 11010
    

    然后在两台服务器上compose文件所在的目录分别运行:

    docker compose up -d
    

将 Docker 容器映射到 EasyTier 网络

现在我们需要调整服务器 B 上的 Docker 容器配置,使其能通过 EasyTier 网络访问。

修改服务器 B 上的 docker-compose.yml

version: "3.8"
services:
  web_service:
    image: your_web_image:latest
    ports:
      - "127.0.0.1:3000:3000"  # 本地访问
      - "10.144.144.2:3000:3000"  # EasyTier 网络访问

这样配置可以确保服务只在本地和 EasyTier 网络中可用,而不会直接暴露到公网。

从服务器 A 访问服务器 B 的 Docker 容器

现在,服务器 A 可以通过 EasyTier 网络轻松访问服务器 B 上的 Docker 容器了。例如,如果服务器 A 上运行着 Nginx 作为反向代理,可以这样配置:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://10.144.144.2:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

总结与思考

通过使用 EasyTier,我们巧妙地解决了 Docker 绕过 UFW 防火墙的安全问题。这种方法不仅提高了系统的安全性,还简化了跨服务器的 Docker 容器访问配置。EasyTier 提供的去中心化、安全的虚拟内网为我们的服务器间通信开辟了一条安全通道。


本文首发于NodeSeek,禁止转载

点赞
  1. Eric0321说道:

    BD好贴多发点

  2. Redwind说道:

    @kyo #4 发布于2024/7/3 12:40:28
    我都是直接本地端口+nginx反代
    @minikoro #5 发布于2024/7/3 12:43:27
    大佬厉害 虽然我现在在用127.0.0.1+nginx反代

    这个教程的目的是解决多服务器之间的连接,例如用性能差的线路鸡反代高配建站鸡,或者小硬盘鸡连接大鸡的数据库,我个人目前用怪兽云反代绿云的SJC,如果一个鸡鸡线路又好配置又高,那确实本地反代就行了

  3. shisan说道:

    @Redwind #27 容器内部端口映射到127.0.0.1,再把127.0.0.1的端口映射到本机的公网地址上。用ufw管理公网地址的端口,很难理解吗

发表回复

电子邮件地址不会被公开。必填项已用 * 标注

×
订阅图标按钮