需求描述:出口为运营商的ONT,下面是Fortigate做多合一网关,在下面有一台Linux服务器,运行PVE,虚拟机内连接另一城市的外部网络,同时在Fortigate上做分流,使得同局域网下其他设备能够访问外部网络。
该项目仅作为个人记录,也许不太容易复制和实践。
所用设备:
- FortiGate 61E,FortiOS 7.2.13
- PantherX2,Debian 12.9 aarch64
基础环境
架构简述
- Fortigate 61E / FortiOS 7.2
wan1:去往运营商internal:192.168.99.99/24,管理与普通内网internal.10:VLAN 10,Fortigate → proxy VM 入口internal.20:VLAN 20,proxy VM → Fortigate 出口
- PVE 单网口接 Fortigate
internalvmbr0:开启VLAN-awaretag 10:proxy VM 入口网卡tag 20:proxy VM 出口网卡
- proxy VM
enp0s11(VLAN10):10.10.10.11/30,接收 Fortigate 策略路由送来的流量enp2s4(VLAN20):10.20.20.21/30,mihomo 出站回 Fortigate
IP地址规划
- Fortigate internal:
- 192.168.99.99/24
- PVE 管理地址:
- 192.168.99.101/24
- 网关:192.168.99.99
- VLAN 10 / proxy_in:
- Fortigate internal.10:10.10.10.10/24
- mihomo VM enp0s11:10.10.10.11/24
- VLAN 20 / proxy_out:
- Fortigate internal.20:10.20.20.20/24
- mihomo VM enp2s4:10.20.20.21/24
- 网关:10.20.20.20
- 其他普通客户端:
- 192.168.99.0/24
- 网关:192.168.99.99
流量走向
普通流量:
1 | 192.168.99.x |
需要代理的流量:
1 | 192.168.99.x |
配置前提示
本文环境假定当前防火前已配通外部网络(即流量走向章节中的普通流量走向是通的);本文中配置大多为最小化配置,但直接复制应该可以跑得起来,主要是展示原理,需要读者具备一定的数通知识。
一、PVE配置
此处PVE的安装和配置省略,可查看本站往期文章。
二、防火墙配置
2.1.创建VLAN
在internal硬件交换下创建两个vlan,这里我创建为vlan10和vlan20。

1 | config system interface |
2.2.创建地址对象
创建代理机相关的地址对象,方便后面写防火墙策略和策略路由。
1 | config firewall address |
安全和方便起见,我建议再把客户端的地址对象也创建出来。我这里DHCP实际分配范围没有那么大,所以单独写了个地址对象:
1 | config firewall address |
2.3.创建需要代理的地址对象
这一步创建需要代理的地址对象,我这里准备了一个用于探测本地IP地址的服务。因为该服务实际位置在海外,意味着在国内访问可以获取国内地址;一旦该服务被代理,则应输出代理的地址。
1 | C:\Users\LxnChan>curl https://ipdetect.arlxn.top/myip |
出于测试目的,这里我使用该服务用于测试分流。
1 | config firewall address |
2.4.创建策略路由
这一步创建策略路由,策略是将指定地址对象的流量发送到指定的网关上。
1 | config router policy |
2.5.创建防火墙策略(放行)
- 放行内网到代理机的流量
1
2
3
4
5
6
7
8
9
10
11
12config firewall policy
edit 199
set name "InternalSetting"
set srcintf "internal"
set dstintf "proxyIn"
set action accept
set srcaddr "internalClient"
set dstaddr "proxyIn address"
set schedule "always"
set service "ALL"
next
end - 放行代理机出网流量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15config firewall policy
edit 198
set name "proxyOut"
set srcintf "proxyOut"
set dstintf "wan1"
set action accept
set srcaddr "proxyOut"
set dstaddr "all"
set schedule "always"
set service "ALL"
set nat enable
set fixedport enable
set comments "代理机上网"
next
end - 我的所有DNS都走内网(内网有独立的DNS服务器),因此还需要放行代理机到内网DNS的流量
1
2
3
4
5
6
7
8
9
10
11
12
13config firewall policy
edit 197
set name "proxyToDNS"
set srcintf "proxyOut"
set dstintf "internal"
set action accept
set srcaddr "proxyOut"
set dstaddr "DNServerAddr"
set schedule "always"
set service "DNS"
set comments "代理机DNS"
next
end - 放行从【普通客户端】经由【策略路由】指引到【代理机】的流量
1
2
3
4
5
6
7
8
9
10
11
12config firewall policy
edit 196
set name "internetThroughProxy"
set srcintf "internal"
set dstintf "proxyIn"
set action accept
set srcaddr "internalClient"
set dstaddr "all"
set schedule "always"
set service "ALL"
next
end
防火墙的配置到此告一段落。
三、虚拟机配置
3.1.创建虚拟机
创建一个具备两块网卡的虚拟机,这里记为enp0s11和enp2s4,分别设置tag为10和20。
代理机的操作系统我采用了debian 11.11。

