找回密码
 注册
查看: 1406|回复: 0

neutron 网络Neutron 理解 (9): OpenStack 是如何实现 Neutron 网络 和 Nova虚机 防火墙的 [How Nova Imp

[复制链接]

0

主题

0

回帖

9

积分

管理员

积分
9
QQ
发表于 2021-12-7 15:28:32 | 显示全部楼层 |阅读模式
1. Nova 安全组: q7 S. E. a0 _8 u/ B
1.1 配置
$ j; Y# m# b  D: Q" e8 {节点 配置文件 配置项 说明* W6 f: }8 e% G" b7 w
controller  /etc/nova/nova.conf security_group_api = nova  是的 nova secgroup* 命令使用的是 nova 安全组的 API; z$ _5 P" z" p& U# A$ Y
/etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组
& i/ V" K$ H3 u( a6 a7 Y5 gnova-compute
5 S) _- r' A; q1 [1 Z/etc/nova/nova.conf
1 m: ], A& W' X& O! J3 V/etc/nova/nova-compute.conf# {/ K4 F. w6 z
firewall_driver = nova.virt.firewall.IptablesFirewallDriver 指定 Nova 安全组的驱动,可以是IptablesFirewallDriver 或者 NWFilterFirewall。默认是 IptablesFirewallDriver。见下面的说明。  V+ q& ?+ v, Q1 U, V
  /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组1 D6 Z8 f& B: K+ e
network /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组
& K; O& n0 D1 l% w nova 提供两种实现方式:使用 libvirt's nwfilter 的实现以及使用 linux iptables 的实现,默认的方式是使用 linux iptables。可以通过设置配置项  firewall_driver 的值指定。需要注意的是,即使使用 iptables,依然使用了部分 nwfilter 功能。参见 https://ask.openstack.org/en/question/19456/how-security-group-is-implemented/" n; Y, R1 {# [  ~
firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver3 ?, m, \* E/ }$ O/ `5 }' B( |
firewall_driver=nova.virt.libvirt.firewall.NWFilterFirewall4 N& z. c3 u# p, |2 c
1.2 CLI
1 R) o  y5 C, c4 K# z! I& Q# k复制代码6 x( F. d1 |/ E6 x( j
列表安全组:
9 Y7 u5 @& G1 D, u  a; ?; Ms1@controller:~$ nova secgroup-list-rules novasg1
2 @# p/ X. q# `9 U$ E* k  F0 v+-------------+-----------+---------+-----------+--------------+
" X) _5 W! F4 w: l| IP Protocol | From Port | To Port | IP Range  | Source Group |7 W; B* o- z& u
+-------------+-----------+---------+-----------+--------------+1 t+ x' k. S$ P3 L1 g4 w6 F8 U# O
| tcp         | 22        | 22      | 0.0.0.0/0 |              |
% i/ b$ N; ^. v+-------------+-----------+---------+-----------+--------------+
( |4 j3 z8 t0 K+ l/ m% ?4 C: W/ p创建一个安全组规则:
! m# o5 ?  I, e' W# A% ^s1@controller:~$ nova secgroup-add-rule novasg1 udp 53 53 100.1.100.0/24- a. p( c8 y0 h3 a" k9 y
+-------------+-----------+---------+----------------+--------------+
5 ^$ Z' e1 G( g| IP Protocol | From Port | To Port | IP Range | Source Group |
: Q* D+ j! b" O7 X, L9 u2 A+-------------+-----------+---------+----------------+--------------+
$ }5 j* }& ?/ Z/ X$ p| udp | 53 | 53 | 100.1.100.0/24 | |
- q7 u. L1 ?; U* W8 c2 E+-------------+-----------+---------+----------------+--------------+7 Q% z1 ~; n1 z; ^+ l& W
删除虚机的安全组:; n$ @( B5 q# j- C* v! B
s1@controller:~$ nova remove-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
! b5 \# y5 o% u" ]+ C添加安全组到虚机:
/ \3 \4 o  T' o( Ts1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
/ }  L, I) z8 f, m4 f, t创建第二个安全组:
3 x3 O: Y& @4 c: x# `6 Z- X- h& us1@controller:~$ nova secgroup-add-rule novasg2
2 ]5 s4 X( h' U( |/ z3 S添加规则:
3 K# f, T- i- ~s1@controller:~$ nova secgroup-add-rule novasg2 icmp -1 -1 0.0.0.0/03 V. q6 I6 }7 t8 H% M5 R7 O
+-------------+-----------+---------+-----------+--------------+7 ?+ L9 L0 g; y! G4 U
| IP Protocol | From Port | To Port | IP Range | Source Group |3 R5 v% A3 ?. w' N/ a
+-------------+-----------+---------+-----------+--------------+
) A+ x6 `$ k  g; }6 {| icmp | -1 | -1 | 0.0.0.0/0 | |  l/ j  W" e1 {; f* n5 s3 D7 B
+-------------+-----------+---------+-----------+--------------+
9 N/ e* M3 ^# K1 L! H- ?再添加安全组到虚机:" K' I& `3 `0 Q9 @& Z' U
s1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg2$ c! i2 A9 {- Y/ l& ~
复制代码
4 c2 L  q# \) _! Y1.3 iptables 链, }; ?: Z/ G% i3 A! s
Nova-compute 增加了 filter 表的 INPUT,OUTPUT 和 FORWARD 链:0 n1 }, \& `, W  @8 A

