【注】
Security Group在openstack中起到很重要的作用,它直接保护租户的vm。但不恰当的配置也容易导致各种莫名其妙的问题。
理解Security Group的实现,有助于理解OpenStack的设计理念和解决各种网络问题。
最新版pdf也可以从这里下载。
--------------------------------------------------------------------------------
Security group的实现,目前是放在qbr***这样的Linux传统bridge上的,是基于iptables服务。
首先在控制节点上用neutron port-list命令列出虚拟机的端口id,例如:
# neutron port-list
+--------------------------------------+------+-------------------+----------------------------------------------------------------------------------------+
| id | name | mac_address | fixed_ips |
+--------------------------------------+------+-------------------+----------------------------------------------------------------------------------------+
| 2a169bb4-4d8b-4c67-802c-a24bdafe1312 | | fa:16:3e:2f:e9:72 | {"subnet_id": "a2456a2c-5eea-416d-8757-d10bc0aa2aaa", "ip_address": "192.168.0.1"} |
| 583c7038-d341-41ec-a0d1-0cd2c33866ca | | fa:16:3e:9c:dc:3a | {"subnet_id": "a2456a2c-5eea-416d-8757-d10bc0aa2aaa", "ip_address": "192.168.0.2"} |
| 9b2db4ac-3145-401c-8dc6-486ca6e303b6 | | fa:16:3e:4e:f1:b5 | {"subnet_id": "ea4ed31b-e05a-4735-8c3f-9b430e656b64", "ip_address": "192.168.122.200"} |
| c5a7d51b-9934-40bd-befa-adff840462d2 | | fa:16:3e:21:1d:00 | {"subnet_id": "ea4ed31b-e05a-4735-8c3f-9b430e656b64", "ip_address": "192.168.122.201"} |
| db2f5a49-7c0d-45dd-acad-908931f9a654 | | fa:16:3e:17:5c:36 | {"subnet_id": "a2456a2c-5eea-416d-8757-d10bc0aa2aaa", "ip_address": "192.168.0.3"} |
+--------------------------------------+------+-------------------+----------------------------------------------------------------------------------------+
其中id的前10位数字被用作虚机对外连接的qbr(同时也是tap口)的id。i或o加上前9位数字被用作安全组chain的id。
所有的规则默认都在filter表(默认表)中实现,分别来查看filter表的INPUT、OUTPUT、FORWARD三条链上的规则。
在计算节点上,可以用iptables --line-numbers -vnL [CHAIN]来获得filter表(可以指定某个链上的)规则。
#iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 360K 56M neutron-openvswi-INPUT all -- * * 0.0.0.0/0 0.0.0.0/0
2 10583 2146K ACCEPT tcp -- * * 192.168.122.100 0.0.0.0/0 multiport dports 5666 /* 001 nagios-nrpe incoming 192.168.122.100 */
3 846 50966 ACCEPT tcp -- * * 192.168.122.100 0.0.0.0/0 multiport dports 5900:5999 /* 001 nova compute incoming 192.168.122.100 */
4 1033K 894M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
5 760 63840 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
6 1 60 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
7 977 58620 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
8 3899 1194K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
可以看到,跟安全组相关的规则被重定向到neutron-openvswi-INPUT。
查看其规则,只有一条。
#iptables --line-numbers -vnL neutron-openvswi-INPUT
Chain neutron-openvswi-INPUT (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 neutron-openvswi-o583c7038-d all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in tap583c7038-d3 --physdev-is-bridged
重定向到neutron-openvswi-o583c7038-d。
#iptables --line-numbers -vnL neutron-openvswi-o583c7038-d
Chain neutron-openvswi-o583c7038-d (2 references)
num pkts bytes target prot opt in out source destination
1 3894 1199K RETURN udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:68 dpt:67
2 4282 1536K neutron-openvswi-s583c7038-d all -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68
4 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
5 3971 1510K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
6 311 25752 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
7 0 0 neutron-openvswi-sg-fallback all -- * * 0.0.0.0/0 0.0.0.0/0
如果是vm发出的dhcp请求,直接通过,否则转到neutron-openvswi-s583c7038-d。
#iptables --line-numbers -vnL neutron-openvswi-s583c7038-d
Chain neutron-openvswi-s583c7038-d (1 references)
num pkts bytes target prot opt in out source destination
1 4284 1537K RETURN all -- * * 192.168.0.2 0.0.0.0/0 MAC FA:16:3E:9C:DC:3A
2 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
这条chain主要检查从vm发出来的网包,是否是openstack所分配的IP和MAC,如果不匹配,则禁止通过。这将防止利用vm上进行一些伪装地址的攻击。
#iptables --line-numbers -vnLables --line-numbers -vnL OUTPUT
Chain OUTPUT (policy ACCEPT 965K packets, 149M bytes)
num pkts bytes target prot opt in out source destination
1 481K 107M neutron-filter-top all -- * * 0.0.0.0/0 0.0.0.0/0
2 481K 107M neutron-openvswi-OUTPUT all -- * * 0.0.0.0/0 0.0.0.0/0
分别跳转到neutron-filter-top和neutron-openvswi-OUTPUT。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-filter-top
Chain neutron-filter-top (2 references)
num pkts bytes target prot opt in out source destination
1 497K 112M neutron-openvswi-local all -- * * 0.0.0.0/0 0.0.0.0/0
跳转到neutron-openvswi-local。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-OUTPUT
Chain neutron-openvswi-OUTPUT (1 references)
num pkts bytes target prot opt in out source destination
该chain目前无规则。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-local
Chain neutron-openvswi-local (1 references)
num pkts bytes target prot opt in out source destination
该chain目前也无规则。
FORWARD chain上主要实现安全组的功能。用户在配置缺省安全规则时候(例如允许ssh到vm,允许ping到vm),影响该chain。
#iptables --line-numbers -vnLables --line-numbers -vnL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 16203 5342K neutron-filter-top all -- * * 0.0.0.0/0 0.0.0.0/0
2 16203 5342K neutron-openvswi-FORWARD all -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
同样跳转到neutron-filter-top,无规则。跳转到neutron-openvswi-FORWARD。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-FORWARD
Chain neutron-openvswi-FORWARD (1 references)
num pkts bytes target prot opt in out source destination
1 8170 2630K neutron-openvswi-sg-chain all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out tap583c7038-d3 --physdev-is-bridged
2 8156 2729K neutron-openvswi-sg-chain all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in tap583c7038-d3 --physdev-is-bridged
neutron-openvswi-FORWARD将匹配所有进出tap-XXX端口的流量。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-sg-chain
Chain neutron-openvswi-sg-chain (2 references)
num pkts bytes target prot opt in out source destination
1 8170 2630K neutron-openvswi-i583c7038-d all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-out tap583c7038-d3 --physdev-is-bridged
2 8156 2729K neutron-openvswi-o583c7038-d all -- * * 0.0.0.0/0 0.0.0.0/0 PHYSDEV match --physdev-in tap583c7038-d3 --physdev-is-bridged
3 12442 4163K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
如果是网桥从tap-XXX端口发出到VM的流量,则跳转到neutron-openvswi-i9LETTERID;如果是从tap-XXX端口进入到网桥的(即vm发出来的)流量,则跳转到neutron-openvswi-o9LETTERID。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-i583c7038-d
Chain neutron-openvswi-i583c7038-d (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
2 400 43350 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 1 60 RETURN tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
4 1 84 RETURN icmp -- * * 0.0.0.0/0 0.0.0.0/0
5 3885 1391K RETURN udp -- * * 192.168.0.3 0.0.0.0/0 udp spt:67 dpt:68
6 3885 1197K neutron-openvswi-sg-fallback all -- * * 0.0.0.0/0 0.0.0.0/0
neutron-openvswi-i9LETTERID允许安全组中配置的策略(允许ssh、ping等)和dhcp reply通过。默认的neutron-openvswi-sg-fallback将drop所有流量。
#iptables --line-numbers -vnLables --line-numbers -vnL neutron-openvswi-o583c7038-d
Chain neutron-openvswi-o583c7038-d (2 references)
num pkts bytes target prot opt in out source destination
1 3886 1197K RETURN udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:68 dpt:67
2 4274 1533K neutron-openvswi-s583c7038-d all -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:67 dpt:68
4 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
5 3963 1507K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
6 311 25752 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
7 0 0 neutron-openvswi-sg-fallback all -- * * 0.0.0.0/0 0.0.0.0/0
neutron-openvswi-o9LETTERID将跳转到neutron-openvswi-s583c7038-d,允许DHCP Request和匹配VM的源IP和源MAC的流量通过。
整体逻辑如图表所示。
图表 OpenStack中相关iptables规则的整体逻辑
从前面分析可以看出,某个vm的安全组相关规则的chain的名字,跟vm的id的前9个字符有关。
因此,要快速查找qbr-XXX上相关的iptables规则,可以用iptables -S列出(默认是filter表)所有链上的规则,其中含有id的链即为虚拟机相关的安全组规则。其中--physdev-in表示即将进入某个网桥的端口,--physdev-out表示即将从某个网桥端口发出。
#iptables -S |grep tap583c7038-d3
-A neutron-openvswi-FORWARD -m physdev --physdev-out tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-sg-chain
-A neutron-openvswi-FORWARD -m physdev --physdev-in tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-sg-chain
-A neutron-openvswi-INPUT -m physdev --physdev-in tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-o583c7038-d
-A neutron-openvswi-sg-chain -m physdev --physdev-out tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-i583c7038-d
-A neutron-openvswi-sg-chain -m physdev --physdev-in tap583c7038-d3 --physdev-is-bridged -j neutron-openvswi-o583c7038-d
可以看出,进出tap-XXX口的FORWARD链上的流量都被扔到了neutron-openvswi-sg-chain这个链,neutron-openvswi-sg-chain上是security group具体的实现(两条规则,访问虚拟机的流量扔给neutron-openvswi-i583c7038-d;从虚拟机出来的扔给neutron-openvswi-o583c7038-d)。