分享

EdgeRouter 策略路由实现分析 | @sskaje

 xxqa的新文艺 2019-08-16

最近家里的路由规则越来越复杂,而且越来越好用。正好昨天跟朋友讨论他的家用路由改造方案,所以研究了一下EdgeRouter的策略路由(Policy-based Routing,PBR)的实现。

我家里的路由是EdgeRouter Lite,固件1.9.1.1,这个实现跟固件关系不大。

首先,我们可以参考一下官方的文档:EdgeRouter – Policy-based routing (source address based)

IP规则配置

我的路由里:
1. 把Google的IP段配置到了一个firewall group里,组名是 G1,所有访问G1的流量都会走wg0转发,G1的成员是固定的;
2. 把DNSMASQ的一个域名列表的解析结果加到了另外一个group,G2,所有访问G2的流量都会走wg0转发,如前边所述,G2的成员由dnsmasq解析的结果来动态生成;
3. 把我家的一个单独的网段,设置为组G3,所有来自G3的流量都走wg0转发;后来我写了一个简单的页面,可以支持客户端把自己的IP添加到G3或从G3移除,后话再说。

我的路由上,G1,G2,G3都使用了network-group,配置命令

1
2
configure
set firewall group network-group G3 network 192.168.16.0/24

具体实现上,相当于如下的命令:

1
2
# ipset create G3 hash:net
# ipset add G3 192.168.16.0/24

路由表

接下来,配置的是route table。
192.168.10.1 是wg0 网络的远端网关地址,wg0本地ip是 192.168.10.50,所以不需要额外配置192.168.10.0/24的设备路由。

1
2
3
configure
set protocols static table 6 route 0.0.0.0/0 next-hop 192.168.10.1
[edit]

对应的实现,

1
ip route add table 6 0.0.0.0/0 via 192.168.10.1

如果配置使用的wg0是TUN模式,例如openvpn tun,这个时候应该使用interface-route,对应的实现改为 dev xxx。

查看路由表
EdgeRouter的操作模式下

1
2
root@ubnt:/home/ubnt# show ip route table 6
default via 192.168.10.1 dev wg0

对应的实现

1
2
root@ubnt# ip route show table 6
default via 192.168.10.1 dev wg0

防火墙策略

防火墙配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
root@ubnt:/home/ubnt# configure
[edit]
root@ubnt# show firewall modify AUTO_VPN
description "Auto route to vpn based on destination"
rule 700 {
     action modify
     description "src based routing"
     modify {
         table 6
     }
     source {
         group {
             network-group G3
         }
     }
}
rule 800 {
     action modify
     destination {
         group {
             network-group G1
         }
     }
     modify {
         table 6
     }
}
rule 900 {
     action modify
     destination {
         group {
             network-group G2
         }
     }
     modify {
         table 6
     }
}
[edit]
root@ubnt# show interfaces ethernet eth0 firewall
in {
     modify AUTO_VPN
}
[edit]

上述配置中,我定义了AUTO_VPN的规则,把前边提到的G1, G2, G3配置进来。我的路由LAN口在eth0上,所以对于eth0的流入流量应用了这个AUTO_VPN规则。

对应的实现,需要查看iptables。

1
2
3
4
5
6
7
# iptables-save |grep AUTO_VPN
:AUTO_VPN - [0:0]
-A AUTO_VPN -m comment --comment AUTO_VPN-700 -m set --match-set G3 src -j UBNT_PBR_6
-A AUTO_VPN -m comment --comment AUTO_VPN-800 -m set --match-set G1 dst -j UBNT_PBR_6
-A AUTO_VPN -m comment --comment AUTO_VPN-900 -m set --match-set G2 dst -j UBNT_PBR_6
-A AUTO_VPN -m comment --comment "AUTO_VPN-10000 default-action accept" -j RETURN
-A VYATTA_FW_IN_HOOK -i eth0 -j AUTO_VPN

继续查看 UBNT_PBR_6 的规则

1
2
3
4
5
6
7
8
root@ubnt# iptables-save |grep UBNT_PBR_6
:UBNT_PBR_6 - [0:0]
-A AUTO_VPN -m comment --comment AUTO_VPN-700 -m set --match-set G3 src -j UBNT_PBR_6
-A AUTO_VPN -m comment --comment AUTO_VPN-800 -m set --match-set G1 dst -j UBNT_PBR_6
-A AUTO_VPN -m comment --comment AUTO_VPN-900 -m set --match-set G2 dst -j UBNT_PBR_6
-A UBNT_PBR_6 -j MARK --set-xmark 0x3000000/0x7f800000
-A UBNT_PBR_6 -j ACCEPT
[edit]

上述规则都在 mangle

这里,我们看到了对于 UBNT_PBR_6 的规则,iptables给数据包打了个 0x3000000/0x7f800000 的标记。

从iptables的文档里可以看到:

connmark

This module matches the netfilter mark field associated with a connection (which can be set using the CONNMARK target below).
[!] –mark value[/mask]
Matches packets in connections with the given mark value (if a mask is specified, this is logically ANDed with the mark before the comparison).

而这个规则的使用在 ip rule list 里可以看到

1
2
3
4
5
6
root@ubnt# ip rule list
0: from all lookup local
6: from all fwmark 0x3000000/0x7f800000 lookup 6
220: not from all fwmark 0xffffffff lookup 220
32766: from all lookup main
32767: from all lookup default

添加方法:

1
ip rule add pref 6 fwmark 0x3000000/0x7f800000 table 6

回过头来,还得看看 VYATTA_FW_IN_HOOK 这个规则是如何进入的:

1
2
3
4
5
6
7
root@ubnt# iptables-save  |grep VYATTA_FW_IN_HOOK
:VYATTA_FW_IN_HOOK - [0:0]
-A PREROUTING -j VYATTA_FW_IN_HOOK
-A VYATTA_FW_IN_HOOK -i eth0 -j AUTO_VPN
:VYATTA_FW_IN_HOOK - [0:0]
-A FORWARD -j VYATTA_FW_IN_HOOK
[edit]

PREROUTING 在 nat 表里;
FORWARD 在 mangle 表里。

NAT

对于 wg0,或者所有需要流出流量的设备,需要启用nat,才能保证流量正常流入流出。

1
2
3
4
5
6
7
root@ubnt# show service nat rule
...
rule 5032 {
     outbound-interface wg0
     type masquerade
}
[edit]

对应的实现是 在 nat.POSTROUTING 配置 MASQUERADE

1
-A POSTROUTING -o wg0 -m comment --comment NAT-5032 -j MASQUERADE

完结

按上述的结构,我们实现了:
1 定义好组的规则
2 从 mangle.PREROUTING 里,把流量都转向 mangle.VYATTA_FW_IN_HOOK
3 从 mangle.VYATTA_FW_IN_HOOK 里筛选 eth0 的入站流量,应用到 mangle.AUTO_VPN
4 从 mangle.AUTO_VPN 匹配1中定义的规则,应用请求到 mangle.UBNT_PBR_6
5 对 mangle.UBNT_PBR_6 的数据包执行 ACCEPT操作,同时标记为 0x3000000/0x7f800000
6 使用 iproute2 添加一个 0.0.0.0/0 的routing table,指向目标设备/IP
7 使用 iproute2 添加一个规则,把 0x3000000/0x7f800000 的数据包指向 6 中添加的routing table
8 对于目标设备,启用 MASQUERADE

EdgeRouter 策略路由实现分析 by @sskaje: https:///2017/06/edgerouter-policy-based-routing-analysis/

Incoming search terms:

Link to this post!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多