OpenStack防火墙功能实现介绍
防火墙功能介绍
OpenStack防火墙的核心是防火墙策略和防火墙规则,策略是一组防火墙规则集合,规则是由一组匹配条件(如端口范围、协议、IP地址),以及对匹配流量采取的操作(allow、deny);
策略可以设置成public,跨project使用;
防火墙的功能实现有很多方式,取决于driver的选用;例如:iptables driver使用iptables rule来实现,OVS driver使用流表,Cisco防火墙driver使用NSX设备;
OpenStack现有FWaaS v1和FWaaS v2,本文介绍v1
FWaaS v1
OpenStack Rocky版本
FWaaS v1提供针对路由的保护,当防火墙关联到一个路由上,那么所有的内部port都是受该防火墙保护的;
防火墙driver
[firewall_drivers]
iptables = neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.iptables_fwaas:IptablesFwaasDriver
创建防火墙
neutron_fwaas.services.firewall.service_drivers.agents.drivers.linux.iptables_fwaas
class IptablesFwaasDriver():
# apply_list: router_info_list _get_router_info_list_for_tenant
# firewall: fw_with_rules _make_firewall_dict_with_rules
def create_firewall(self, agent_mode, apply_list, firewall):
if firewall['admin_state_up']:
# setup操作如下:
# 1. 生成名称i,o(ingress, egress) + v4(ip版本) + fwid 取前11位;尝试删除对应链
# 2. 尝试删除名为fwaas-default-policy的链
# 3. 创建名为fwaas-default-policy的链,并加入drop all的规则
# 4. 增加规则:增加第一步中删除的链,在每个链中(1)drop所有无效包(2)allow已建立链接的包(3)根据firewall_rule里的规则加入
# 5. 将第4步中生成的链链接到Forward,将第3步生成的链链接到Forward
self._setup_firewall(agent_mode, apply_list, firewall)
# 生效
self._remove_conntrack_new_firewall(agent_mode,
apply_list, firewall)
# 设置pre_firewall为当前firewall
self.pre_firewall = dict(firewall)
else:
# 如果firewall的admin_state_up为False,即只添加default DROP ALL的规则
self.apply_default_policy(agent_mode, apply_list, firewall)
更新防火墙
更新防火墙从agent的看起
neutron_fwaas.services.firewall.service_drivers.agents.l3reference.firewall_l3_agent
class FWaaSL3AgentExtension():
def update_firewall():
# L320 先调用driver的删除
self.fwaas_driver.delete_firewall(
self.conf.agent_mode,
router_info_list,
firewall)
# L348 再调用driver的update
self.fwaas_driver.update_firewall(
self.conf.agent_mode,
router_info_list,
firewall)
def delete_firewall(self, agent_mode, apply_list, firewall):
fwid = firewall['id']
try:
for router_info in apply_list:
ipt_if_prefix_list = self._get_ipt_mgrs_with_if_prefix(
agent_mode, router_info)
for ipt_if_prefix in ipt_if_prefix_list:
ipt_mgr = ipt_if_prefix['ipt']
# 删除创建过程中3,4步骤的生成的链
self._remove_chains(fwid, ipt_mgr)
self._remove_default_chains(ipt_mgr)
# apply the changes immediately (no defer in firewall path)
ipt_mgr.defer_apply_off()
self.pre_firewall = None
def update_firewall(self, agent_mode, apply_list, firewall):
try:
if firewall['admin_state_up']:
# 详见创建防火墙的创建过程
self._setup_firewall(agent_mode, apply_list, firewall)
if self.pre_firewall:
# 如果已有防火墙,作比较,获取需要增加和删除的规则
self._remove_conntrack_updated_firewall(agent_mode,
apply_list, self.pre_firewall, firewall)
else:
self._remove_conntrack_new_firewall(agent_mode,
apply_list, firewall)
else:
self.apply_default_policy(agent_mode, apply_list, firewall)
# 更新当前防火墙
self.pre_firewall = dict(firewall)
......
删除防火墙
在更新防火墙中已提及
其他操作
在针对防火墙的操作中,还有insert_rule和remove_rule等操作;
neutron_fwaas.services.firewall.fwaas_plugin
class FirewallPlugin():
def insert_rule(self, context, id, rule_info):
# 判断防火墙是否可以更新
self._ensure_update_firewall_policy(context, id)
fwp = super(FirewallPlugin,
self).insert_rule(context, id, rule_info)
# 调用agent做update_firewall
self._rpc_update_firewall_policy(context, id)
resource = 'firewall_policy.update.insert_rule'
self._notify_firewall_updates(context, resource, rule_info)
return fwp
def remove_rule(self, context, id, rule_info):
self._ensure_update_firewall_policy(context, id)
fwp = super(FirewallPlugin,
self).remove_rule(context, id, rule_info)
# 调用agent做update_firewall
self._rpc_update_firewall_policy(context, id)
resource = 'firewall_policy.update.remove_rule'
self._notify_firewall_updates(context, resource, rule_info)
return fwp
总结
防火墙工作原理是在关联router后,针对该router对应的namespace做iptables的规则添加。而且在FWaaS v1中是默认default都DROP,然后加ALLOW的规则。
后记
后续会接着介绍一下FWaaS v2的功能。
版权声明:本文为mr1jie原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。