场景描述
通过在路由器上配置基于端口的PBR,实现将指定流量引至BMF进行安全分析而后回注路由器的目的。
注 因为PBR比默认路由优先级高,因此配置PBR时要注意回注的流量能否正确路由的问题
实验环境搭建
要实现PBR引流BMF,我们需要下面几个要素:
- 流量
- 路由器
- BMF
利用手头的资源,决定使用Linux系统充当路由器,通过配置namespace构造流量。下面是实验环境的拓扑图:
I. pbr-router
- 环境准备:使用裸机安装CentOS 7发行版,并安装Open vSwitch (以下简称ovs)。网络方面,除管理口外还要UP两个口
egress ingress
(根据自己设备指定值,如em2 eth2
等),直连egress
与BMFfilter
、ingress
与BMFdelivery
- 创建三个namespace
router src dst
、三个ovs网桥br-pbr br-egress br-ingress
,将egress
物理口加入br-egress
、ingress
物理口加入br-ingress
。再创建两个ovs patch口用于连接三个ovs网桥
# 创建namespace
ip netns add src
ip netns add dst
ip netns add router
# 创建ovs网桥
ovs-vsctl add-br br-pbr
ovs-vsctl add-br br-ingress
ovs-vsctl add-br br-egress
# 使用patch port连接ovs网桥
ovs-vsctl \
-- add-port br-pbr pbr-patch-ingress \
-- set Interface pbr-patch-ingress type=patch options:peer=ingress-patch-pbr \
-- add-port br-ingress ingress-patch-pbr \
-- set Interface ingress-patch-pbr type=patch options:peer=pbr-patch-ingress
ovs-vsctl \
-- add-port br-pbr pbr-patch-egress \
-- set Interface pbr-patch-egress type=patch options:peer=egress-patch-pbr \
-- add-port br-egress egress-patch-pbr \
-- set Interface egress-patch-pbr type=patch options:peer=pbr-patch-egress
# 将物理口加入ovs网桥
ovs-vsctl add-port br-ingress ingress
ovs-vsctl add-port br-egress egress
- 创建一对veth pair,分别放到namespace
src
和ovs的br-pbr
中,用作请求的源端。再创建一对veth pair,分别放到namespacedst
和ovs的br-pbr
中,用作请求的目的端
# 创建veth对
ip link add veth-src type veth peer name veth-src-br
ip link add veth-dst type veth peer name veth-dst-br
ip link add dev src netns veth-src
ip link add dev dst netns veth-dst
ip netns exec src ifconfig veth-src 192.168.0.2/24 up
ip netns exec dst ifconfig veth-dst 192.168.2.2/24 up
ip netns exec src ifconfig lo up
ip netns exec dst ifconfig lo up
# 将veth一段加入ovs网桥
ovs-vsctl add-port br-pbr veth-src-br
ovs-vsctl add-port br-pbr veth-dst-br
- 创建四个ovs的internal port,放入namespace
router
中。其中,qr-0-1
为src的默认网关,qr-1-1
为dst的默认网关,qg-e
为PBR出口,qg-i
为PBR回注口。
注 四个port在不同网段。
qg-e
与nf-in
同网段,qg-i
与nf-out
同网段。并且,router namespace中要配置nf-in
的 静态arp
# 创建四个ovs internal port
ovs-vsctl add-port br-pbr qr-0-1\
-- set Interface qr-0-1 type=internal
ovs-vsctl add-port br-pbr qr-1-1\
-- set Interface qr-1-1 type=internal
ovs-vsctl add-port br-pbr qg-e\
-- set Interface qg-e type=internal
ovs-vsctl add-port br-pbr qg-i\
-- set Interface qg-i type=internal
# 将ovs internel port加入router namespace
ip link set dev qr-0-1 netns router
ip link set dev qr-1-1 netns router
ip link set dev qg-i netns router
ip link set dev qg-e netns router
ip netns exec router ifconfig qr-0-1 192.168.0.1/24 up
ip netns exec router ifconfig qr-1-1 192.168.1.1/24 up
ip netns exec router ifconfig qg-e 172.16.0.1/24 up
ip netns exec router ifconfig qg-i 172.16.1.1/24 up
ip netns exec router ifconfig lo up
# 设置网关和arp
ip netns exec src ip ro add default via 192.168.0.1
ip netns exec dst ip ro add default via 192.168.1.1
ip netns exec router arp -s 172.16.0.2 <MAC>
- 在
router
namespace中并配置PBR
- 从
qr-0-1
进来的流量,下一跳为nf-in的IP - 从
qr-1-1
进来的流量,下一跳为nf-in的IP
# 开启linux内核转发
ip netns exec router sysctl -w net.ipv4.ip_forward=1
# 创建pbr路由表
echo "1 pbr" >> /etc/iproute2/rt_tables
ip netns exec router ip ro add default via 172.16.0.2 table pbr
# 第一条策略路由
ip netns exec router ip ru add from all iif qr-0-1 table pbr
# 第二条策略路由
ip netns exec router ip ru add from all iif qr-1-1 table pbr
II. BMF service-node
- 环境准备:使用裸机安装CentOS 7发行版,除管理口外还要UP两个口
nf-in nf-out
(根据自己设备指定值,如em2 eth2
等),将两个口接入BMF,配置好Policy
# 开启linux内核转发
sysctl -w net.ipv4.ip_forward=1
# UP两块网卡,并配置IP地址
ifconfig nf-in 172.16.0.2/24 up
ifconfig ne-out 172.16.1.2/24 up
- 配置PBR
- 从
nf-in
进来的流量,下一跳为qg-i的IP
注 要配置
qg-i
的静态arp
# 开启linux内核转发
sysctl -w net.ipv4.ip_forward=1
# 创建pbr路由表
echo "1 pbr" >> /etc/iproute2/rt_tables
ip ro add default via 172.16.1.1 table pbr
# 第一条策略路由
ip ru add from all iif nf-in table pbr
# 添加静态arp
arp -s 172.16.1.1 <MAC>
实验环境下流量走向
- pbr-router的
src
namespace发送向dst
的请求报文,会根据namespace中配置的默认路由经由src-port
到达qr-0-1
-
qr-0-1
收到的请求报文命中PBR,知道下一跳为nf-in
,于是从qg-e
发出,在ovs内部经由patch
口到达br-egress
,最终由egress
物理口发出,达到BMF中的nf-in
-
nf-in
收到的请求报文命中PBR,知道下一跳为qg-i
,于是从nf-out
发出,穿过BMF到达ingress
物理口,在ovs内部经由patch
口到达qg-i
-
qg-i
收到的请求未命中PBR,因此走默认路由,于是从qr-1-1
发出,经由dst-port
到达dst
-
dst
发送的报文流向与src
的请求报文是相似的,不再赘述
问题及解决方案
- service-node数据包未能转发,策略路由不生效
答:这是由Linux内置的“反向路由过滤”功能引起的。它是Linux利用反向路由查询防止IP地址欺骗攻击的策略。通过检查收到的数据包源IP是否可路由决定是否丢弃数据包。详见这篇文章
解决办法是关闭配置了策略路由的网口的反向路由过滤功能
# service-node
sysctl -w net.ipv4.conf.nf-in.rp_filter=0
# pbr-router
ip netns exec router sysctl -w net.ipv4.conf.qg-i.rp_filter=0