OpenStack 安全组原理详解
本文目录
1. 安全组和防火墙区别
安全组(security group)
主要是用主机防护,针对每一个 port 做网络访问控制,所以它更像是一个主机防火墙。
security group定义的是允许通过的规则集合,即规则的动作就是ACCEPT。
换句话说定义的是白名单规则,因此如果虚拟机关联的是一个空规则安全组,则虚拟机既出不去也进不来。并且由于都是白名单规则,因此安全组规则顺序是无所谓的,而且一个虚拟机port可以同时关联多个安全组,此时相当于规则集合的并集。
防火墙(firewall)
主要是做 VPC 防护,针对整个 VPC 网络做网络访问控制,通常是在 Router 上做配置。
firewall规则是有动作的(allow,deny,reject),由于规则既可以是ACCEPT,也可以是DROP,因此先后顺序则非常重要,一个包的命运,不仅取决于规则,还取决于规则的优先级顺序。
2. 安全组开启
在 /etc/neutron/plugins/ml2/openvswitch_agent.ini
配置文件中,取消如下注释
firewall_driver =openvswitch
然后确保 port 开启安全组 (查看 port_security_enabled
要为 True)
# 开启安全组
neutron port-update --enable-port-security [port_id] neutron port-update --security-group [security_group_id] [port_id]
# 关闭安全组
neutron port-update --disable-port-security [port_id] neutron port-update --no-security-group [port_id]
上面的 security_group_id
需要你提前创建安全组。
# 创建安全组
neutron security-group-create --tenant-id [tenant_id] [NAME]
# 创建规则,绑定到安全组 neutron security-group-rule-create --direction ingress --protocol icmp --remote-ip-prefix 172.20.50.10 [sg_id]
安全组规则创建出来,默认的 policy 是 drop,priority 是 70。
3. 安全组规则创建
Neutron 通过security-group-create
子命令创建安全组,参数只有一个name
,即安全组名称
$ neutron security-group-create [sg_name]
Neutron 创建的新安全组并不是一个空规则安全组,而是会自动添加两条默认规则:即禁止所有的流量访问,允许所有的流量出去。
$ neutron security-group-rule-list
-F security_group \
-F ethertype \
-F remote \
-F port/protocol \
-F direction \
| grep int32bit-test-secgroup-1
| sg_name | egress| IPv6| any| any|
| sg_name | egress| IPv4| any| any|
创建了安全组后,就可以往安全组里面加规则了。Neutron 通过security-group-rule-create
子命令创建,涉及的参数如下:
--direction
: 该规则是出访(egress)还是入访(ingress)。--ethertype
: 以太网类型,ipv4或者ipv6。--protocol
: 协议类型,tcp/udp/icmp等。不指定该参数则表示任意协议。--port-range-min
、--port-range-max
端口范围,如果只有一个端口,则两个参数填一样即可,端口范围为1~65535。--remote-ip-prefix
,如果是入访则指的是源IP地址段,如果是出访则指的是目标IP段,通过CIDR格式定义,如果只指定一个IP,通过x.x.x.x/32
指定,如果是任意IP,则通过0.0.0.0/0
指定。--remote-group-id
: 除了通过ip段指定规则,OpenStack还支持通过安全组作为匹配条件,比如允许关联了xyz安全组的所有虚拟机访问22端口。
4. 防火墙驱动
在 安全组开启
那节,有配置了 firewall_driver
为 openvswitch
。
[securitygroup]
firewall_driver =openvswitch
firewall_driver 的值的可选项:iptables 和 openvswitch
当你创建安全组并配置规则后:
- 若使用的是 iptables ,那么是通过 iptables 规则来实现流量数据包的过滤。
- 若使用的是 openvswitch,那么是通过 ovs 流表规则 来实现流量数据包的过滤。
为什么使用 openvswitch
而不使用 iptables
?
因为 iptables 不能直接使用在 ovs 网桥上,所以要新建 linuxbridge 网桥,然后用 veth pair 连接两个网桥。
它的模型构架如下,会在 br-int 和 vm 之间创建一个 linuxbridge 网桥。
而使用 openvswitch,就不用创建 linuxbridge, VM 就可以直接接在 br-int 上,免去了之前的
种种转发环节,性能会得到明显的提高。
5. OVS 流表逻辑
使用如下命令,在虚拟机所在的宿主机上执行,可以查看 ovs 流表。
$ ovs-ofctl dump-flows br-int
OVS 流表的逻辑:
- 不管是出方向还是入方向,都是先经过 table = 0 的表,后面再经过哪个表,由流表的resubmit 动作来转发
- 同一张表里,先经过优先级(priority)比较高的流表,再经过优先级较低的流表
- 一旦经过并匹配 actions = NORMAL 的流表,就会跳出流表的筛选过滤。
- 一旦经过并匹配 actions = drop 的流表,数据包就会被丢弃。
6. OVS 命令
查看 dp 的id
$ ovs-appctl dpif/show
查看 ofport – port – mac – vm_id 对应关系
$ ovsdb-client dump Interface name ofport external_ids
查看 pmd 线程绑定在哪个核上
$ ovs-appctl dpif-netdev/pmd-rxq-show | grep "thread numa_id"