因为项目有一个新的需求,需要修改openstack中每次新建租户后的默认安全组规则。
首先先来分析一下:
我用的openstack版本为queens。每次新建租户后本来是没有安全组的,当使用新租户第一次访问dashboard的安全组列表或者调用API时,openstack会自动的为该租户创建一个default安全组,有4条规则。如图
大意就是
1)允许使用该安全组的虚拟机向外部发送一切数据包。
2)阻止所有外部的数据包到达使用该安全组的虚拟机(来自于同一个default安全组的主机的数据包除外)。
我的目标是增加两条安全组规则,①允许外部所有TCP包访问虚拟机 ②允许外部ping虚拟机。
实现这个功能需要修改源代码,非常简单。
直接修改源码,路径为/usr/lib/python2.7/site-packages/neutron/db/securitygroups_db.py,寻找方法create_security_group,源码实现如下:
def create_security_group(self, context, security_group, default_sg=False):
#前面的创建安全组逻辑省略
#重点是下面的创建安全组规则逻辑
for ethertype in ext_sg.sg_supported_ethertypes:
if default_sg:
# Allow intercommunication
ingress_rule = sg_obj.SecurityGroupRule(
context, id=uuidutils.generate_uuid(),
project_id=tenant_id, security_group_id=sg.id,
direction='ingress', ethertype=ethertype,
remote_group_id=sg.id)
ingress_rule.create()
sg.rules.append(ingress_rule)
egress_rule = sg_obj.SecurityGroupRule(
context, id=uuidutils.generate_uuid(),
project_id=tenant_id, security_group_id=sg.id,
direction='egress', ethertype=ethertype)
egress_rule.create()
sg.rules.append(egress_rule)
sg.obj_reset_changes(['rules'])
#后面的通知广播逻辑省略
在这里的代码后面添加自己需要的安全组规则即可实现,修改后代码如下:
def create_security_group(self, context, security_group, default_sg=False):
# 前置逻辑省略
for ethertype in ext_sg.sg_supported_ethertypes:
if default_sg:
# Allow intercommunication
ingress_rule = sg_obj.SecurityGroupRule(
context, id=uuidutils.generate_uuid(),
project_id=tenant_id, security_group_id=sg.id,
direction='ingress', ethertype=ethertype,
remote_group_id=sg.id)
ingress_rule.create()
sg.rules.append(ingress_rule)
egress_rule = sg_obj.SecurityGroupRule(
context, id=uuidutils.generate_uuid(),
project_id=tenant_id, security_group_id=sg.id,
direction='egress', ethertype=ethertype)
egress_rule.create()
sg.rules.append(egress_rule)
#################### 自定义安全规则逻辑 start ####################
#remote_ip_prefix定义了允许远端访问的IP地址段,0.0.0.0/0代表所有IP
remote_ip_prefix = utils.AuthenticIPNetwork('0.0.0.0/0')
#第一条规则,表示允许所有icmp协议访问安全组内部,即允许ping
ingress_rule_1 = sg_obj.SecurityGroupRule(
context, id=uuidutils.generate_uuid(),
project_id=tenant_id, security_group_id=sg.id,
direction='ingress', ethertype='IPv4',
protocol='icmp',
remote_ip_prefix=remote_ip_prefix)
ingress_rule_1.create()
sg.rules.append(ingress_rule_1)
#第二条规则,表示允许所有tcp协议访问安全组内部机器所有端口
ingress_rule_2 = sg_obj.SecurityGroupRule(
context, id=uuidutils.generate_uuid(),
project_id=tenant_id, security_group_id=sg.id,
direction='ingress', ethertype='IPv4',
protocol='tcp',
remote_ip_prefix=remote_ip_prefix,port_range_max=65535,
port_range_min=1)
ingress_rule_2.create()
sg.rules.append(ingress_rule_2)
#################### 自定义安全规则逻辑 end ####################
#后续逻辑不用动,在此省略
sg.obj_reset_changes(['rules'])
修改完成后,删除/usr/lib/python2.7/site-packages/neutron/db/securitygroups_db.pyc文件,重新启动neutron服务。
systemctl restart neutron-server
新建租户,查看安全组规则列表,达到预期目的,效果图如下: