本文将详细介绍如何在 Docker
中部署 OpenWrt
并配置宿主机网络转发,使用 172.16.0.0/16
的内网环境。
docker 容器默认使用
172.17.0.0/16
以及之后的网段, 注意可能冲突
架构概述
在 Docker
容器中运行 OpenWrt
作为透明网关,使宿主机和局域网设备可以通过 OpenWrt
容器转发流量。架构特点包括:
- 使用
Docker
运行完整的OpenWrt
系统 Docker macvlan
网络:容器直接接入物理网络- 双 IP 设计:宿主机同时拥有主 IP 和 macvlan IP
OpenClash
使用 Fake-IP & TUN 模式
网络拓扑
[路由器]
│
└─ LAN 口 (172.16.0.0/16)
│
├─[宿主机 Debian]
│ ├─ enp1s0 172.16.1.202 (主 IP)
│ ├─ local-macvlan 172.16.0.248 (虚拟网卡, 桥接 enp1s0)
│ └─ Docker 服务
│ └────┐
├─[Debian > Docker > OpenWrt]
│ └─ eth0 172.16.0.254
│
└─[其他设备]
└─ 172.16.x.x
准备工作
系统要求
Linux
宿主机(本文以Debian
为例)Docker
和Docker Compose
已安装- 物理网卡
enp1s0
(根据实际情况调整) Debian
网络使用networking
配置systemctl status networking
文件结构准备
创建以下目录结构:
~/openwrt-docker/
├── docker-compose.yml
├── openwrt/
│ ├── config/ # 持久化 openwrt 配置文件
│ └── core/ # 放置 openclash meta 内核文件 clash_meta
详细配置步骤
1. Docker Compose 配置
创建 docker-compose.yml
文件:
1 | services: |
关键参数说明:
privileged: true
和cap_add
是容器获得完整网络功能所必需macvlan
将物理网卡拆分成多个虚拟网卡的实现方案macvlan_mode: bridge
使容器获得与宿主机同级的网络地位
固定 IP172.16.0.254
作为网关地址(OpenWrt 的 IP)
使用bridge
模式确保容器可以与其他设备通信
2. 宿主机网络配置
主网络接口配置
创建 /etc/network/interfaces.d/enp1s0.network
:
1 | # 基本网络配置 |
macvlan 接口配置
创建 /etc/network/interfaces.d/local-macvlan.network
:
1 | # macvlan 接口配置 |
双IP设计原理
主 IP(172.16.1.202) 为宿主机IP, 用于常规网络通信
local-macvlan 的 IP(172.16.0.248) 用作宿主机无法直接与 openwrt 容器 IP(172.16.0.254) 通信的三层路由方案解决
Docker macvlan
网络无法与宿主机直接通信的问题
3. OpenWrt 网络配置
OpenWrt
的主要网络配置文件位于 /etc/config/network
,我们需要配置以下内容:
1 | config interface 'lan' |
4. DNS 配置
修改宿主机 /etc/resolv.conf
以使用 OpenWrt 的 DNS 服务:
1 | nameserver 172.16.0.254 # 指向 OpenWrt 容器 |
1. 要防止网络管理器覆盖, 可以看看 /etc/resolv.conf 文件是不是个 NetworkManager 的软链
当然直接软链删了直接创建个 /etc/resolv.conf 文件就能解决
像在某些系统上有 systemd-resolve 的, 会被接管 dns 到127.0.0.53, 可以直接把 systemd-resolve 关掉
2. 为防止网络管理器覆盖此配置,执行:
1 | sudo chattr +i /etc/resolv.conf # 设置不可变属性 |
部署与验证
1. 启动 OpenWrt 容器
1 | # 进入 docker-compose.yaml 目录执行 |
2. 应用宿主机网络配置
1 | sudo systemctl restart networking |
3. 验证配置
检查容器网络
1 | ip r # 看地址 |
ip r
输出应该类似于:
default via 172.16.0.1 dev br-lan proto static
172.16.0.0/16 dev br-lan proto kernel scope link src 172.16.0.254
198.18.0.0/30 dev utun proto kernel scope link src 198.18.0.1
应显示 eth0
地址为 172.16.0.254
检查宿主机路由表
1 | ip route |
输出应该类似于:
default via 172.16.0.254 dev local-macvlan
172.16.0.0/16 dev enp1s0 proto kernel scope link src 172.16.1.202
172.16.0.0/16 dev local-macvlan proto kernel scope link src 172.16.0.248
172.16.0.254 dev local-macvlan scope link
测试宿主机连接
1 | ping 172.16.0.254 # 测试容器连通性 |
正常配置并成功启动 OpenClash
后, 验证宿主机流量转发情况
1 | curl -vL google.com |
验证 DNS 解析
1 | dig @172.16.0.254 google.com # 测试 DNS 解析 |
google.com DNS 若正常解析即实现本文宿主机的网络转发, 输出应该类似于:
; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> @172.16.0.254 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59826
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; MBZ: 0x0001, udp: 1232
; COOKIE: d8dfbdf3bfbf757e (echoed)
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 1 IN A 198.18.0.5
;; Query time: 0 msec
;; SERVER: 172.16.0.254#53(172.16.0.254) (UDP)
;; WHEN: Fri Apr 01 13:35:00 CST 2025
;; MSG SIZE rcvd: 67
--- END ---
写在最后
未尽事宜待补充, 如有疑问请联系站点概述内邮箱
感谢 kairlec 提供技术指导
本文由 DeepSeek V3 编写, solitude,kairlec 校对