boxmoe_header_banner_img

Hello! 欢迎来到我的博客!

文章导读

AimiliVPN 安装配置:解决机房 VPS 无法使用 AI / 流媒体服务,实现 Docker 版 3x-ui 分流


📅 最后更新:2026年9月12日  | 
🏷️ 标签:Debian, Docker, 3x-ui, AimiliVPN, iptables, DOCKER-USER, 分流

本文是系列教程的后篇,记录一套适用于 Debian 13.x 最小系统的 AimiliVPN + Docker 3x-ui 部署方案。

主要目标是让 Docker 中的 3x-ui 通过 AimiliVPN 提供的本地 HTTP 代理实现指定网站分流,同时使用独立的 Docker 防火墙规则控制节点端口。

📌 适用场景:
DD 重装后的 Debian VPS、Docker 3x-ui、AimiliVPN、指定域名分流,以及需要长期稳定运行的节点环境。
⚠️ 安全提醒:
本文不包含任何具体服务器的公网 IP、SSH 端口、域名、后台地址或其他可识别服务器的信息。
发布时请根据自己的环境替换相关参数。

前置步骤:安装基础环境

DD 重装后的 Debian 最小系统通常只包含最基本的软件包。正式部署之前,需要安装 Docker、Docker Compose、Git、curl、Python 3 以及防火墙持久化工具。

0.1 更新系统

apt update
apt full-upgrade -y

0.2 安装基础工具

apt install -y \
  ca-certificates \
  curl \
  git \
  python3 \
  iptables \
  iptables-persistent \
  netfilter-persistent

如果安装过程中出现是否保存当前 IPv4/IPv6 防火墙规则的提示,可以选择 Yes

📌 说明:
这里安装 iptables-persistentnetfilter-persistent,主要用于保存宿主机基础防火墙规则。
Docker 自己创建的 Docker 专用链则由后面的 systemd 服务重新应用。

0.3 安装 Docker Engine + Docker Compose

install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
  -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
  > /etc/apt/sources.list.d/docker.list
apt update
apt install -y \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin
systemctl enable --now docker

0.4 检查基础环境

docker --version
docker compose version
git --version
python3 --version
curl --version
iptables --version

检查 Docker 服务:

systemctl status docker --no-pager
✅ 看到 Active: active (running),说明 Docker 已经正常运行。

第 1 步:创建 Docker 网络

本教程统一创建一个名为 web 的 Docker Bridge 网络。

docker network create \
  --driver bridge \
  --subnet 172.20.0.0/16 \
  --gateway 172.20.0.1 \
  web

检查网络:

docker network inspect web
项目 配置
网络名称 web
Subnet 172.20.0.0/16
Gateway 172.20.0.1

容器 IP 规划:

容器 IP
mysql57 172.20.0.10
npm 172.20.0.20
wordpress 172.20.0.30
3x-ui 172.20.0.50

第 2 步:部署 AimiliVPN

AimiliVPN 项目目录统一放在:

/opt/aimilivpn
mkdir -p /opt
cd /opt
git clone https://github.com/xiaoxinkeji/aimili-vpngate.git aimilivpn
cd /opt/aimilivpn

2.1 修改 Dockerfile

sed -i 's/COPY proxy_server.py/COPY metrics.py proxy_server.py/' Dockerfile
grep "COPY metrics.py" Dockerfile

应该看到:

COPY metrics.py proxy_server.py

2.2 创建 AimiliVPN 数据目录

mkdir -p /opt/aimilivpn/vpngate_data
📌 数据持久化:
AimiliVPN 数据通过宿主机目录挂载到容器中。即使以后删除并重新创建容器,数据仍然保存在宿主机上。

2.3 创建 docker-compose.yml

cd /opt/aimilivpn
nano docker-compose.yml
services:
  aimilivpn:
    build:
      context: .
      args:
        IMAGE_VERSION: dev
        BUILD_DATE: unknown
        GIT_COMMIT: unknown

    image: ghcr.io/xiaoxinkeji/aimili-vpngate:latest

    container_name: aimilivpn

    restart: unless-stopped

    network_mode: host

    cap_add:
      - NET_ADMIN
      - NET_RAW

    devices:
      - /dev/net/tun:/dev/net/tun

    volumes:
      - /opt/aimilivpn/vpngate_data:/opt/aimilivpn/vpngate_data

    environment:
      - VPNGATE_DATA_DIR=/opt/aimilivpn/vpngate_data
      - LOCAL_PROXY_HOST=172.20.0.1
      - LOCAL_PROXY_PORT=7928
      - UI_HOST=172.20.0.1
      - UI_PORT=8787
      - METRICS_ENABLED=true
      - METRICS_PORT=9798
      - METRICS_REFRESH_INTERVAL=15