$ n# f. z* l% y, i复制代码
6 i: J9 b: Y9 S7 X-N nova-compute-FORWARD/ g6 }) b& t; ?# P2 l- I# g
-N nova-compute-INPUT4 v2 J, f* r+ M6 s/ u' l
-N nova-compute-OUTPUT0 w' |2 W9 s1 p" F% q1 i
-N nova-compute-inst-122 #每个虚机一个链,命名规则是 ”inst“-<instance 在数据库中的 id>2 X! j' i! {9 S- D
-N nova-compute-local: K' X& |; P& Z3 T8 C+ N+ k
-N nova-compute-provider$ ]- c" B' p1 n" L1 o3 Z* Q
-N nova-compute-sg-fallback# z( S3 P6 p8 u
-N nova-filter-top: J8 g+ A+ G2 y, o* H
-A INPUT -j nova-compute-INPUT
! p9 f# M/ ^+ q7 S. w4 [# F-A FORWARD -j nova-filter-top
9 {4 z# H. `& a( V-A FORWARD -j nova-compute-FORWARD: C( G8 e4 n/ ~: p; ]0 d
-A OUTPUT -j nova-filter-top
5 t' w( _9 U$ Q) ^1 p) s-A OUTPUT -j nova-compute-OUTPUT
/ P/ X, i% d3 i-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 广播
2 k( o0 Z' s2 K4 J-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 广播包
* n" P  X' n; p3 [2 F. s-A nova-compute-inst-122 -m state --state INVALID -j DROP
! ~5 o" p0 w( m+ T; F4 G/ {-A nova-compute-inst-122 -m state --state RELATED,ESTABLISHED -j ACCEPT- O$ k" w& Q+ L
-A nova-compute-inst-122 -j nova-compute-provider1 w5 {+ V8 j. [" B+ l
-A nova-compute-inst-122 -s 91.1.180.2/32 -p udp -m udp --sport 67 --dport 68 -j ACCEPT #接受该虚机所在子网的 DHCP Server 返回的包8 ]" r  N5 V: l. ~/ w* ]8 ]
-A nova-compute-inst-122 -s 91.1.180.0/24 -j ACCEPT                                     #在配置项 allow_same_net_traffic = true 的情况下接受同网段虚机的来访包5 j3 n( r! h, e: K
-A nova-compute-inst-122 -p tcp -m tcp --dport 22 -j ACCEPT                             #用户安全组规则指定的来访包* O0 t& {" c! l. u9 t, `
-A nova-compute-inst-122 -s 100.1.100.0/24 -p udp -m udp --dport 53 -j ACCEPT           #用户安全组规则指定的来访包; g9 {: n% p: c; D# ]& W  C  ]* W
-A nova-compute-inst-122 -p icmp -j ACCEPT                                              #用户安全组规则指定的来防爆
* b0 \- K  s" E* ?% Q, X-A nova-compute-inst-122 -j nova-compute-sg-fallback                                    #没被上面规则处理的其它来访包
% k' b1 ^6 z: r4 r-A nova-compute-local -d 91.1.180.14/32 -j nova-compute-inst-122                        # “-d“ 决定了 nova 安全组只检查进入虚机的网络包
# P( m+ K8 F3 ^4 j# c' Z-A nova-compute-sg-fallback -j DROP                                                     #丢弃其它包,只允许上述规则指定的网络访问! |/ S0 q' S0 t1 Y- n
-A nova-filter-top -j nova-compute-local
; T, V( B/ d9 @6 S3 J  q复制代码4 E( g* A0 k- R3 j0 p/ ~2 H
2. FWaas
; u* ?5 v- L- R8 R2.1 概念
" u, R, S1 b  y9 F7 Q    从 Havana 版本开始,Neutron 提供一种基于 Neutron L3 Agent 的一种网络四层防火墙虚拟化参考实现 Firewall-as-a-service,简称 FWaas。本文的分析是基于 OpenStack Juno 版本进行的。Juno 版本中,FWaas 是分租户的,但是可以在多个租户之间共享。每个租户只允许一个防火墙。与物理的防火墙类似,FWaas 也有三个主要概念:
2 }  p0 ~, Z$ m0 b+ N4 W- r (1)规则(Rule):允许用户指定所要匹配的名称,描述,针对的协议(TCP, UDP, ICMP, ANY),行为(Allow,Deny),源/目的 IP 地址/子网 和 端口号/端口号区间。
9 ~  X. i% V! }4 _5 o: e
) y0 s+ w: Q5 j0 a( S与 neutron 安全组中的规则的区别是,这里需要指定被匹配到的数据包的处理行为是通过(ALLOW)和不通过(DENY),但是不能指定网络方向。FWaas 会将规则同时应用到进出网络的网络包上。
+ C# N8 o4 D' C(2)策略(Policy):规则的逻辑集合。Policy 可以是共享的 和 被审计的(Audited)。目前,FWaas 只是把 “audited” 保存到 DB 中,并没有对它做任何处理。
( \- @, n9 O' m6 z; {
9 A3 L5 Z7 @5 @  B7 X% u! B(3)防火墙(Firewall):策略的逻辑集合。见上面右图。Juno 版本中,每个租户只能拥有最多一个 Firewall。防火墙可以是共享的。
& t, F. I- Q8 ]  B% P    这里需要说明的是 FWaas 和 Security Group (安全组) 的区别。安全组规则在连接到一个实例的计算节点上的Linux桥 qbr 上实施,FWaaS 创建的防火墙规则在租户网络边缘实现的虚拟路由器上实施。 FWaaS 并不旨在取代安全组的功能,并且它提供更为补充安全组,特别是在其当前实现状态下。 FWaaS 目前缺乏安全组提供的一些功能,包括无法指定通信的方向等。与此相反,安全组,也因为他们缺乏创建特定规则拒绝所有流量的能力,因此需要 FWaas 作为补充。
4 X& J( @! R$ G" v  F# @" M/ s! z2 R$ a# d
' ~% u! C) e" k
$ S. x- |3 Y' }1 Q& {2 e# n1 f1 `2.2 配置
' f  g3 ?% H* r% a节点 配置和操作$ I2 A9 [6 d3 m9 b) k1 R5 b" g
控制节点上
, E4 I  J' b0 ?修改 /etc/neutron/neutron.conf:
9 f( f* F2 C8 }+ Y' L  W9 R8 ^[default]1 p' c  u8 ?4 G4 p2 s
service_plugins = router,lbaas,firewall5 N, C% w' }* c  }
[service_providers]7 y. b- |* m5 g
service_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default' L0 ?5 s6 A; S2 k2 z. X6 f4 }, [  z
; C8 d. U2 r* }& w& y% V6 b6 U
service neutron-server restart5 t5 a3 j; W) Y( A) U
# `) E! e1 s7 e% u( }
修改 /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py:'enable_firewall': True
1 L/ ~5 b9 b; n0 U8 ^- E网络节点上 % f# \! U- V/ ^- y
修改 /etc/neutron/fwaas_driver.ini:
4 d( i# k4 C# `+ x! }; J[fwaas]) X8 y9 S; L6 `  F) i
driver = neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver4 k) d- r4 h. h6 A! }" y
enabled = True' `% y& s1 x5 J. H" I
0 a1 }& J- V4 d2 Q% C' t5 ?. ]
service neutron-l3-agent restart( q. s: C" W( v' X2 _$ [% h

: Y1 r9 {0 \( }. {2.3 实现. k' ~0 J9 k3 h/ t
目前的实现中,FWaas 是通过在其所在 tenant 中的所有 Virtual Router 上添加 iptbales 规则来实现对进出数据网络的网络包进行控制的。0 N+ X& x5 u. f6 i

0 P( i  a+ i3 ~3 i* k) h代码实现:& i  L% Q; k! I7 k
控制节点上(class FirewallPlugin):
0 D9 A( E2 ^* ~5 S& F) z6 ]9 b(1)create rule:纯数据库操作,将 rule 保存到数据中。
/ P, s4 R* m/ y8 ]8 ?(2)create policy:纯数据库操作,将 policy 保存到数据中。* r( I7 v- [& R+ O! t* r9 v; y
(3)如果将 rule 添加到一个已经添加到 firwall 的 policy,或者将一个 policy 加入一个存在的 firewall,在数据库操作后,通过 RPC fanout 到所有的 L3 Agent host:5 }" Y: ?8 o0 E+ i: ], ?  ]
{'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'}
. p, k0 j4 [1 D, @( ?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_firewall7 P4 ~6 t# }: p0 y. i; w
create_firewall -> Firewall_db_mixin.create_firewall -> FirewallAgentApi.create_firewall+ Q- T7 ]1 n0 T; H
update_firewall -> Firewall_db_mixin.update_firewall -> FirewallAgentApi.update_firewall
* K# R: t/ u+ Fdelete_firewall -> Firewall_db_mixin.delete_firewall -> FirewallAgentApi.delete_firewall
3 P% x& ?9 `2 ~- N8 R6 @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_api0 ?: P# H- ?4 h+ l1 t1 l9 Z
网络节点上(class FWaaSL3AgentRpcCallback):( K* @: I, j% H* M- R. N
(1) 通过 RPC 获取所有的 router,在获取firewall 所在的 tenant 上的 routers
# Q2 {) J; X8 S1 g" U, f(2)调用 IptablesFwaasDriver.update_firewall,依次更新每个 router 的 iptables 规则
( G2 h5 w5 W1 h$ X(3)首先删除已有规则,然后根据配置的 rules 重新生成规则
& |: j. h4 E! W: ]$ X1 ]复制代码. j/ \5 Q1 a8 b# m$ e% f
root@network:/var/cache# ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 iptables -t filter -S* @' a" H( t% t4 x
-P INPUT ACCEPT
5 G9 F% Q: E+ R% @7 w( v1 @-P FORWARD ACCEPT
2 q+ ]4 b- A* C( i-P OUTPUT ACCEPT2 a$ p+ B5 H) b. N
-N neutron-filter-top( s' u9 y5 N- y) D1 H$ L4 o- T
-N neutron-l3-agent-FORWARD
* t  S" C6 R4 o1 r$ V! D6 h1 }+ ]3 g-N neutron-l3-agent-INPUT, D' _$ U0 S; ?( f4 C6 b
-N neutron-l3-agent-OUTPUT5 g; |/ u8 i$ G: l' N% z' e
-N neutron-l3-agent-fwaas-defau #新增的 firewall chain1 d# y$ ^2 q# T2 \! [$ a
-N neutron-l3-agent-iv4aa85bd66 #新增的 firewall chain
' J0 Q( d4 I) l# A-N neutron-l3-agent-local
8 w* J6 p# J0 n-N neutron-l3-agent-ov4aa85bd66 #for firewall' |& a) r( D4 V% {
-A INPUT -j neutron-l3-agent-INPUT% j9 H4 Q/ X$ }; `8 T
-A FORWARD -j neutron-filter-top
; g/ P  h5 b1 {: y1 [' a-A FORWARD -j neutron-l3-agent-FORWARD #将 forward 转到 neutron 的chain
& g4 }- J; p+ i& Q  m-A OUTPUT -j neutron-filter-top* L- s2 Q& k. q* `% b
-A OUTPUT -j neutron-l3-agent-OUTPUT5 N/ y' m: I; v6 s2 M% e  t
-A neutron-filter-top -j neutron-l3-agent-local
  a/ w2 b& y6 {$ E9 ^( {0 _-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-iv4aa85bd66 #进数据网络的包
5 d/ d% b2 E& X9 ]7 d-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-ov4aa85bd66 #出数据网络的包
; e! d5 r6 G+ y7 w+ N-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-defau #进数据网络的包的默认处理 chain, t) e9 A4 U0 V3 x
-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-defau #出数据网络的包的默认处理 chain4 q8 a8 L( L! P
-A neutron-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT" @2 Q, g5 x$ m
-A neutron-l3-agent-fwaas-defau -j DROP                             #默认丢弃没有被以上规则处理的所有包, d4 F7 [& _" c  }& J
-A neutron-l3-agent-iv4aa85bd66 -m state --state INVALID -j DROP
( E3 Y# _1 e1 Y# Y8 h-A neutron-l3-agent-iv4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT #接受状态为 RELATED, ESTABLISHED (已建立的连接)的包
4 h. P: a% G+ S' F: i' g2 Z; w-A neutron-l3-agent-iv4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT             #根据定义的 FWaas rule,接受目的端口为 80 的 tcp 包. Q9 ?1 l8 O1 {
-A neutron-l3-agent-ov4aa85bd66 -m state --state INVALID -j DROP
+ B- x  \" H# r% ~-A neutron-l3-agent-ov4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT
4 {8 ^1 D1 V* f' d7 x! x3 x4 q-A neutron-l3-agent-ov4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT             #根据 FWaas rule,接收目的端口为 80 的 tcp 包9 M) _9 T  \9 K8 Z9 _# L! W
复制代码; x4 g4 V: s9 b; e9 ~: M) q# n
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-11 22:59 , Processed in 0.023902 second(s), 23 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表