3.2.配置网络
用于传入连接的网卡(vlan10)不需要设置网关(因为代理机自己就是网关),另外一块网卡(vlan20)供代理机上网因此需要设置网关。
1 | # /etc/network/interfaces |
3.3.启用转发和禁用IPv6
禁用IPv6是防止路由泄露,也防止配置混乱,后面如果有用到IPv6再单独配置。
注意修改如下配置文件中的网卡名称。
1 | cat >/etc/sysctl.d/99-lxnchan-oversea.conf <<'EOF' |
如果是用本机网卡创建的vlan怎么写这个sysctl配置文件:
因为创建的vlan子网卡的网卡名一般是eth0.10这样,因此这么写:
1 net.ipv4.conf.eth0/10.rp_filter=0即用斜杠做转义即可。
四、配置代理
4.1.下载mihomo
1 | wget https://github.com/MetaCubeX/mihomo/releases/download/v1.19.24/mihomo-linux-arm64-v1.19.24.gz |
生成配置文件夹:
1 | mkdir -p /etc/mihomo |
4.2.安装yq
主要是后面自动patch配置文件时会方便一些。
1 | wget https://github.com/mikefarah/yq/releases/download/latest/yq_linux_arm64 -O /usr/local/bin/yq |
4.3.生成配置文件
我的服务提供商给的配置文件是完整的config.yaml文件,也有的服务商给的只有代理节点信息的,这个之后碰到了再说。
新建/etc/mihomo/config.patched.yaml作为补丁文件,写入需要补充或者覆盖的内容:
1 | # 通过其他webui工具进行管理所需,如果不需要直接改成127.0.0.1即可 |
创建Patch脚本。注意修改wget ...为自己的配置链接;修改下面interface-name后面的接口为出网接口名:
1 |
|
执行后可以测试一下配置文件:
1 | root@proxyMan:/etc/mihomo# /usr/local/bin/mihomo -d /etc/mihomo -f /etc/mihomo/config.yaml -t |
没有报错就可以了。
4.4.以服务方式运行mihomo
写入/etc/systemd/system/mihomo.service:
1 | [Unit] |
启动服务:
1 | systemctl enable --now mihomo |
五、DNS服务器
本来不想写这部分的,后来在实际使用中发现DNS也是很重要的一环。
首先Fortigate的策略路由虽然可以引用域名和Internet服务,但是本质上路径仍然是FQDN先解析为IP然后把对应的流量路由到指定的网关,这意味着Fortigate需要提前知道对应的域名。
而Fortigate知道对应域名的IP的方式主要有两种:通过FortiGuard更新的ISDB库,内置了Fortigate官方对这些域名的解析值;其余手动添加的域名一般都需要Fortigate自己去向DNS请求解析。那么这里就会有一个问题就是当Fortigate和客户端获得的解析不同时,会发生客户端请求无法正确通过策略走向指定路由。本章节所有配置文件仅为展示原理及细节,不是完整配置文件,实际使用需根据实际情况调整。
5.1.DNS部署与配置
我这里内网已经有了DNS,选用的是smartdns,性能和资源占用都比较优秀。
主要需要配置的有两部分(最小配置):
- 解析至少要分为default和oversea两部分,oversea全部配置海外DNS服务。必要时可以配置doh。
1
2
3
4
5
6
7# oversea
server-https https://dns.quad9.net/dns-query -group oversea
server-https https://dns.google/dns-query -group oversea
# default
server-https https://doh.pub/dns-query
server-https https://dns.alidns.com/dns-query
server 119.29.29.29 - 需要把经过策略路由的域名加入oversea组强制走海外解析,此处仅为示例,建议将所有过策略路由的域名都加入oversea解析组,如果写了DoH,建议把DoH的域名也使用oversea解析
1
2
3
4
5
6
7# Github oversea
nameserver /github.com/oversea
nameserver /githubusercontent.com/oversea
nameserver /github.io/oversea
nameserver /ghcr.io/oversea
nameserver /githubassets.com/oversea
nameserver /github.blog/oversea1
2
3
4
5
6
7
8
9# Cloudflare DNS
server 1.0.0.1 -group oversea -group bootstrap-dns
server 1.1.1.1 -group oversea -group bootstrap-dns
# doh bootstrap
nameserver /dns.google/bootstrap-dns
nameserver /dns.quad9.net/bootstrap-dns
# doh servers
server-https https://dns.quad9.net/dns-query -group oversea
server-https https://dns.google/dns-query -group oversea
5.2.EDNS
这一步建议不配置。EDNS相关知识请见官方文档。
国内DNS直接写自己所在网络的子网:
1 | # DNSPod DNS+ |
海外DNS不写-subnet参数,禁用全局EDNS配置(默认情况下EDNS是未启用的)。当然海外DNS也可以根据你海外节点去写对应的EDNS,但是如果线路比较多且使用了CDN产品会导致维护成本过高,实际操作中还是不建议启用。
5.3.防火墙配置
防火墙上主要就是通过策略路由把指定的海外DNS本身的请求流量直接路由到代理网关:
- 配置地址对象
1
2
3
4
5
6
7
8
9config firewall address
edit "CloudflareDNS"
set subnet 1.1.1.1 255.255.255.255
next
edit "GoogleDNS"
set type fqdn
set fqdn "dns.google"
next
end - 配置DNS的策略路由
1
2
3
4
5
6
7
8
9
10config router policy
edit 205
set input-device "internal"
set srcaddr "DNServerAddr"
set dstaddr "CloudflareDNS" "GoogleDNS"
set gateway 10.10.10.11
set output-device "proxyIn"
set comments "海外DNS出方向"
next
end - 在确保Fortigate本机到DNS服务器路由层面通的前提下把Fortigate的系统DNS改到smartDNS,以便Fortigate能和客户端获取相同的地址解析。
1
2
3
4config system dns
set primary 192.168.99.100
set secondary 1.0.0.1
end
六、测试并正式启用
此时测试,可以正常走海外线路了:
1 | C:\Users\LxnChan>curl https://ipdetect.arlxn.top/myip |
此时可以把Google、X或者Telegram等服务加入到策略路由的地址组中,观察到可以正常使用了。