2.4 构建并启动 AimiliVPN

cd /opt/aimilivpn

docker compose build --no-cache aimilivpn
docker compose up -d aimilivpn
docker ps

确认 aimilivpn 容器状态为 Up


第 3 步:配置系统网络参数

nano /etc/sysctl.d/99-aimilivpn.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2
sysctl --system

检查:

sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.rp_filter

正常结果应包含:

net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 2

第 4 步:配置 Docker daemon

⚠️ 注意:
不要直接使用 cat > /etc/docker/daemon.json 覆盖整个文件。
如果系统中已经存在其他 Docker 配置,这样操作会把原有配置覆盖掉。

使用 Python 对现有 JSON 配置进行合并,只修改需要的项目。

mkdir -p /etc/docker
python3 - <<'PY'
import json
from pathlib import Path

p = Path("/etc/docker/daemon.json")

if p.exists():
    try:
        data = json.loads(p.read_text())
        if not isinstance(data, dict):
            data = {}
    except Exception:
        data = {}
else:
    data = {}

data["ip-forward-no-drop"] = True

p.write_text(
    json.dumps(data, indent=2, ensure_ascii=False) + "\n"
)
PY

检查:

cat /etc/docker/daemon.json

确认包含:

"ip-forward-no-drop": true

为什么使用 ip-forward-no-drop?

Docker 在启用 IPv4 forwarding 时可能调整 Linux 的 FORWARD 默认策略。

设置:

"ip-forward-no-drop": true

表示让 Docker 不要自动修改 FORWARD 默认策略

本教程并不会因此将 FORWARD 设置成 ACCEPT。相反,后面的自定义防火墙脚本会明确设置:

iptables -P FORWARD DROP
Docker

不自动管理 FORWARD 默认策略

自定义防火墙脚本

FORWARD = DROP

第 5 步:确保 AimiliVPN 随 Docker 自动启动

AimiliVPN 使用 Docker Compose 管理,并通过 restart: unless-stopped 让容器在 Docker 启动后自动恢复。

首先确保 Docker 设置为开机启动:

systemctl enable docker

确认 AimiliVPN 使用自动重启策略:

cd /opt/aimilivpn

docker compose up -d aimilivpn
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' aimilivpn

正常应该看到:

unless-stopped
📌 启动关系:
VPS 重启后,systemd 先启动 Docker;Docker 启动完成后,会根据 restart: unless-stopped 自动恢复 AimiliVPN 容器。
后面的 docker-firewall.service 再负责重新应用 Docker 专用防火墙规则。

第 6 步:配置 Docker → AimiliVPN 防火墙

AimiliVPN 使用:

network_mode: host

因此 HTTP 代理监听在宿主机:

172.20.0.1:7928

3x-ui 位于:

172.20.0.50
3x-ui
172.20.0.50


172.20.0.1:7928


AimiliVPN


VPN 出口

6.1 创建 Docker 防火墙脚本

nano /usr/local/sbin/docker-firewall.sh
#!/bin/bash
set -e

IPTABLES="/usr/sbin/iptables"

# ============================================================
# 1. 明确设置 FORWARD 默认策略
# ============================================================

$IPTABLES -P FORWARD DROP


# ============================================================
# 2. 允许 Docker 网络访问 AimiliVPN HTTP 代理
# ============================================================

$IPTABLES -C INPUT \
  -s 172.20.0.0/16 \
  -d 172.20.0.1 \
  -p tcp \
  --dport 7928 \
  -j ACCEPT 2>/dev/null || \
$IPTABLES -I INPUT 1 \
  -s 172.20.0.0/16 \
  -d 172.20.0.1 \
  -p tcp \
  --dport 7928 \
  -j ACCEPT


# ============================================================
# 3. 允许 Docker 网络访问 AimiliVPN 管理页面
# ============================================================

