Neutron 理解 (9): OpenStack 是如何實現 Neutron 網絡 和 Nova虛機 防火牆的 [How Nova Implements Security Group and How Neutron Implements Virtual Firewall]


學習 Neutron 系列文章:

(1)Neutron 所實現的虛擬化網絡

(2)Neutron OpenvSwitch + VLAN 虛擬網絡

(3)Neutron OpenvSwitch + GRE/VxLAN 虛擬網絡

(4)Neutron OVS OpenFlow 流表 和 L2 Population

(5)Neutron DHCP Agent

(6)Neutron L3 Agent  

(7)Neutron LBaas

(8)Neutron Security Group

(9)Neutron FWaas 和 Nova Security Group

(10)Neutron VPNaas

(11)Neutron DVR

(12)Neutron VRRP

(13)High Availability (HA)

 

    本文的基礎知識和所用到的技術和實現和 Neutron 理解 (8): Neutron 是如何實現虛機防火牆的 [How Netruon Implements Security Group] 非常類似,因此會省去相同的部分。

1. Nova 安全組

1.1 配置

節點 配置文件 配置項 說明
controller  /etc/nova/nova.conf security_group_api = nova  是的 nova secgroup* 命令使用的是 nova 安全組的 API
/etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全組
nova-compute

/etc/nova/nova.conf

/etc/nova/nova-compute.conf

firewall_driver = nova.virt.firewall.IptablesFirewallDriver 指定 Nova 安全組的驅動,可以是IptablesFirewallDriver 或者 NWFilterFirewall。默認是 IptablesFirewallDriver。見下面的說明。
  /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全組
network /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全組

 nova 提供兩種實現方式:使用 libvirt's nwfilter 的實現以及使用 linux iptables 的實現,默認的方式是使用 linux iptables。可以通過設置配置項  firewall_driver 的值指定。需要注意的是,即使使用 iptables,依然使用了部分 nwfilter 功能。參見 https://ask.openstack.org/en/question/19456/how-security-group-is-implemented/

  • firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver
  • firewall_driver=nova.virt.libvirt.firewall.NWFilterFirewall

1.2 CLI

列表安全組:
s1@controller:~$ nova secgroup-list-rules novasg1 +-------------+-----------+---------+-----------+--------------+ | IP Protocol | From Port | To Port | IP Range | Source Group | +-------------+-----------+---------+-----------+--------------+ | tcp | 22 | 22 | 0.0.0.0/0 | | +-------------+-----------+---------+-----------+--------------+
創建一個安全組規則:

s1@controller:~$ nova secgroup-add-rule novasg1 udp 53 53 100.1.100.0/24
+-------------+-----------+---------+----------------+--------------+
| IP Protocol | From Port | To Port | IP Range | Source Group |
+-------------+-----------+---------+----------------+--------------+
| udp | 53 | 53 | 100.1.100.0/24 | |
+-------------+-----------+---------+----------------+--------------+

刪除虛機的安全組:

s1@controller:~$ nova remove-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1

添加安全組到虛機:

s1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1

創建第二個安全組:

s1@controller:~$ nova secgroup-add-rule novasg2

添加規則:

s1@controller:~$ nova secgroup-add-rule novasg2 icmp -1 -1 0.0.0.0/0
+-------------+-----------+---------+-----------+--------------+
| IP Protocol | From Port | To Port | IP Range | Source Group |
+-------------+-----------+---------+-----------+--------------+
| icmp | -1 | -1 | 0.0.0.0/0 | |
+-------------+-----------+---------+-----------+--------------+

再添加安全組到虛機:

s1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg2

1.3 iptables 鏈

Nova-compute 增加了 filter 表的 INPUT,OUTPUT 和 FORWARD 鏈:

