本帖最后由 tr069 于 2023-10-25 15:06 编辑
感谢datong大佬的教程:https://idndx.com/use-routeros-ospf-and-raspberry-pi-to-create-split-routing-for-different-ip-ranges/
一、网络拓扑
光猫下接MikroTik hAP ac2。
ac2下接PVE服务器+AP。
AP下接电视电脑和手机等。
二、分流需求
国内IP从ac2的pppoe口出;
国外IP从PVE隧道出;
qBittorrent安装在PVE上,所有qBittorrent流量从ac2的pppoe口出。
三、效果
手机打开ipw.cn,显示的是你手机的ip。
手机打开ip.sb,显示的是你的海淘隧道的ip。
qBittorrent下载种子,500M宽带,最高下载速度可以达到70M/s,进pt站个人中心查看,你的BT客户端显示的你pve的地址。
打开winbox,导航到/System Resources,当pt下载70M/s时,CPU load在10%到30%。
四、需要用到的工具
海淘隧道:比如naive,监听1080端口;
tun2socks:用来建立tun接口,并转发流量到1080端口;
bird2:用来发布静态路由。
nchnroutes:用来拉取非CN IP地址。
五、PVE设置
1、安装bird2
2、备份bird.conf
- mv /etc/bird/bird.conf /etc/bird/bird.conf.bak
复制代码
3、新建bird.conf
内容如下:
- log syslog all;
- router id 192.168.1.247;
- protocol device {
- scan time 60;
- }
- protocol kernel {
- ipv4 {
- import none;
- export all;
- };
- }
- protocol kernel {
- ipv6 {
- import none;
- export all;
- };
- }
- protocol static {
- ipv4;
- include "routes4.conf";
- }
- protocol static {
- ipv6;
- include "routes6.conf";
- }
- protocol ospf v2 {
- ecmp no;
- ipv4 {
- export all;
- };
- area 0.0.0.0 {
- interface "vmbr0" {
- type pointopoint;
- };
- };
- }
- protocol ospf v3 {
- ecmp no;
- ipv6 {
- export all;
- };
- area 0.0.0.0 {
- interface "vmbr0" {
- type pointopoint;
- };
- };
- }
复制代码
192.168.1.247和vmbr0是PVE的ip地址和接口。
4、拉取海外IP
- git clone https://github.com/dndx/nchnroutes
- cd nchnroute
- nano Makefile
复制代码
修改第5行为:
python3 produce.py --exclude 这里是不走隧道的海外IPv6v4都要写上两个ip之间用空格隔开。
取消 6 7 8行的注释
- sudo mv routes4.conf /etc/bird/routes4.conf
- sudo mv routes6.conf /etc/bird/routes6.conf
- sudo birdc configure
复制代码
然后
添加到计划任务
添加一行:
- 0 0 * * * make -C /path/to/nchnroutes
复制代码
每天晚上12:00就会更新一次ip。
5、启动海陶隧道
过程略
6、建立wg0接口
- sysctl net.ipv4.conf.all.rp_filter=0
- sysctl net.ipv4.conf.eth0.rp_filter=0
- ip tuntap add mode tun dev wg0
- ip addr add 198.18.0.1/15 dev wg0
- ip link set dev wg0 up
- tun2socks -device wg0 -proxy so+ck+s5://127.0.0.1:1080 tcp-sndbuf&
复制代码
把它写为服务
- nano /etc/systemd/system/tun2socks.service
复制代码
内容:
- [Unit]
- Description=TCP forwarding for tun2socks
- After=nss-lookup.target
- [Service]
- ExecStartPre=/usr/bin/ip tuntap add mode tun dev wg0
- ExecStartPre=/usr/bin/ip addr add 198.18.0.1/15 dev wg0
- ExecStartPre=/usr/bin/ip link set dev wg0 up
- ExecStart=/usr/bin/tun2socks -device wg0 -loglevel error -proxy socks5://127.0.0.1:1080 tcp-sndbuf
- ExecStopPost=/usr/bin/ip link set dev wg0 down
- ExecStopPost=/usr/bin/ip addr del 198.18.0.1/15 dev wg0
- ExecStopPost=/usr/bin/ip tuntap del mode tun dev wg0
- [Install]
- WantedBy=multi-user.target
复制代码
服务自启动
- systemctl enable tun2socks
复制代码
启动tun2socks
- systemctl start tun2socks
复制代码
查看启动状态
- systemctl status tun2socks
复制代码
到这里,PVE就完成了国内外ip分流。
测试一下:
ipw.cn显示的是PVE的ip。
ip.sb显示的是海淘隧道海外端的ip。
现在实验一下,手机的网关指向PVE。
再分别打开ipw.cn和ip.sb。
已经实现分流了。
但是这只是实现了PVE内的程序分流,其他设备实现分流需要指定PVE为网关才行。
当然我们不能这样做,因为太傻了,这就需要设置一下RouterOS。
六、RouterOS设置
1、ospf设置
- /routing ospf instance
- add disabled=no name=bird version=2 router-id=192.168.1.1 routing-table=main
- add disabled=no name=bird-ipv6 version=3 router-id=192.168.1.1 routing-table=main
- /routing ospf area
- add disabled=no instance=bird name=bird
- add disabled=no instance=bird-ipv6 name=bird-ipv6
- /routing ospf interface-template
- add area=bird interfaces=LAN type=ptp
- add area=bird-ipv6 interfaces=LAN type=ptp
复制代码
配置好了后,稍等一会,PVE会自动与 RouterOS 建立 OSPF 邻居关系。
RouterOS 会收到了PVE发过来的路由。
我们可以看到,到国外的IP的下一跳是PVE。
现在随便拿一个手机,打开YOUTUBE,发现可以上了。
如果你不用PT,不用zerotier等等,那就完了,这样就完了。
如果你用PT或zerotier等,那就还剩下一个问题。
qBittorrent或zerotier等发送到国外的流量也走wg0接口了怎么办?
我们需要在PVE上执行6条命令:
- iptables -t mangle -A OUTPUT -m owner --gid-owner qbittorrent -j MARK --set-xmark 1
复制代码 qbittorrent用户组的流量给打上标记,标记是0x1
- ip rule add fwmark 1 lookup 1
复制代码 被标记为0x1的流量让它走路由表1
- ip route add default via 192.168.1.1 dev vmbr0 table 1
复制代码 路由表1流量从vmbr0接口走,网关是192.168.1.1
- ip6tables -t mangle -A OUTPUT -m owner --gid-owner qbittorrent -j MARK --set-xmark 1
复制代码 qbittorrent用户组的流量给打上标记,标记是0x1
- ip -6 rule add fwmark 1 lookup 1
复制代码 被标记为0x1的流量让它走路由表1
- ip -6 route add default via fe80::xxx:xxxx:fxxx:xxx dev vmbr0 table 1
复制代码 路由表1流量从vmbr0接口走,网关是fe80::xxx:xxxx:fxxx:xxx
这里的fe80::xxx:xxxx:fxxx:xxx是RouterOS的bridge接口的内网ipv6地址。
zerotier等也是一样,照猫画虎即可。
把以上命令写入/etc/bypasspt.sh并给予可执行权限。
再在/etc/crontab加一行内容:
@reboot root /etc/bypasspt.sh
重启,就自动运行了。
这样qBittorrent的国外流量就不走wg0,而从vmbr0后到达RouterOS的bridge口,RouterOS一看,这是发往
国外的流量,一查路由表,哦,国外流量的下一跳是PVE,又把它发往PVE。
循环了。
要解决这个问题,就需要RouterOS对来自PVE的所有流量都从pppou-out1出去。
这个好办。
1、添加一个bypass路由表
- /routing table add fib name=bypass
复制代码
2、指定PVE走bypass路由表
- /routing rule add src-address=192.168.1.247 action=lookup table=bypas
- /routing rule add src-address=PVE的ipv6地址/128 action=lookup table=bypas
复制代码
3、添加ipv6静态路由让bypass表流量走pppoe-out1
- /ipv6 route
- add dst-address=::/0 gateway=pppoe-out1 distance=1 routing-table=bypass
复制代码
4、添加ipv4静态路由让bypass表走pppoe-out1
- /ip route
- add distance=1 dst-address=0.0.0.0/0 gateway=pppoe-out1 routing-table=bypass
复制代码
现在又有新问题了,PVE出来的所有流量都走了pppoe-out1,包括到192.168.0.0/16等内网的流量,所以
无法从PVE访问内网了,所以还得排除一下。
5、排除来自PVE的到内网的流量
让到fe80::/10的流量走bridge,当然这一条可以不加,因为基本不用
- /ipv6 route
- add dst-address=fe80::/10 gateway=bridge distance=1 routing-table=bypass
复制代码
到10.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 255.255.255.255/32的流量走bridge
- /ip route
- add distance=1 gateway=pppoe-out routing-mark=bypass
- add distance=1 dst-address=10.0.0.0/8 gateway=bridge routing-table=bypass
- add distance=1 dst-address=169.254.0.0/16 gateway=bridge routing-table=bypass
- add distance=1 dst-address=172.16.0.0/12 gateway=bridge routing-table=bypass
- add distance=1 dst-address=192.168.0.0/16 gateway=bridge routing-table=bypass
- add distance=1 dst-address=224.0.0.0/4 gateway=bridge routing-table=bypass
- add distance=1 dst-address=255.255.255.255/32 gateway=bridge routing-table=bypass
复制代码
这样,从PVE出来的流量,到私有地址的流量走bridge,其余全部走pppoe-out1出。
七、其他设置
1、如果你的pve还有其他192.168网段的接口,比如说我就有zerotier的192.168.194.0/24和tinc的
192.168.87.0/24。当qBittorrent用这些地址对外发包时,到RouterOS就无法走bypass表。这就需要在
qBittorrent的高级设置里绑定接口为vmbr0。
2、RouterOS开启ipv6后,如果遇到网站打开慢,有的直接打不开,或者加载不全,多半是MTU的问题
,两条命令解决。
- /ip firewall mangle
- add action=change-mss chain=forward new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn
- /ipv6 firewall mangle
- add action=change-mss chain=forward new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn
复制代码
另外一种方法(建议):RouterOS PPPoE 拨号启用IPv6设置 - 易科博客 (exsvc.cn)
3、上面指定PVE走bypass路由表这一步,因为PVE的ipv6地址是动态的,pppoe每拨号一次,它就变动一次,
我们现在需要一个脚本,让ipv6地址变动时自动更新路由表。
脚本内容如下:
- :local ipv6address
- :foreach neighbor in=[/ipv6 neighbor find address~"2409:8a6a" mac-address="1C:1B:19:1F:18:10" status=reachable] do={
- :set ipv6address [/ipv6 neighbor get $neighbor address]
- :if ($ipv6address != "") do={
- :set ipv6address ($ipv6address . "/128")
- :if ([:len [/routing rule find src-address~"1e1b:19ff:fe1f:1810"]] = 0 || [/routing rule get [/routing rule find src-address~"1e1b:19ff:fe1f:1810"] src-address] != $ipv6address) do={
- /routing rule set [find src-address~"1e1b:19ff:fe1f:1810"] src-address=$ipv6address
- }
- }
- }
复制代码
大意就是从neighbor中查找address包含"2409:8a6a" mac-address="1C:1B:19:1F:18:10" 状态是可达的ipv6地址
将它存储为变量ipv6address,如果这个数值不是空的,那就加上掩码/128,并和/routing rule里src-address包含
"1e1b:19ff:fe1f:1810"的ipv6地址相比较,如果两者不相符,则将后者更新为前者。
把2409:8a6a和1C:1B:19:1F:18:10改为你自己的。脚本就成了。5秒或10秒执行一次,就OK了。
八、更好的放行PT下载设备的方法
把pt下载用的设备不要放进bridge,另外起个pool,在另外一个网段,直接放行端口就可以了。
比如,pt设备插在routeros的ether5
/routing rule add interface=ether5 action=lookup table=bypass
就可以了。
请不要胡乱输入以及粘贴、复制等方式灌水
请尊重作者、并共同维护网站的正常阅读,否则账户将会被限制发帖、回帖,并且积分可能会被清零,站内短信以及阅读权限等都会受到影响,谢谢。
具体限制方式:https://www.right.com.cn/forum/thread-8307840-1-1.html
|