$IPTABLES -C INPUT \
  -s 172.20.0.0/16 \
  -d 172.20.0.1 \
  -p tcp \
  --dport 8787 \
  -j ACCEPT 2>/dev/null || \
$IPTABLES -I INPUT 1 \
  -s 172.20.0.0/16 \
  -d 172.20.0.1 \
  -p tcp \
  --dport 8787 \
  -j ACCEPT


# ============================================================
# 4. 创建独立的 3x-ui 防火墙链
# ============================================================

$IPTABLES -N AIMILI-3XUI 2>/dev/null || true

$IPTABLES -F AIMILI-3XUI


# ============================================================
# 5. 已建立连接直接放行
# ============================================================

$IPTABLES -A AIMILI-3XUI \
  -m conntrack \
  --ctstate ESTABLISHED,RELATED \
  -j ACCEPT


# ============================================================
# 6. 当前开放节点
# ============================================================

$IPTABLES -A AIMILI-3XUI \
  -d 172.20.0.50 \
  -p tcp \
  --dport 12701 \
  -j ACCEPT

$IPTABLES -A AIMILI-3XUI \
  -d 172.20.0.50 \
  -p udp \
  --dport 12703 \
  -j ACCEPT


# ============================================================
# 7. 其他预留端口拒绝
# ============================================================

for PORT in 12700 12702 12704 12705 12706 12707 12708 12709 12710
do
    $IPTABLES -A AIMILI-3XUI \
      -d 172.20.0.50 \
      -p tcp \
      --dport "$PORT" \
      -j DROP
done


# ============================================================
# 8. 删除旧的跳转
# ============================================================

while $IPTABLES -C DOCKER-USER \
  -j AIMILI-3XUI 2>/dev/null
do
    $IPTABLES -D DOCKER-USER \
      -j AIMILI-3XUI
done


# ============================================================
# 9. 将独立链加入 DOCKER-USER
# ============================================================

$IPTABLES -I DOCKER-USER 1 \
  -j AIMILI-3XUI

赋予执行权限:

chmod +x /usr/local/sbin/docker-firewall.sh

第 7 步:创建 Docker 防火墙开机服务

Docker 启动时会创建和重建 Docker 自己的防火墙链,因此 Docker 专用规则应该在 Docker 启动完成后重新应用。

系统启动

Docker 启动

Docker 创建 DOCKER-USER 等链

docker-firewall.service

重新应用自定义规则

创建 systemd 服务:

nano /etc/systemd/system/docker-firewall.service

写入:

[Unit]
Description=Apply custom Docker firewall rules after Docker starts
Requires=docker.service
After=docker.service
PartOf=docker.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/docker-firewall.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
📌 为什么使用 multi-user.target?
这是更标准的 systemd 启用方式。WantedBy=multi-user.target 负责开机启动,
After=docker.service 负责确保 Docker 在该服务之前启动。

重新加载 systemd:

systemctl daemon-reload

设置开机启动:

systemctl enable docker-firewall.service

立即执行:

systemctl start docker-firewall.service

检查:

systemctl status docker-firewall.service --no-pager

正常情况下:

Active: active (exited)

第 8 步:保存系统防火墙规则

本教程将防火墙规则分为两部分管理:

规则类型 负责组件
宿主机基础防火墙规则 netfilter-persistent
Docker 动态防火墙链 docker-firewall.service
📌 重要说明:
Docker 启动后会创建 DOCKER-USER 等 Docker 专用链,因此 Docker 专用规则不依赖
netfilter-persistent 在 Docker 启动之前恢复,而是由后面的
docker-firewall.service 在 Docker 启动完成后重新应用。

检查 INPUT:

iptables -L INPUT -n -v --line-numbers

检查 FORWARD:

iptables -L FORWARD -n -v --line-numbers

重点确认:

Chain FORWARD (policy DROP)

保存宿主机基础防火墙规则:

netfilter-persistent save
⚠️ 注意:
netfilter-persistent 主要负责宿主机静态防火墙规则。
DOCKER-USERAIMILI-3XUI 等 Docker 专用规则由
docker-firewall.service 在 Docker 启动后重新应用。

检查持久化规则文件:

iptables-restore --test < /etc/iptables/rules.v4

echo $?

正常返回:

0

第 9 步:配置 3x-ui 分流