-N nova-compute-FORWARD
-N nova-compute-INPUT
-N nova-compute-OUTPUT
-N nova-compute-inst-122 #每個虛機一個鏈,命名規則是 ”inst“-<instance 在數據庫中的 id>
-N nova-compute-local
-N nova-compute-provider
-N nova-compute-sg-fallback
-N nova-filter-top
-A INPUT -j nova-compute-INPUT
-A FORWARD -j nova-filter-top
-A FORWARD -j nova-compute-FORWARD
-A OUTPUT -j nova-filter-top
-A OUTPUT -j nova-compute-OUTPUT
-A nova-compute-FORWARD -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -j ACCEPT #允許本機上的虛機發出 DHCP 廣播
-A nova-compute-INPUT -s 0.0.0.0/32 -d 255.255.255.255/32 -p udp -m udp --sport 68 --dport 67 -j ACCEPT  #允許本機接受 DHCP 廣播包
-A nova-compute-inst-122 -m state --state INVALID -j DROP
-A nova-compute-inst-122 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A nova-compute-inst-122 -j nova-compute-provider
-A nova-compute-inst-122 -s 91.1.180.2/32 -p udp -m udp --sport 67 --dport 68 -j ACCEPT #接受該虛機所在子網的 DHCP Server 返回的包
-A nova-compute-inst-122 -s 91.1.180.0/24 -j ACCEPT                                     #在配置項 allow_same_net_traffic = true 的情況下接受同網段虛機的來訪包
-A nova-compute-inst-122 -p tcp -m tcp --dport 22 -j ACCEPT                             #用戶安全組規則指定的來訪包
-A nova-compute-inst-122 -s 100.1.100.0/24 -p udp -m udp --dport 53 -j ACCEPT           #用戶安全組規則指定的來訪包
-A nova-compute-inst-122 -p icmp -j ACCEPT                                              #用戶安全組規則指定的來防爆
-A nova-compute-inst-122 -j nova-compute-sg-fallback                                    #沒被上面規則處理的其它來訪包 
-A nova-compute-local -d 91.1.180.14/32 -j nova-compute-inst-122                        # “-d“ 決定了 nova 安全組只檢查進入虛機的網絡包
-A nova-compute-sg-fallback -j DROP                                                     #丟棄其它包,只允許上述規則指定的網絡訪問
-A nova-filter-top -j nova-compute-local

2. FWaas

2.1 概念

    從 Havana 版本開始,Neutron 提供一種基於 Neutron L3 Agent 的一種網絡四層防火牆虛擬化參考實現 Firewall-as-a-service,簡稱 FWaas。本文的分析是基於 OpenStack Juno 版本進行的。Juno 版本中,FWaas 是分租戶的,但是可以在多個租戶之間共享。每個租戶只允許一個防火牆。與物理的防火牆類似,FWaas 也有三個主要概念:

 (1)規則(Rule):允許用戶指定所要匹配的名稱,描述,針對的協議(TCP, UDP, ICMP, ANY),行為(Allow,Deny),源/目的 IP 地址/子網 和 端口號/端口號區間。

 

與 neutron 安全組中的規則的區別是,這里需要指定被匹配到的數據包的處理行為是通過(ALLOW)和不通過(DENY),但是不能指定網絡方向。FWaas 會將規則同時應用到進出網絡的網絡包上。

(2)策略(Policy):規則的邏輯集合。Policy 可以是共享的 和 被審計的(Audited)。目前,FWaas 只是把 “audited” 保存到 DB 中,並沒有對它做任何處理。

(3)防火牆(Firewall):策略的邏輯集合。見上面右圖。Juno 版本中,每個租戶只能擁有最多一個 Firewall。防火牆可以是共享的。 

    這里需要說明的是 FWaas 和 Security Group (安全組) 的區別。安全組規則在連接到一個實例的計算節點上的Linux橋 qbr 上實施,FWaaS 創建的防火牆規則在租戶網絡邊緣實現的虛擬路由器上實施。 FWaaS 並不旨在取代安全組的功能,並且它提供更為補充安全組,特別是在其當前實現狀態下。 FWaaS 目前缺乏安全組提供的一些功能,包括無法指定通信的方向等。與此相反,安全組,也因為他們缺乏創建特定規則拒絕所有流量的能力,因此需要 FWaas 作為補充。

 

2.2 配置

節點 配置和操作
控制節點上
修改 /etc/neutron/neutron.conf:
[default]
service_plugins = router,lbaas,firewall
[service_providers]
service_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default
 
service neutron-server restart
 
修改 /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py:'enable_firewall': True
網絡節點上
修改 /etc/neutron/fwaas_driver.ini:
[fwaas]
driver = neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver
enabled = True
 
service neutron-l3-agent restart

 

2.3 實現

目前的實現中,FWaas 是通過在其所在 tenant 中的所有 Virtual Router 上添加 iptbales 規則來實現對進出數據網絡的網絡包進行控制的。

代碼實現:

控制節點上(class FirewallPlugin):

(1)create rule:純數據庫操作,將 rule 保存到數據中。

(2)create policy:純數據庫操作,將 policy 保存到數據中。

(3)如果將 rule 添加到一個已經添加到 firwall 的 policy,或者將一個 policy 加入一個存在的 firewall,在數據庫操作后,通過 RPC fanout 到所有的 L3 Agent host:

