MSF-Docker
Docker app from ScoltZero's Repository
Overview
Readme
View on GitHubDocker TUN 部署
Docker host-tun 与 macvlan-tun 已正式收口为 TUN-only。初始化界面不会提供 nftables,后端也会拒绝 Docker 环境的 nftables 请求。
当前稳定镜像:ghcr.io/scoltzero/msf:latest
当前 Docker 镜像:
ghcr.io/scoltzero/msf:latest
发布流程同时推送版本化 tag 与 latest;下方安装命令统一使用 latest,日常升级无需手动修改版本号。
当前状态
- Docker 版默认使用 Mihomo TUN,不再由 MSF 写入宿主机 nftables 或 policy routing。
- 支持两种容器网络:
host-tun和macvlan-tun。 host-tun使用 Docker 宿主机网络命名空间,适合测试、宿主机自身代理,或已经能配置主路由静态路由和宿主机转发的旁路由环境。macvlan-tun让容器拥有独立 LAN IPv4,适合 Unraid Dockerman / br0 / 自定义网络场景,也是当前 Docker 网关部署更推荐的方式。- 运行数据必须映射到宿主机目录;容器内数据目录固定为
/opt/msf,默认示例映射到宿主机./msf-data。 - 容器内禁用
msf update和 WebUI 自更新安装;镜像升级必须通过 Docker / Compose / 容器管理器完成。
初始化预检会阻止缺少 /dev/net/tun、CAP_NET_ADMIN、CAP_NET_RAW 或无效 Docker 网络模式的部署继续初始化。
运行要求
两种模式都需要 TUN 设备和网络管理权限:
cap_add:
- NET_ADMIN
- NET_RAW
devices:
- /dev/net/tun:/dev/net/tun
Docker 镜像默认设置:
MSF_RUNTIME=docker
MSF_DOCKER_NETWORK_MODE=host-tun
MSF_DOCKER_CLEANUP_NETWORK_ON_EXIT=false
Docker TUN 模式下,Mihomo 配置会启用 tun.auto-route、tun.auto-detect-interface 和 tun.route-address,显式保持 tun.dns-hijack=[]、tun.auto-redirect=false,并配置 dns.proxy-server-nameserver。DNS 分流仍由 MosDNS 负责,Mihomo 只接管 Fake-IP 和必要公网目标。这意味着 MSF 不会写宿主机 table inet msf、fwmark 1 table 100 或 ip rule。如果你把 host-tun 当作旁路网关使用,还需要按下文补充宿主机 FakeIP 路由。
数据目录必须持久化映射:
宿主机目录 -> 容器目录
./msf-data -> /opt/msf
MosDNS、Mihomo、Zashboard 下载文件、数据库、配置、日志和用户上传的 Mihomo 配置都会写入 /opt/msf。如果不映射这个目录,容器重建后这些数据会丢失,WebUI 中的组件下载和配置管理也无法可靠工作。
快速启动:host TUN
host TUN 使用宿主机 IP 对外提供 WebUI、DNS 和代理服务。
Docker Compose
仓库根目录已经提供 docker-compose.yml。如果你需要手工创建文件,可以直接复制下面内容保存为 docker-compose.yml:
services:
msf:
image: ghcr.io/scoltzero/msf:latest
container_name: msf
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
devices:
- /dev/net/tun:/dev/net/tun
environment:
MSF_RUNTIME: docker
MSF_DATA_DIR: /opt/msf
MSF_DOCKER_NETWORK_MODE: host-tun
MSF_DOCKER_CLEANUP_NETWORK_ON_EXIT: "false"
volumes:
- ./msf-data:/opt/msf
restart: unless-stopped
stop_grace_period: 30s
启动:
mkdir -p msf-data
docker compose up -d
默认 compose 文件使用:
- 镜像:
ghcr.io/scoltzero/msf:latest - 网络:
host - 数据目录:
./msf-data:/opt/msf - WebUI:
http://<宿主机IP>:7777 - 运行标识:
MSF_RUNTIME=docker - Docker 网络模式:
MSF_DOCKER_NETWORK_MODE=host-tun
普通 Docker 脚本
不适合使用 Docker Compose 的机器可以直接运行:
mkdir -p msf-data
./docker-run.sh
等价的核心参数是:
docker run -d \
--name msf \
--network host \
--cap-add NET_ADMIN \
--cap-add NET_RAW \
--device /dev/net/tun:/dev/net/tun \
--restart unless-stopped \
--stop-timeout 30 \
-e MSF_RUNTIME=docker \
-e MSF_DOCKER_NETWORK_MODE=host-tun \
-e MSF_DATA_DIR=/opt/msf \
-v "$PWD/msf-data:/opt/msf" \
ghcr.io/scoltzero/msf:latest
快速启动:macvlan TUN
macvlan TUN 给容器分配独立 LAN IPv4。路由器侧 DHCP DNS 和 FakeIP 静态路由都应指向这个容器 IPv4,而不是宿主机 IP。
Docker Compose
仓库根目录已经提供 docker-compose.macvlan.yml。如果你需要手工创建文件,可以直接复制下面内容保存为 docker-compose.macvlan.yml:
services:
msf:
image: ${MSF_IMAGE:-ghcr.io/scoltzero/msf:latest}
container_name: ${MSF_CONTAINER_NAME:-msf}
cap_add:
- NET_ADMIN
- NET_RAW
devices:
- /dev/net/tun:/dev/net/tun
environment:
MSF_RUNTIME: docker
MSF_DATA_DIR: /opt/msf
MSF_DOCKER_NETWORK_MODE: macvlan-tun
MSF_DOCKER_CLEANUP_NETWORK_ON_EXIT: "false"
volumes:
- ${MSF_DOCKER_DATA_DIR:-./msf-data}:/opt/msf
networks:
msf_macvlan:
ipv4_address: ${MSF_DOCKER_IPV4_ADDRESS:?set MSF_DOCKER_IPV4_ADDRESS}
restart: unless-stopped
stop_grace_period: 30s
networks:
msf_macvlan:
name: ${MSF_DOCKER_NETWORK_NAME:-msf-macvlan}
driver: macvlan
driver_opts:
parent: ${MSF_DOCKER_PARENT_IFACE:?set MSF_DOCKER_PARENT_IFACE}
ipam:
config:
- subnet: ${MSF_DOCKER_SUBNET:?set MSF_DOCKER_SUBNET}
gateway: ${MSF_DOCKER_GATEWAY:?set MSF_DOCKER_GATEWAY}
复制示例环境变量并按你的 LAN 修改:
cp docker.env.example .env
也可以直接复制下面这个 macvlan compose .env 示例保存为 .env 后修改:
MSF_IMAGE=ghcr.io/scoltzero/msf:latest
MSF_CONTAINER_NAME=msf
MSF_DOCKER_DATA_DIR=./msf-data
MSF_DOCKER_NETWORK_NAME=msf-macvlan
MSF_DOCKER_PARENT_IFACE=eth0
MSF_DOCKER_SUBNET=192.168.1.0/24
MSF_DOCKER_GATEWAY=192.168.1.1
MSF_DOCKER_IPV4_ADDRESS=192.168.1.10
macvlan 模式至少需要按你的 LAN 修改 MSF_DOCKER_PARENT_IFACE、MSF_DOCKER_SUBNET、MSF_DOCKER_GATEWAY 和 MSF_DOCKER_IPV4_ADDRESS。
启动:
mkdir -p msf-data
docker compose -f docker-compose.macvlan.yml up -d
普通 Docker 脚本
MSF_DOCKER_NETWORK_MODE=macvlan-tun \
MSF_DOCKER_PARENT_IFACE=eth0 \
MSF_DOCKER_SUBNET=192.168.1.0/24 \
MSF_DOCKER_GATEWAY=192.168.1.1 \
MSF_DOCKER_IPV4_ADDRESS=192.168.1.10 \
./docker-run.sh
脚本会在 msf-macvlan 网络不存在时创建它。可用 MSF_DOCKER_NETWORK_NAME 覆盖网络名。
Unraid Community Applications / Dockerman IPv4 macvlan
仓库提供 Community Applications Docker 模板 packaging/unraid/ca/msf-docker.xml。从 CA 安装 MSF Docker 时,模板会预填以下参数;也可以继续在 Unraid Dockerman 中手工创建容器。
- 在 Unraid Docker 设置中启用自定义网络,并选择
macvlan或你当前系统推荐的自定义网络实现。 - 从 CA 安装 MSF Docker,或新建容器并填写镜像
ghcr.io/scoltzero/msf:latest。 - Network Type 选择自定义 LAN 网络,例如
br0。 - Fixed IP address 填写一个未被 DHCP 分配的静态 IPv4,例如
192.168.1.10。 - Extra Parameters 或高级参数添加:
--cap-add NET_ADMIN --cap-add NET_RAW --device /dev/net/tun:/dev/net/tun
- 添加环境变量:
| 变量 | 值 |
|---|---|
MSF_RUNTIME |
docker |
MSF_DOCKER_NETWORK_MODE |
macvlan-tun |
MSF_DATA_DIR |
/opt/msf |
- 添加路径映射:
| 宿主机路径 | 容器路径 |
|---|---|
/mnt/user/appdata/msf-docker |
/opt/msf |
WebUI 地址为 http://<容器IPv4>:7777。
路由接入
首次打开 WebUI 后完成初始化向导。Docker runtime 下初始化页默认选择 TUN 模式。
路由器侧需要:
- DHCP DNS 指向 MSF 地址。
- FakeIP 静态路由指向同一个 MSF 地址。
MSF 地址按网络模式选择:
| Docker 模式 | 路由器应指向 |
|---|---|
host-tun |
Docker 宿主机 LAN IP |
macvlan-tun |
容器独立 LAN IPv4;启用 IPv6 时还需要容器可路由 IPv6 |
默认 FakeIP 网段:
| 类型 | 网段 |
|---|---|
| IPv4 | 28.0.0.0/8 |
| IPv6 | f2b0::/18 |
macvlan 默认验收仍以 IPv4 为主。若启用 IPv6,需要容器拥有可被主路由访问的 IPv6,并在主路由上把 f2b0::/18 指向这个容器 IPv6。完整教程见 路由器接入总览。
host-tun FakeIP 路由持久化
host-tun 共享 Docker 宿主机网络命名空间。主路由把 28.0.0.0/8 静态路由指向 Docker 宿主机后,宿主机还必须把完整 IPv4 FakeIP 网段交给 Mihomo TUN;启用 IPv6 时,f2b0::/18 也需要同样指向 Mihomo TUN。部分环境里 Mihomo 只会给 mihomo 接口生成 28.0.0.0/30,这只能覆盖 28.0.0.0 到 28.0.0.3,客户端拿到 28.0.0.13 这类 FakeIP 时就不会进入 TUN。
新版本会在 Docker host-tun + Mihomo TUN 模式下,在 Mihomo 启动成功后自动补齐 FakeIP IPv4 路由;如果配置中启用了 IPv6,也会自动补齐 FakeIP IPv6 路由。程序还会尝试关闭默认出口网卡的 rp_filter。如果宿主机 /proc/sys 只读、系统防火墙重放了路由规则,或你正在排查旧版本问题,可以继续使用下面的手工命令作为 fallback。程序不会自动重启 firewalld、nftables 或 ufw。
先在 Docker 宿主机上临时验证:
sudo ip route replace 28.0.0.0/8 dev mihomo src 28.0.0.1
# 如果启用了 IPv6:
sudo ip -6 route replace f2b0::/18 dev mihomo src f2b0::1
IFACE="$(ip -4 route show default | awk '/default/ {print $5; exit}')"
echo 0 | sudo tee "/proc/sys/net/ipv4/conf/$IFACE/rp_filter" >/dev/null
sudo sh -c '
if systemctl is-active --quiet firewalld 2>/dev/null; then
systemctl restart firewalld
elif systemctl is-active --quiet nftables 2>/dev/null; then
systemctl restart nftables
elif command -v ufw >/dev/null 2>&1; then
ufw reload
else
echo "no firewalld/nftables/ufw service detected, skipped"
fi
'
确认 FakeIP 已经走 mihomo:
ip route get 28.0.0.13
# 如果启用了 IPv6:
ip -6 route get f2b0::13
cat "/proc/sys/net/ipv4/conf/$IFACE/rp_filter"
期望看到:
28.0.0.13 dev mihomo src 28.0.0.1
f2b0::13 dev mihomo src f2b0::1
0
临时命令在容器、Mihomo 或宿主机重启后可能丢失。需要持久化时,在 Docker 宿主机上创建 systemd 定时任务。它会定期检查 mihomo 接口是否存在,存在时补齐 FakeIP 路由并关闭出口网卡 rp_filter。如果启用了 IPv6,把脚本里的 ENABLE_IPV6=0 改为 ENABLE_IPV6=1:
sudo tee /usr/local/sbin/msf-host-tun-route >/dev/null <<'EOF'
#!/bin/sh
set -eu
ENABLE_IPV6=0
ip link show mihomo >/dev/null 2>&1 || exit 0
IFACE="$(ip -4 route show default | awk '/default/ {print $5; exit}')"
ip route replace 28.0.0.0/8 dev mihomo src 28.0.0.1
if [ "$ENABLE_IPV6" = "1" ]; then
ip -6 route replace f2b0::/18 dev mihomo src f2b0::1
fi
if [ -n "$IFACE" ] && [ -w "/proc/sys/net/ipv4/conf/$IFACE/rp_filter" ]; then
echo 0 > "/proc/sys/net/ipv4/conf/$IFACE/rp_filter"
fi
EOF
sudo chmod +x /usr/local/sbin/msf-host-tun-route
sudo tee /etc/systemd/system/msf-host-tun-route.service >/dev/null <<'EOF'
[Unit]
Description=Apply MSF Docker host-tun FakeIP route
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/msf-host-tun-route
EOF
sudo tee /etc/systemd/system/msf-host-tun-route.timer >/dev/null <<'EOF'
[Unit]
Description=Refresh MSF Docker host-tun FakeIP route
[Timer]
OnBootSec=30s
OnUnitActiveSec=30s
AccuracySec=5s
Unit=msf-host-tun-route.service
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now msf-host-tun-route.timer
sudo systemctl start msf-host-tun-route.service
防呆:如果你的系统防火墙服务会缓存或重放转发规则,安装持久化任务后手动重启当前正在使用的防火墙服务:
sudo sh -c '
if systemctl is-active --quiet firewalld 2>/dev/null; then
systemctl restart firewalld
elif systemctl is-active --quiet nftables 2>/dev/null; then
systemctl restart nftables
elif command -v ufw >/dev/null 2>&1; then
ufw reload
else
echo "no firewalld/nftables/ufw service detected, skipped"
fi
'
脚本变量
docker-run.sh 支持:
| 变量 | 默认值 | 用途 |
|---|---|---|
MSF_IMAGE |
ghcr.io/scoltzero/msf:latest |
容器镜像 |
MSF_CONTAINER_NAME |
msf |
容器名称 |
MSF_DOCKER_DATA_DIR |
$PWD/msf-data |
宿主机数据目录 |
MSF_DOCKER_NETWORK_MODE |
host-tun |
host-tun 或 macvlan-tun |
MSF_DOCKER_NETWORK_NAME |
msf-macvlan |
macvlan Docker network 名称 |
MSF_DOCKER_PARENT_IFACE |
无 | macvlan 父接口 |
MSF_DOCKER_SUBNET |
无 | macvlan IPv4 子网 |
MSF_DOCKER_GATEWAY |
无 | macvlan IPv4 网关 |
MSF_DOCKER_IPV4_ADDRESS |
无 | 容器静态 IPv4 |
如果同名容器已经存在,先停止并删除旧容器:
docker stop msf
docker rm msf
常见问题
LXC / Proxmox 提示 /dev/net/tun 不存在
如果部署时报错:
error gathering device information while adding custom device "/dev/net/tun": no such file or directory
说明 Docker daemon 所在的运行环境没有 /dev/net/tun。如果 Docker 跑在 LXC 里,需要在 LXC 容器内检查:
ls -l /dev/net/tun
cat /dev/net/tun
正常情况下,cat /dev/net/tun 应返回类似 File descriptor in bad state。如果文件不存在,需要在外层宿主机加载并透传 TUN,例如 Proxmox LXC 可参考:
modprobe tun
features: nesting=1
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
修改 LXC 配置后重启容器。不同平台的 LXC 权限模型不完全一样,必要时请使用 privileged LXC 或 VM 测试。
v0.3.7 Docker TUN 出现 DNS / Fake-IP 连接异常
v0.3.7 的 Docker TUN 默认配置存在缺陷:Mihomo 可能把节点服务器域名解析成 28.0.0.x 这类 Fake-IP,随后拨号失败;日志里也可能出现大量 127.0.0.1:8888 connection refused 或节点域名连接超时。
修复版本会统一 Linux TUN 生成逻辑:
tun.stack使用system。tun.dns-hijack保持空数组,由 MosDNS 继续负责 DNS 分流。tun.route-address包含 Fake-IP 网段和必要公网目标。tun.route-exclude-address排除 LAN、loopback、link-local 和常见国内 DNS。dns.proxy-server-nameserver使用223.5.5.5、119.29.29.29,避免节点服务器域名被 Fake-IP 污染。
升级到修复版本后,如果你仍使用生成配置模式,MSF 会在启动时自动修正旧的 TUN / DNS 配置块。若你已经切换到 Mihomo 自定义配置模式,MSF 不会自动覆盖你的文件,请按上面的字段手动调整,或在 WebUI 中恢复为生成配置后重新生成。
macvlan 提示 invalid subinterface vlan name
如果部署时报错类似:
invalid subinterface vlan name MSF_DOCKER_PARENT_IFACE:eth0, example formatting is eth0.10
说明 Docker 收到的 macvlan parent 不是实际网卡名。parent 必须是 Docker 所在宿主环境中的真实接口,例如 eth0、ens18、br0 或 VLAN 子接口 eth0.10。
.env 文件必须使用等号写法:
MSF_DOCKER_PARENT_IFACE=eth0
不要写成:
MSF_DOCKER_PARENT_IFACE:eth0
在 Portainer Stack 里,请把 MSF_DOCKER_PARENT_IFACE 作为环境变量名、eth0 作为值填写,不要把 MSF_DOCKER_PARENT_IFACE:eth0 当成一个完整值。可以先用下面命令确认 compose 展开结果:
MSF_DOCKER_PARENT_IFACE=eth0 \
MSF_DOCKER_SUBNET=192.168.1.0/24 \
MSF_DOCKER_GATEWAY=192.168.1.1 \
MSF_DOCKER_IPV4_ADDRESS=192.168.1.10 \
docker compose -f docker-compose.macvlan.yml config
输出中应能看到:
driver_opts:
parent: eth0
更新和卸载
Docker 容器内禁用 msf update 和 WebUI 自更新安装。镜像升级应通过拉取新镜像并重建容器完成。
Docker Compose:
docker compose pull
docker compose up -d
普通 Docker:
docker pull ghcr.io/scoltzero/msf:latest
docker stop msf
docker rm msf
./docker-run.sh
卸载时通过 Docker / Compose / 容器管理器删除容器。默认数据目录在宿主机当前目录的 ./msf-data,需要彻底清理时再手动删除该目录。
MosDNS、Mihomo、Zashboard 的组件更新仍可在 WebUI 中使用。
常见端口
Docker TUN 默认不使用 TProxy/Redirect 端口。
| 端口 | 用途 |
|---|---|
7777 |
MSF WebUI |
53/tcp,udp |
MosDNS |
7890 |
Mihomo HTTP proxy |
7891 |
Mihomo SOCKS proxy |
7892 |
Mihomo mixed proxy |
9090 |
Mihomo controller / Zashboard |
9099 |
MosDNS observability |
Requirements
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/scoltzero/msf:latestRuntime arguments
- Web UI
http://[IP]:[PORT:7777]- Network
br0- Shell
bash- Privileged
- false
- Extra Params
--cap-add=NET_ADMIN --cap-add=NET_RAW
Template configuration
Persistent MSF configuration, components, databases, and logs.
- Target
- /opt/msf
- Default
- /mnt/user/appdata/msf-docker
- Value
- /mnt/user/appdata/msf-docker
Pass the host TUN device into the container.
- Target
- /dev/net/tun
- Value
- /dev/net/tun
MSF WebUI port. Keep 7777 when using a custom br0 address.
- Target
- 7777
- Default
- 7777
- Value
- 7777
Identifies this installation as a Docker runtime.
- Target
- MSF_RUNTIME
- Default
- docker
- Value
- docker
Persistent data directory inside the container.
- Target
- MSF_DATA_DIR
- Default
- /opt/msf
- Value
- /opt/msf
MSF TUN networking mode for an Unraid custom LAN address.
- Target
- MSF_DOCKER_NETWORK_MODE
- Default
- macvlan-tun
- Value
- macvlan-tun
Keep host and container networking intact when MSF exits.
- Target
- MSF_DOCKER_CLEANUP_NETWORK_ON_EXIT
- Default
- false
- Value
- false