3x-ui 使用固定 Docker IP:

172.20.0.50

Docker 端口映射可以保留:

12700-12710/TCP
12703/UDP
📌 保留未使用端口的目的:
以后增加 3x-ui 节点时,不需要重新创建容器。只需要调整防火墙规则即可。

9.1 当前开放节点

协议 端口 状态
TCP 12701 允许公网访问
UDP 12703 允许公网访问

9.2 预留节点端口

以下端口继续保留 Docker 映射,但由防火墙拒绝公网访问:

12700
12702
12704
12705
12706
12707
12708
12709
12710

以后如果新增节点,例如使用 12705/TCP,只需要修改 AIMILI-3XUI 中对应端口的防火墙规则,无需重新创建 Docker 容器。

9.3 AimiliVPN HTTP 代理

3x-ui 使用:

http://172.20.0.1:7928
3x-ui

├── 指定分流域名
│ │
│ ▼
│ AIMILI-VPN
│ │
│ ▼
│ 172.20.0.1:7928
│ │
│ ▼
│ AimiliVPN
│ │
│ ▼
│ VPN 出口

└── 其他网站


direct

9.4 推荐的 OpenAI / ChatGPT 分流域名

openai.com
chatgpt.com
oaistatic.com
oaiusercontent.com
ai.com

上述域名设置为走 AIMILI-VPN

其他流量继续使用 direct

📌 说明:
如果已经在 3x-ui 中完成 routing 配置,则不需要重复修改。保持现有分流规则即可。

第 10 步:最终验证、持久化与重启测试

10.1 验证 AimiliVPN HTTP 代理

curl -4 \
  --proxy http://172.20.0.1:7928 \
  https://api.ipify.org

如果能够返回 VPN 出口 IP,说明 AimiliVPN HTTP 代理正常。

10.2 验证 3x-ui → AimiliVPN

docker exec 3xui sh -c \
'curl -4 --connect-timeout 10 \
--proxy http://172.20.0.1:7928 \
https://api.ipify.org'

如果能够正常返回 VPN 出口 IP,说明以下链路已经打通:

3x-ui

Docker Gateway

172.20.0.1:7928

AimiliVPN

VPN 出口

10.3 验证 NPM → AimiliVPN 管理页面

如果使用 NPM 反向代理 AimiliVPN 管理页面,可以从 NPM 容器内部测试。

将下面的 你的面板路径 替换成自己设置的路径:

docker exec npm sh -c \
'curl -4 --connect-timeout 10 \
http://172.20.0.1:8787/你的面板路径/ \
-o /dev/null \
-w "%{http_code}\n"'

正常情况下返回:

200
如果没有设置自定义面板路径,也可以直接测试:
docker exec npm sh -c \
'curl -4 --connect-timeout 10 \
http://172.20.0.1:8787/ \
-o /dev/null \
-w "%{http_code}\n"'

10.4 验证 Docker 防火墙

iptables -L DOCKER-USER -n -v --line-numbers

应该能够看到:

AIMILI-3XUI

检查独立链:

iptables -L AIMILI-3XUI -n -v --line-numbers

应该包含:

  • 12701/TCP ACCEPT
  • 12703/UDP ACCEPT
  • 其他预留 TCP 端口 DROP

10.5 验证 FORWARD 策略

iptables -L FORWARD -n -v

确认:

Chain FORWARD (policy DROP)

10.6 验证防火墙服务

systemctl status docker-firewall.service --no-pager

正常应该为:

Active: active (exited)

10.7 再次保存宿主机防火墙规则

netfilter-persistent save
iptables-restore --test < /etc/iptables/rules.v4

echo $?

返回 0 即表示规则文件语法正常。

📌 注意:
Docker 专用规则不依赖这里的恢复过程。
VPS 重启后,Docker 启动并创建 Docker 专用链,再由
docker-firewall.service 自动重新应用 AIMILI-3XUI 等规则。

10.8 重启 VPS

⚠️ 注意:
只有前面的测试全部正常后,再执行重启。
reboot

10.9 重启后检查 Docker

docker ps

确认需要的容器均正常运行。

10.10 重启后检查防火墙

iptables -L FORWARD -n -v

确认:

policy DROP

继续检查:

iptables -L DOCKER-USER -n -v --line-numbers

