centos ovn 搭建测试(五:ACL)
ACL 功能测试
priority
指定acl规则的优先级,值越大优先级越高。如果匹配到的多条规则优先级相同,最终哪条规则生效是不确定的。direction
指定报文的方向,只有两个值: from-lport和to-lport。前者表示入方向,后者表示出方向,这是在逻辑交换机的角度来说的。match
用来指定报文匹配域,具体的表达式规则可参考sbdb中 logical_flow table的match列。注意:类型为localnet和router的端口上不能应用acl规则。action
对于匹配到规则的报文的处理,目前支持四个值:allow, allow-related, drop, or reject。- allow: 表示允许报文通过;
- allow-related:表示允许报文和其响应报文通过;
- drop:静默丢弃报文;
- reject:丢弃报文,并回复报文。对于tcp协议报文,回复rst,对于其他类型的报文,回复ICMPv4/ICMPv6 unreachable。
# 所有ovn-nbctl操作都在ovn-master节点上执行
# 创建2个逻辑交换机及port
# 创建logical switch ovn-nbctl ls-add ls1 ovn-nbctl ls-add ls2 # 创建 logical port ls1-veth1 ovn-nbctl lsp-add ls1 ls1-veth1 ovn-nbctl lsp-set-addresses ls1-veth1 "aa:aa:aa:11:11:aa 1.1.1.100" # 创建 logical port ls1-veth3 ovn-nbctl lsp-add ls1 ls1-veth3 ovn-nbctl lsp-set-addresses ls1-veth3 "aa:aa:aa:11:11:bb 1.1.1.200" # 创建 logical port ls2-veth5 ovn-nbctl lsp-add ls2 ls2-veth5 ovn-nbctl lsp-set-addresses ls2-veth5 "aa:aa:aa:22:22:aa 2.1.1.100" # 创建 logical port ls2-veth7 ovn-nbctl lsp-add ls2 ls2-veth7 ovn-nbctl lsp-set-addresses ls2-veth7 "aa:aa:aa:22:22:bb 2.1.1.200"
# 创建逻辑路由器及port
# 创建逻辑路由器 ovn-nbctl lr-add lr # 创建逻辑路由器port ovn-nbctl lrp-add lr lr1-port 00:00:00:00:10:00 1.1.1.1/24 # 创建逻辑交换机port并关联路由器port ovn-nbctl lsp-add ls1 ls1-port ovn-nbctl lsp-set-type ls1-port router ovn-nbctl lsp-set-addresses ls1-port "00:00:00:00:10:00 1.1.1.1" ovn-nbctl lsp-set-options ls1-port router-port=lr1-port # 创建逻辑路由器port ovn-nbctl lrp-add lr lr2-port 00:00:00:00:20:00 2.1.1.1/24 # 创建逻辑交换机port并关联路由器port ovn-nbctl lsp-add ls2 ls2-port ovn-nbctl lsp-set-type ls2-port router ovn-nbctl lsp-set-addresses ls2-port "00:00:00:00:20:00 2.1.1.1" ovn-nbctl lsp-set-options ls2-port router-port=lr2-port
# 配置网络命名空间
# ovn-master: ip netns add ns1 ip link add veth1 type veth peer name veth2 ifconfig veth1 up ifconfig veth2 up ip link set veth2 netns ns1 ip netns exec ns1 ip link set veth2 address aa:aa:aa:11:11:aa ip netns exec ns1 ip addr add 1.1.1.100/24 dev veth2 ip netns exec ns1 ip link set veth2 up ip netns exec ns1 ip r add default via 1.1.1.1 ovs-vsctl add-port br-int veth1 ovs-vsctl set Interface veth1 external_ids:iface-id=ls1-veth1 ip netns exec ns1 ip addr show # ovn-master: ip netns add ns2 ip link add veth3 type veth peer name veth4 ifconfig veth3 up ifconfig veth4 up ip link set veth4 netns ns2 ip netns exec ns2 ip link set veth4 address aa:aa:aa:11:11:bb ip netns exec ns2 ip addr add 1.1.1.200/24 dev veth4 ip netns exec ns2 ip link set veth4 up ip netns exec ns2 ip r add default via 1.1.1.1 ovs-vsctl add-port br-int veth3 ovs-vsctl set Interface veth3 external_ids:iface-id=ls1-veth3 ip netns exec ns2 ip addr show # ovn-node1: ip netns add ns3 ip link add veth5 type veth peer name veth6 ifconfig veth5 up ifconfig veth6 up ip link set veth6 netns ns3 ip netns exec ns3 ip link set veth6 address aa:aa:aa:22:22:aa ip netns exec ns3 ip addr add 2.1.1.100/24 dev veth6 ip netns exec ns3 ip link set veth6 up ip netns exec ns3 ip r add default via 2.1.1.1 ovs-vsctl add-port br-int veth5 ovs-vsctl set Interface veth5 external_ids:iface-id=ls2-veth5 ip netns exec ns3 ip addr show # ovn-node1: ip netns add ns4 ip link add veth7 type veth peer name veth8 ifconfig veth7 up ifconfig veth8 up ip link set veth8 netns ns4 ip netns exec ns4 ip link set veth8 address aa:aa:aa:22:22:bb ip netns exec ns4 ip addr add 2.1.1.200/24 dev veth8 ip netns exec ns4 ip link set veth8 up ip netns exec ns4 ip r add default via 2.1.1.1 ovs-vsctl add-port br-int veth7 ovs-vsctl set Interface veth7 external_ids:iface-id=ls2-veth7 ip netns exec ns4 ip addr show
# 查看配置
[root@ovn-master ~]# ovn-nbctl show switch bfeecb70-d36e-479a-9050-567c40d5fe2b (ls1) port ls1-veth3 addresses: ["aa:aa:aa:11:11:bb 1.1.1.200"] port ls1-port type: router addresses: ["00:00:00:00:10:00 1.1.1.1"] router-port: lr1-port port ls1-veth1 addresses: ["aa:aa:aa:11:11:aa 1.1.1.100"] switch 8f43cfaf-ce6b-48f9-a0f3-9bc3104c1feb (ls2) port ls2-veth7 addresses: ["aa:aa:aa:22:22:bb 2.1.1.200"] port ls2-veth5 addresses: ["aa:aa:aa:22:22:aa 2.1.1.100"] port ls2-port type: router addresses: ["00:00:00:00:20:00 2.1.1.1"] router-port: lr2-port router 4e7e7acc-9cbc-4be8-b1db-f8003a20b6ec (lr) port lr1-port mac: "00:00:00:00:10:00" networks: ["1.1.1.1/24"] port lr2-port mac: "00:00:00:00:20:00" networks: ["2.1.1.1/24"]
# 测试连通性
# ns1 ping ns2 [root@ovn-master ~]# ip netns exec ns1 ping 1.1.1.200 PING 1.1.1.200 (1.1.1.200) 56(84) bytes of data. 64 bytes from 1.1.1.200: icmp_seq=1 ttl=64 time=0.397 ms 64 bytes from 1.1.1.200: icmp_seq=2 ttl=64 time=0.054 ms # ns1 ping ns3 [root@ovn-master ~]# ip netns exec ns1 ping 2.1.1.100 PING 2.1.1.100 (2.1.1.100) 56(84) bytes of data. 64 bytes from 2.1.1.100: icmp_seq=1 ttl=63 time=13.5 ms 64 bytes from 2.1.1.100: icmp_seq=2 ttl=63 time=0.290 ms # ns1 ping ns4 [root@ovn-master ~]# ip netns exec ns1 ping 2.1.1.200 PING 2.1.1.200 (2.1.1.200) 56(84) bytes of data. 64 bytes from 2.1.1.200: icmp_seq=1 ttl=63 time=1.03 ms 64 bytes from 2.1.1.200: icmp_seq=2 ttl=63 time=0.274 ms
# ls1 的 ns1 上启动web服务
# ovn-master 节点上执行
rm /tmp/www -rf mkdir -p /tmp/www echo "i am ns1" > /tmp/www/index.html cd /tmp/www ip netns exec ns1 python -m SimpleHTTPServer 8000
# 服务连通性验证
# 客户端 [root@ovn-node1 ~]# ip netns exec ns3 curl 1.1.1.100:8000 i am ns1 [root@ovn-node1 ~]# ip netns exec ns4 curl 1.1.1.100:8000 i am ns1 # 服务端 [root@ovn-master www]# ip netns exec ns1 python -m SimpleHTTPServer 8000 Serving HTTP on 0.0.0.0 port 8000 ... 1.1.1.200 - - [22/Jul/2022 14:09:34] "GET / HTTP/1.1" 200 - 2.1.1.100 - - [22/Jul/2022 14:09:46] "GET / HTTP/1.1" 200 - 2.1.1.200 - - [22/Jul/2022 14:09:50] "GET / HTTP/1.1" 200 -
# 配置ACL
# 从ls1-ns1发出和发往ls1-vm1的ip报文默认drop
ovn-nbctl acl-add ls1 to-lport 0 'outport == "ls1-veth1" && ip' drop ovn-nbctl acl-add ls1 from-lport 0 'inport == "ls1-veth1" && ip' drop
# 配置验证
# 客户端 [root@ovn-node1 ~]# ip netns exec ns3 curl 1.1.1.100:8000 curl: (7) Failed connect to 1.1.1.100:8000; Connection timed out [root@ovn-node1 ~]# ip netns exec ns4 curl 1.1.1.100:8000 curl: (7) Failed connect to 1.1.1.100:8000; Connection timed out # 服务端 [root@ovn-master ~]# ip netns exec ns2 curl 1.1.1.100:8000 curl: (7) Failed connect to 1.1.1.100:8000; Connection timed out
# 再添加一个acl规则,使ls2上的两个ns可以访问web服务
//只允许 2.1.1.0/24 网段的ip访问8000服务,优先级是1000 ovn-nbctl acl-add ls1 to-lport 1000 'outport == "ls1-veth1" && ip4.src == 2.1.1.0/24 && tcp.dst == 8000' allow-related
# 配置验证
# 客户端 [root@ovn-node1 ~]# ip netns exec ns4 curl 1.1.1.100:8000 i am ns1 [root@ovn-node1 ~]# ip netns exec ns3 curl 1.1.1.100:8000 i am ns1 #服务端 [root@ovn-master ~]# ip netns exec ns2 curl 1.1.1.100:8000 curl: (7) Failed connect to 1.1.1.100:8000; Connection timed out
# 查看ovn配置
[root@ovn-master ~]# ovn-nbctl acl-list ls1 from-lport 0 (inport == "ls1-veth1" && ip) drop to-lport 1000 (outport == "ls1-veth1" && ip4.src == 2.1.1.0/24 && tcp.dst == 8000) allow-related to-lport 0 (outport == "ls1-veth1" && ip) drop
# IP地址集
# 创建ip地址集合 ovn-nbctl create Address_Set name=ns_2_ipset addresses='2.1.1.100 2.1.1.200'
# 使用地址集,允许地址集中的ns1访问8000端口 ovn-nbctl acl-add ls1 to-lport 1000 'outport == "ls1-veth1" && ip4.src == $ns_2_ipset && tcp.dst == 8000' allow-related
# ovn-trace 分析路径
[root@ovn-master ~]# ovn-trace --detailed ls2 'inport == "ls2-veth5" && eth.src == aa:aa:aa:22:22:aa && ip4.src == 1.1.1.100 && eth.dst == 00:00:00:00:20:00 && ip4.dst == 1.1.1.100 && ip.ttl == 64 && tcp.dst == 8000' # tcp,reg14=0x1,vlan_tci=0x0000,dl_src=aa:aa:aa:22:22:aa,dl_dst=00:00:00:00:20:00,nw_src=1.1.1.100,nw_dst=1.1.1.100,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=8000,tcp_flags=0 ingress(dp="ls2", inport="ls2-veth5") ------------------------------------- 0. ls_in_port_sec_l2 (ovn-northd.c:4843): inport == "ls2-veth5", priority 50, uuid 877f3ea4 next; 17. ls_in_l2_lkup (ovn-northd.c:5359): eth.dst == 00:00:00:00:20:00, priority 50, uuid 07a8ee8b outport = "ls2-port"; output; egress(dp="ls2", inport="ls2-veth5", outport="ls2-port") -------------------------------------------------------- 9. ls_out_port_sec_l2 (ovn-northd.c:5503): outport == "ls2-port", priority 50, uuid ed4afe28 output; /* output to "ls2-port", type "patch" */ ingress(dp="lr", inport="lr2-port") ----------------------------------- 0. lr_in_admission (ovn-northd.c:6198): eth.dst == 00:00:00:00:20:00 && inport == "lr2-port", priority 50, uuid cf473857 next; 7. lr_in_ip_routing (ovn-northd.c:5780): ip4.dst == 1.1.1.0/24, priority 49, uuid 276dff8e ip.ttl--; reg0 = ip4.dst; reg1 = 1.1.1.1; eth.src = 00:00:00:00:10:00; outport = "lr1-port"; flags.loopback = 1; next; 9. lr_in_arp_resolve (ovn-northd.c:7604): outport == "lr1-port" && reg0 == 1.1.1.100, priority 100, uuid ab03db9c eth.dst = aa:aa:aa:11:11:aa; next; 13. lr_in_arp_request (ovn-northd.c:8001): 1, priority 0, uuid 2cfce45d output; egress(dp="lr", inport="lr2-port", outport="lr1-port") ------------------------------------------------------ 3. lr_out_delivery (ovn-northd.c:8029): outport == "lr1-port", priority 100, uuid 1c2b5b49 output; /* output to "lr1-port", type "patch" */ ingress(dp="ls1", inport="ls1-port") ------------------------------------ 0. ls_in_port_sec_l2 (ovn-northd.c:4843): inport == "ls1-port", priority 50, uuid 274ef440 next; 3. ls_in_pre_acl (ovn-northd.c:3792): ip && inport == "ls1-port", priority 110, uuid c2e9cf28 next; 17. ls_in_l2_lkup (ovn-northd.c:5359): eth.dst == aa:aa:aa:11:11:aa, priority 50, uuid 0076e76a outport = "ls1-veth1"; output; egress(dp="ls1", inport="ls1-port", outport="ls1-veth1") -------------------------------------------------------- 1. ls_out_pre_acl (ovn-northd.c:3840): ip, priority 100, uuid 72de04cf reg0[0] = 1; next; 2. ls_out_pre_stateful (ovn-northd.c:3994): reg0[0] == 1, priority 100, uuid c315944a ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 4. ls_out_acl (ovn-northd.c:4233): ct.est && ct_label.blocked == 0 && (outport == "ls1-veth1" && ip), priority 1000, uuid 1902fe24 ct_commit(ct_label=0x1/0x1);
# 访问不存在的目的IP(1.1.1.101 不存在该地址)
[root@ovn-master ~]# ovn-trace --detailed ls2 'inport == "ls2-veth5" && eth.src == aa:aa:aa:22:22:aa && ip4.src == 1.1.1.100 && eth.dst == 00:00:00:00:20:00 && ip4.dst == 1.1.1.101 && ip.ttl == 64 && tcp.dst == 8000' # tcp,reg14=0x1,vlan_tci=0x0000,dl_src=aa:aa:aa:22:22:aa,dl_dst=00:00:00:00:20:00,nw_src=1.1.1.100,nw_dst=1.1.1.101,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=8000,tcp_flags=0 ingress(dp="ls2", inport="ls2-veth5") ------------------------------------- 0. ls_in_port_sec_l2 (ovn-northd.c:4843): inport == "ls2-veth5", priority 50, uuid 877f3ea4 next; 17. ls_in_l2_lkup (ovn-northd.c:5359): eth.dst == 00:00:00:00:20:00, priority 50, uuid 07a8ee8b outport = "ls2-port"; output; egress(dp="ls2", inport="ls2-veth5", outport="ls2-port") -------------------------------------------------------- 9. ls_out_port_sec_l2 (ovn-northd.c:5503): outport == "ls2-port", priority 50, uuid ed4afe28 output; /* output to "ls2-port", type "patch" */ ingress(dp="lr", inport="lr2-port") ----------------------------------- 0. lr_in_admission (ovn-northd.c:6198): eth.dst == 00:00:00:00:20:00 && inport == "lr2-port", priority 50, uuid cf473857 next; 7. lr_in_ip_routing (ovn-northd.c:5780): ip4.dst == 1.1.1.0/24, priority 49, uuid 276dff8e ip.ttl--; reg0 = ip4.dst; reg1 = 1.1.1.1; eth.src = 00:00:00:00:10:00; outport = "lr1-port"; flags.loopback = 1; next; 9. lr_in_arp_resolve (ovn-northd.c:7810): ip4, priority 0, uuid 93842144 get_arp(outport, reg0); /* No MAC binding. */ next; 13. lr_in_arp_request (ovn-northd.c:7994): eth.dst == 00:00:00:00:00:00, priority 100, uuid 170af9dc arp { eth.dst = ff:ff:ff:ff:ff:ff; arp.spa = reg1; arp.tpa = reg0; arp.op = 1; output; }; arp --- eth.dst = ff:ff:ff:ff:ff:ff; arp.spa = reg1; arp.tpa = reg0; arp.op = 1; output; egress(dp="lr", inport="lr2-port", outport="lr1-port") ------------------------------------------------------ 3. lr_out_delivery (ovn-northd.c:8029): outport == "lr1-port", priority 100, uuid 1c2b5b49 output; /* output to "lr1-port", type "patch" */ ingress(dp="ls1", inport="ls1-port") ------------------------------------ 0. ls_in_port_sec_l2 (ovn-northd.c:4843): inport == "ls1-port", priority 50, uuid 274ef440 next; 17. ls_in_l2_lkup (ovn-northd.c:5308): eth.mcast, priority 70, uuid ca982bea outport = "_MC_flood"; output; multicast(dp="ls1", mcgroup="_MC_flood") // ls1 所有端口进行arp泛洪 ---------------------------------------- egress(dp="ls1", inport="ls1-port", outport="ls1-port") ------------------------------------------------------- /* omitting output because inport == outport && !flags.loopback */ egress(dp="ls1", inport="ls1-port", outport="ls1-veth1") -------------------------------------------------------- 9. ls_out_port_sec_l2 (ovn-northd.c:5480): eth.mcast, priority 100, uuid 53fe8403 output; /* output to "ls1-veth1", type "" */ egress(dp="ls1", inport="ls1-port", outport="ls1-veth3") -------------------------------------------------------- 9. ls_out_port_sec_l2 (ovn-northd.c:5480): eth.mcast, priority 100, uuid 53fe8403 output; /* output to "ls1-veth3", type "" */