使用mihomo +docker 进行路由转发实现全局透明代理
-
开启混杂模式
ip link set eth0 promisc on
-
docker创建网络,注意将网段改为你自己的
docker network create -d macvlan --subnet=192.168.5.0/24 --gateway=192.168.5.1 -o parent=eth0 _dMACvLan
*
_
是为了提高_dMACvLan
的优先级,可在多网络容器的中作为默认路由。 -
提前准备好正确的mihomo config
-
运行容器
sudo docker run --name mihomo-tproxy -d -v /your/path/mihomo_config:/mihomo_config --network _dMACvLan --ip 192.168.5.254 ghcr.io/silencebay/mihomo-tproxy:premium-latest
version: '3.2' services: mihomo-tproxy: container_name: mihomo-tproxy image: ghcr.io/silencebay/mihomo-tproxy:premium-latest logging: options: max-size: '10m' max-file: '3' restart: unless-stopped #entrypoint: tail -f /dev/null #command: tail -f /dev/null volumes: - ./mihomo_config:/mihomo_config environment: - TZ=Asia/Shanghai - EN_MODE=redir-host cap_add: - NET_ADMIN extra_hosts: - 'baidu.com:220.181.38.251' networks: dMACvLAN: ipv4_address: 192.168.5.254 aio: dns: - 114.114.114.114 networks: dMACvLAN: external: name: _dMACvLan
-
将手机/电脑等客户端 网关设置为容器ip,如192.168.5.254 ,dns也设置成这个
- 只要规则设置的对, 支持国内直连,国外走代理
- 只在linux 测试过,win没试过, mac是不行, 第二步创建网络不行, docker自己的问题, 说不定以后哪天docker for mac支持了?
docker buildx build --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 -t <your_username>/mihomo-tproxy:premium-latest . --push
设置客户端(或设置路由器DHCP)默认网关及DNS服务器为容器IP:192.168.5.254
以openwrt为例,在/etc/config/dhcp
中config dhcp 'lan'
段加入:
list dhcp_option '6,192.168.5.254'
list dhcp_option '3,192.168.5.254'
使用过程中发现,若启用了IPv6,某些客户端(Android)会自动将DNS服务器地址指向默认网关(路由器)的ipv6地址,导致客户端不走docker中的dns服务器。
解决方案是修改路由器中ipv6的通告dns服务器
为容器ipv6地址。
以openwrt为例,在/etc/config/dhcp
中config dhcp 'lan'
段加入:
list dns 'fe80::fe80'
由于docker网络采用macvlan
的bridge
模式,宿主机虽然与容器在同一网段,但是相互之间是无法通信的,所以无法通过tproxy-gateway
透明代理。
让宿主机直接走主路由,不经过代理网关:
ip route add default via 192.168.5.254 dev eth0 # 设置静态路由
echo "nameserver 192.168.5.254" > /etc/resolv.conf # 设置静态dns服务器
利用多个macvlan接口之间是互通的原理,新建一个macvlan虚拟接口:
-
临时配置网络(重启后失效)
ip link add link eth0 mac0 type macvlan mode bridge # 在eth0接口下添加一个macvlan虚拟接口 ip addr add 192.168.5.250/24 brd + dev mac0 # 为mac0 分配ip地址 ip link set mac0 up ip route del default #删除默认路由 ip route add default via 192.168.5.254 dev mac0 # 设置静态路由 echo "nameserver 192.168.5.254" > /etc/resolv.conf # 设置静态dns服务器
-
永久配置网络(重启也能生效)
-
使用 nmcli,需要
NetworkManager
nmcli connection add type macvlan dev eth0 mode bridge ifname mac30 ipv4.route-metric 10 ipv6.route-metric 10 autoconnect yes save yes
如果想自定义 ip 及网关,可执行:
nmcli connection add type macvlan dev eth0 mode bridge ifname mac30 ipv4.route-metric 10 ipv6.route-metric 10 ipv4.method manual ip4 192.168.5.250/24 gw4 192.168.5.254 autoconnect yes save yes
注意:需使用更低的
metric
来提高default
路由的优先级另外,你可能需要修改
dns
:nmcli con mod macvlan-mac30 ipv4.dns "192.168.5.254"
忽略
eth0
的 DHCP 自动获取的 dns:nmcli con mod <eth0-connectionName> ipv4.ignore-auto-dns yes
如果是
ifupdown(eth0)
,先删除:/etc/network/interfaces
仅保留以下内容:
auto lo iface lo inet loopback
/etc/NetworkManager/NetworkManager.conf
更改 [ifupdown] 条目中的managed
值:[ifupdown] managed=false
-
宿主机(Debian)修改网络配置:
vi /etc/network/interface
*请先禁用
NetworkManager
以下配置不支持网线热插拔,热插拔后需手动重启网络。可借用
ifplugd
解决(操作不详)将:
auto eth0 iface eth0 inet static address 192.168.5.250 broadcast 192.168.5.255 netmask 255.255.255.0 gateway 192.168.5.254 dns-nameservers 192.168.5.254
修改为:
-
dhcp
auto eth0 iface eth0 inet dhcp auto macvlan iface macvlan inet dhcp pre-up route del default pre-up route del -net 192.168.5.0 netmask 255.255.255.0 pre-up ip link add $IFACE link eth0 type macvlan mode bridge post-up ip r replace default via 192.168.5.254 post-up echo "nameserver 192.168.5.254" > /etc/resolv.conf # 设置静态dns服务器 post-down ip link del $IFACE link eth0 type macvlan mode bridge
-
静态
auto eth0 iface eth0 inet manual metric 100 auto macvlan iface macvlan inet static metric 10 address 192.168.5.250 netmask 255.255.255.0 gateway 192.168.5.254 dns-nameservers 192.168.5.254 pre-up ip link add $IFACE link eth0 type macvlan mode bridge post-down ip link del $IFACE link eth0 type macvlan mode bridge
或
auto eth0 iface eth0 inet manual auto macvlan iface macvlan inet manual #pre-up ip monitor link dev eth0 | grep -q 'state UP' pre-up while ! ip link show eth0 | grep -q 'state UP'; do echo "waiting for eth0 is ready"; sleep 2; done pre-up while ! ip route show | grep -q '^default'; do echo "waiting eth0 got required rules"; sleep 2; done pre-up while ! ip route show | grep -q '192.168.5.0/24 dev eth0'; do echo "waiting eth0 got required rules"; sleep 2; done pre-up ip link add $IFACE link eth0 type macvlan mode bridge pre-up ip addr add 192.168.5.250/24 brd + dev $IFACE up ip link set $IFACE up #up udevadm trigger post-up ip route del default post-up ip route del 192.168.5.0/24 dev eth0 post-up ip route add default via 192.168.5.254 dev $IFACE post-down ip link del dev $IFACE down ifdown eth0 down ifup eth0
修改完后重启网络
systemctl restart networking
或者重启系统查看效果。 -
-
version: "3.4"
services:
mihomo-tproxy:
...
environment:
- DOCKER_HOST_INTERNAL=172.17.0.0/16,eth0
# or without interface specified. Will find the interface with the shortest path
# - DOCKER_HOST_INTERNAL=172.17.0.0/16
参考资料
docker_global_transparent_proxy
配置文件
路由及防火墙设置
overturn DNS
overturn + mihomo in docker as dns server and transparent proxy gateway
宿主机配置
https://github.com/fanyh123/tproxy-gateway
IPv6 Router Preferences and More-Specific Routes (RFC 4191)