确认:

AIMILI-3XUI

10.11 重启后重新测试 3x-ui → AimiliVPN

docker exec 3xui sh -c \
'curl -4 --connect-timeout 10 \
--proxy http://172.20.0.1:7928 \
https://api.ipify.org'
✅ 如果重启后仍然能够正常返回 VPN 出口 IP,说明 AimiliVPN、Docker、iptables、防火墙持久化以及开机启动顺序全部正常。

最终架构

Internet

┌─────────┴─────────┐
│ │
TCP 节点 UDP 节点
│ │
└─────────┬─────────┘

3x-ui
172.20.0.50

┌───────────┴───────────┐
│ │
指定分流域名 其他流量
│ │
▼ ▼
AIMILI-VPN direct


172.20.0.1:7928


AimiliVPN


VPN 节点


Internet

最终配置总结

项目 配置
系统 Debian 13.x
Docker 网络 web
Docker 子网 172.20.0.0/16
Docker Gateway 172.20.0.1
3x-ui 172.20.0.50
AimiliVPN network_mode: host
HTTP 代理 172.20.0.1:7928
管理服务 172.20.0.1:8787
AimiliVPN 数据 /opt/aimilivpn/vpngate_data
Docker daemon ip-forward-no-drop: true
FORWARD 默认策略 DROP
Docker 自定义防火墙 AIMILI-3XUI
Docker 防火墙入口 DOCKER-USER
防火墙持久化 netfilter-persistent
Docker 防火墙启动 systemd 开机自动执行
WARP 不使用
OpenAI / ChatGPT 分流 AIMILI-VPN
其他流量 direct

常见问题

为什么 Docker 容器访问不了 172.20.0.1:7928?

因为 AimiliVPN 使用 host 网络模式,172.20.0.1:7928 实际属于宿主机监听端口。如果宿主机 INPUT 默认策略为 DROP,Docker 容器访问宿主机端口也可能被 INPUT 防火墙拦截。

因此本教程允许:

172.20.0.0/16 → 172.20.0.1:7928

为什么不直接把 FORWARD 改成 ACCEPT?

因为这样会降低主机默认的网络转发限制。本教程采用:

FORWARD = DROP

再通过 Docker 自身规则以及自定义规则放行合法流量。

为什么不关闭 Docker 的 iptables 管理?

不建议简单使用:

"iptables": false

Docker 的容器网络、端口映射和 NAT 依赖其防火墙规则。关闭 Docker 的 iptables 管理可能导致容器网络异常。

本教程采取:

Docker 正常管理自己的防火墙
+
通过 DOCKER-USER 管理自定义访问控制
+
FORWARD 默认策略明确设置为 DROP

以后增加新的 3x-ui 节点怎么办?

例如新增:

12705/TCP

无需重新创建 3x-ui 容器。只需要调整 AIMILI-3XUI 中对应端口的防火墙规则,将该端口从 DROP 改为 ACCEPT。


结语

这套方案的核心并不是简单地把 AimiliVPN 和 3x-ui 安装在一起,而是分别处理容器网络、宿主机网络、Docker 防火墙、AimiliVPN HTTP 代理以及 3x-ui 分流

最终实现:

  • Docker 使用独立 Bridge 网络;
  • AimiliVPN 使用 host 网络运行;
  • 3x-ui 通过 Docker Gateway 访问 AimiliVPN;
  • 指定网站通过 AimiliVPN 出口;
  • 其他流量保持 direct;
  • FORWARD 默认策略保持 DROP;
  • Docker 公网端口通过独立防火墙链控制;
  • 宿主机基础防火墙规则支持持久化;
  • Docker 启动后自动恢复 Docker 专用防火墙规则;
  • AimiliVPN 数据持久化保存;
  • 重启 VPS 后整套环境仍可自动恢复。
🎉 部署完成标准:重启 VPS 后,Docker 容器正常运行、AimiliVPN HTTP 代理正常、
3x-ui 可以通过 172.20.0.1:7928 获得 VPN 出口,同时 FORWARD 仍保持 DROP,即表示本教程部署成功。

本文中的公网 IP、SSH 端口、域名、管理地址等均未提供,发布时请根据自己的实际环境配置。



评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码

访客信息

您的IP 216.73.216.87
归属地 查询中…
天气 查询中…