{'args': {'firewall': {'status': 'PENDING_UPDATE', 'name': u'fw-for-tcp', 'shared': None, 'firewall_policy_id': u'd14e23a3-2ee6-411d-b678-e6db3dac45f5', 'tenant_id': u'74c8ada23a3449f888d9e19b76d13aab', 'admin_state_up': True, 'id': u'aa85bd66-dc4c-4d1b-909e-6f5736c279c7', 'firewall_rule_list': [{'protocol': u'icmp', 'description': u'', 'source_port': None, 'source_ip_address': None, 'destination_ip_address': None, 'firewall_policy_id': u'd14e23a3-2ee6-411d-b678-e6db3dac45f5', 'position': 1, 'destination_port': None, 'id': u'8658229d-6e34-4069-b091-e560f9e54dc9', 'name': u'rule-allow-icmp', 'tenant_id': u'74c8ada23a3449f888d9e19b76d13aab', 'enabled': True, 'action': u'allow', 'ip_version': 4L, 'shared': False}, {'protocol': u'tcp', 'description': u'', 'source_port': None, 'source_ip_address': None, 'destination_ip_address': None, 'firewall_policy_id': u'd14e23a3-2ee6-411d-b678-e6db3dac45f5', 'position': 2, 'destination_port': '80', 'id': u'00b5bad2-dd14-48d6-9a5c-7b65e6e8c480', 'name': u'fule-allow-tcp-80', 'tenant_id': u'74c8ada23a3449f888d9e19b76d13aab', 'enabled': True, 'action': u'allow', 'ip_version': 4L, 'shared': False}], 'description': u''}, 'host': 'controller'}, 'namespace': None, 'method': 'update_firewall'}

  • insert_rule/remove_rule/update_firewall_rule/update_firewall_policy -> Firewall_db_mixin.insert_rule/remove_rule/update_firewall_rule/update_firewall_policy -> _rpc_update_firewall_policy -> _rpc_update_firewall -> (if policy has a firewall) FirewallAgentApi.update_firewall
  • create_firewall -> Firewall_db_mixin.create_firewall -> FirewallAgentApi.create_firewall
  • update_firewall -> Firewall_db_mixin.update_firewall -> FirewallAgentApi.update_firewall
  • delete_firewall -> Firewall_db_mixin.delete_firewall -> FirewallAgentApi.delete_firewall
  • FirewallAgentApi.create/update/delete_firewall -> fanout_cast ("create/update/delete_firewall", topics.L3_AGENT, "controller", firewall) -----> FWaaSL3AgentRpcCallback.create/update/delete_firewall -> FWaaSL3AgentRpcCallback._invoke_driver_for_plugin_api

 網絡節點上(class FWaaSL3AgentRpcCallback):

(1) 通過 RPC 獲取所有的 router,在獲取firewall 所在的 tenant 上的 routers

(2)調用 IptablesFwaasDriver.update_firewall,依次更新每個 router 的 iptables 規則

(3)首先刪除已有規則,然后根據配置的 rules 重新生成規則 

root@network:/var/cache# ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 iptables -t filter -S -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -N neutron-filter-top -N neutron-l3-agent-FORWARD -N neutron-l3-agent-INPUT -N neutron-l3-agent-OUTPUT -N neutron-l3-agent-fwaas-defau #新增的 firewall chain -N neutron-l3-agent-iv4aa85bd66 #新增的 firewall chain -N neutron-l3-agent-local -N neutron-l3-agent-ov4aa85bd66 #for firewall -A INPUT -j neutron-l3-agent-INPUT -A FORWARD -j neutron-filter-top -A FORWARD -j neutron-l3-agent-FORWARD #將 forward 轉到 neutron 的chain -A OUTPUT -j neutron-filter-top -A OUTPUT -j neutron-l3-agent-OUTPUT -A neutron-filter-top -j neutron-l3-agent-local -A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-iv4aa85bd66 #進數據網絡的包 -A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-ov4aa85bd66 #出數據網絡的包
-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-defau #進數據網絡的包的默認處理 chain -A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-defau #出數據網絡的包的默認處理 chain -A neutron-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT -A neutron-l3-agent-fwaas-defau -j DROP #默認丟棄沒有被以上規則處理的所有包
-A neutron-l3-agent-iv4aa85bd66 -m state --state INVALID -j DROP -A neutron-l3-agent-iv4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT #接受狀態為 RELATED, ESTABLISHED (已建立的連接)的包 -A neutron-l3-agent-iv4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT #根據定義的 FWaas rule,接受目的端口為 80 的 tcp 包
-A neutron-l3-agent-ov4aa85bd66 -m state --state INVALID -j DROP -A neutron-l3-agent-ov4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT -A neutron-l3-agent-ov4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT #根據 FWaas rule,接收目的端口為 80 的 tcp 包

 

歡迎大家關注我的個人公眾號:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM