易陆发现互联网技术论坛

 找回密码
 开始注册
查看: 1405|回复: 0
收起左侧

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

[复制链接]
发表于 2021-12-7 15:28:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?开始注册

x
1. Nova 安全组% x7 c8 V* i/ ^8 P
1.1 配置
, M% T0 L# \$ n节点 配置文件 配置项 说明- I$ G( p' s% S! b) s$ Q, T5 V
controller  /etc/nova/nova.conf security_group_api = nova  是的 nova secgroup* 命令使用的是 nova 安全组的 API+ m* Y5 k2 i; X! d, H
/etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组3 H# W$ d. O* ^. Y
nova-compute
. n* B- y3 A# V2 n$ [* @/etc/nova/nova.conf
7 _8 u( T4 k8 O1 \0 F+ c0 F/etc/nova/nova-compute.conf
1 D9 Z# D! `0 h$ cfirewall_driver = nova.virt.firewall.IptablesFirewallDriver 指定 Nova 安全组的驱动,可以是IptablesFirewallDriver 或者 NWFilterFirewall。默认是 IptablesFirewallDriver。见下面的说明。" |0 w3 |/ T, J, i; [; }2 u: I* m
  /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组  n5 W% q. W% q, z6 H5 Z/ R
network /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组0 {( @8 Y' I+ X- G" f7 {
nova 提供两种实现方式:使用 libvirt's nwfilter 的实现以及使用 linux iptables 的实现,默认的方式是使用 linux iptables。可以通过设置配置项  firewall_driver 的值指定。需要注意的是,即使使用 iptables,依然使用了部分 nwfilter 功能。参见 https://ask.openstack.org/en/question/19456/how-security-group-is-implemented/+ x* x. D! Y4 S+ [
firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver  V$ C0 q: R7 X, r; K6 e
firewall_driver=nova.virt.libvirt.firewall.NWFilterFirewall+ \$ }1 Q' q5 O5 O, d
1.2 CLI
1 `% W* K; Z5 q6 Z复制代码/ }  r; g4 I0 g* Z
列表安全组:9 U7 R4 A# g: @/ k' |6 E, Q3 C
s1@controller:~$ nova secgroup-list-rules novasg1
$ R. [6 z! b6 g' Z  D8 o) }" a+-------------+-----------+---------+-----------+--------------+
/ `5 D5 g$ s& }% A| IP Protocol | From Port | To Port | IP Range  | Source Group |
" V7 ]* t" i7 f/ X/ t$ _) S+-------------+-----------+---------+-----------+--------------+
9 u% a. k1 g: _1 U! D8 m2 ^# y| tcp         | 22        | 22      | 0.0.0.0/0 |              |
3 T, q3 q0 e1 q' p; N) I+-------------+-----------+---------+-----------+--------------+
3 J5 ]% V' m, x! k+ j* E8 H& e0 z创建一个安全组规则:
5 {! K3 w' V. R" Y4 as1@controller:~$ nova secgroup-add-rule novasg1 udp 53 53 100.1.100.0/242 v5 B1 ]/ |  S9 X1 G
+-------------+-----------+---------+----------------+--------------+* j  a/ {: R7 f& \+ e5 v
| IP Protocol | From Port | To Port | IP Range | Source Group |! K4 Q* V5 V. B9 ^$ ]- A4 [* e% D% H/ d
+-------------+-----------+---------+----------------+--------------+
3 y, h2 \) \9 {' o# c' U| udp | 53 | 53 | 100.1.100.0/24 | |
, H6 A: d1 O1 b# i+-------------+-----------+---------+----------------+--------------+4 l! P& @" S6 t! G* g" w6 T' D
删除虚机的安全组:1 f* \' y% c9 g
s1@controller:~$ nova remove-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
3 ]- B1 s! Y$ j9 u添加安全组到虚机:
- w. ]6 v; D  ~& D% hs1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
# W& D  ^% [! B7 O' Z创建第二个安全组:. p$ e& F" d: K" @
s1@controller:~$ nova secgroup-add-rule novasg2
  c: y5 d" h0 g' ~9 h添加规则:
9 H4 F7 Y8 ^; d3 [1 f+ R* Es1@controller:~$ nova secgroup-add-rule novasg2 icmp -1 -1 0.0.0.0/0
- D' Z8 L" ^. j! j+ {' B# s+-------------+-----------+---------+-----------+--------------++ ?. S$ y/ h' H% J7 _; f$ u/ i9 @- a
| IP Protocol | From Port | To Port | IP Range | Source Group |
$ E' ^! J3 o0 g8 x" b1 Q2 A9 ~+-------------+-----------+---------+-----------+--------------+
7 u) F- ~8 L. j$ s' R) u% P| icmp | -1 | -1 | 0.0.0.0/0 | |
: P8 z7 |' T: C' m! L2 ]1 s+-------------+-----------+---------+-----------+--------------+$ |+ D# Y* ~# ]$ S' ?
再添加安全组到虚机:) O/ F: r7 z! Q
s1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg2
  ]: r2 P% \! `) j1 P- w复制代码
0 M7 T* Y; x  A' X+ t8 O0 |. U1.3 iptables 链5 V1 |4 h( g5 [6 R  D
Nova-compute 增加了 filter 表的 INPUT,OUTPUT 和 FORWARD 链:
; h3 [& D1 f& G( R  h9 B% I2 e* @' Z7 A+ a# ^
复制代码
2 e- h7 r& P3 m& V8 \2 g& E-N nova-compute-FORWARD. f  D7 a; ^# N# a# y
-N nova-compute-INPUT
5 z+ U% K* ^" s-N nova-compute-OUTPUT. Q- [5 x) E0 ^
-N nova-compute-inst-122 #每个虚机一个链,命名规则是 ”inst“-<instance 在数据库中的 id>% l8 P/ z2 U5 N3 u. W  g) d  \
-N nova-compute-local$ Q0 p% \  D: c6 u" A4 F! D
-N nova-compute-provider
0 U* z/ o6 \: K1 g-N nova-compute-sg-fallback
2 B9 w% L  P+ J  Y& }8 D* z-N nova-filter-top
* \  A$ O* R2 A0 H7 p  O) C-A INPUT -j nova-compute-INPUT
8 g3 f5 u2 G4 S$ \. ?* o& a# z-A FORWARD -j nova-filter-top
% [7 B) f6 h: K" x-A FORWARD -j nova-compute-FORWARD7 I$ K4 `7 {; c- V: T1 Y, Z
-A OUTPUT -j nova-filter-top8 ^- M+ O6 B4 g% I+ Y7 U
-A OUTPUT -j nova-compute-OUTPUT
% |( [" y5 }, E" W7 U( P-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 广播
) [0 s% b& G9 G  D' i  {-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 广播包( u( Y5 y& F6 ~6 R# Y7 _) N
-A nova-compute-inst-122 -m state --state INVALID -j DROP* ?. h8 y* g% V7 ?7 y; M
-A nova-compute-inst-122 -m state --state RELATED,ESTABLISHED -j ACCEPT
% e8 V# C. ~% h4 E! ^$ r" y" ]-A nova-compute-inst-122 -j nova-compute-provider
# [. M# K- V8 D- @) A' M-A nova-compute-inst-122 -s 91.1.180.2/32 -p udp -m udp --sport 67 --dport 68 -j ACCEPT #接受该虚机所在子网的 DHCP Server 返回的包
% i& X* N0 O' `0 W: u/ R-A nova-compute-inst-122 -s 91.1.180.0/24 -j ACCEPT                                     #在配置项 allow_same_net_traffic = true 的情况下接受同网段虚机的来访包
7 v1 T5 h8 [" v-A nova-compute-inst-122 -p tcp -m tcp --dport 22 -j ACCEPT                             #用户安全组规则指定的来访包; D& q' z% R( z. i% D/ ~
-A nova-compute-inst-122 -s 100.1.100.0/24 -p udp -m udp --dport 53 -j ACCEPT           #用户安全组规则指定的来访包3 g  ?  k$ {1 t. f  x7 h8 O8 `
-A nova-compute-inst-122 -p icmp -j ACCEPT                                              #用户安全组规则指定的来防爆5 }. y9 m3 t! I1 l& k9 i2 m
-A nova-compute-inst-122 -j nova-compute-sg-fallback                                    #没被上面规则处理的其它来访包 . y* t. z4 P# a! H) N
-A nova-compute-local -d 91.1.180.14/32 -j nova-compute-inst-122                        # “-d“ 决定了 nova 安全组只检查进入虚机的网络包
# \+ G( T( q1 s6 H4 G-A nova-compute-sg-fallback -j DROP                                                     #丢弃其它包,只允许上述规则指定的网络访问9 U1 }& _/ M, U
-A nova-filter-top -j nova-compute-local
/ ~! B  q" [% z/ y复制代码  f2 K9 U$ U2 c2 ~5 [# [0 T
2. FWaas
6 g, C, k/ B- {2 z1 u& n$ y# y! f2.1 概念  E- }' N( F6 ~
    从 Havana 版本开始,Neutron 提供一种基于 Neutron L3 Agent 的一种网络四层防火墙虚拟化参考实现 Firewall-as-a-service,简称 FWaas。本文的分析是基于 openstack Juno 版本进行的。Juno 版本中,FWaas 是分租户的,但是可以在多个租户之间共享。每个租户只允许一个防火墙。与物理的防火墙类似,FWaas 也有三个主要概念:8 _) P) E7 b# y
(1)规则(Rule):允许用户指定所要匹配的名称,描述,针对的协议(TCP, UDP, ICMP, ANY),行为(Allow,Deny),源/目的 IP 地址/子网 和 端口号/端口号区间。9 s& F1 O5 c  s' d- |5 E: b

0 @9 q  T0 Q4 }) I与 neutron 安全组中的规则的区别是,这里需要指定被匹配到的数据包的处理行为是通过(ALLOW)和不通过(DENY),但是不能指定网络方向。FWaas 会将规则同时应用到进出网络的网络包上。
! @/ Q7 k  i; p+ y8 C(2)策略(Policy):规则的逻辑集合。Policy 可以是共享的 和 被审计的(Audited)。目前,FWaas 只是把 “audited” 保存到 DB 中,并没有对它做任何处理。
$ V" S5 H7 W( J, i
+ \2 f' i$ Q) H9 Y4 g9 O(3)防火墙(Firewall):策略的逻辑集合。见上面右图。Juno 版本中,每个租户只能拥有最多一个 Firewall。防火墙可以是共享的。 ) t8 A8 z: B2 Q( g! o
    这里需要说明的是 FWaas 和 Security Group (安全组) 的区别。安全组规则在连接到一个实例的计算节点上的Linux桥 qbr 上实施,FWaaS 创建的防火墙规则在租户网络边缘实现的虚拟路由器上实施。 FWaaS 并不旨在取代安全组的功能,并且它提供更为补充安全组,特别是在其当前实现状态下。 FWaaS 目前缺乏安全组提供的一些功能,包括无法指定通信的方向等。与此相反,安全组,也因为他们缺乏创建特定规则拒绝所有流量的能力,因此需要 FWaas 作为补充。
+ S5 M( q* t% I) e! g8 \0 a
+ c" Y/ A9 }4 q. C8 Q1 W9 r
0 R& M4 G3 d& o2 \/ Z8 [, K2.2 配置/ f- E6 w1 O2 W+ K/ m8 l5 E; O
节点 配置和操作/ z: ?. _4 ?; J( ^1 x- l* k
控制节点上
0 e6 s4 ~) R5 d( H+ K修改 /etc/neutron/neutron.conf:( ~& ?0 R! e) X5 z, p( r
[default]; T1 e3 Y! f9 Q
service_plugins = router,lbaas,firewall
/ p" P0 X1 e( O7 U4 e4 F[service_providers]3 z1 M( {2 E) t0 S/ q) Q5 @# y
service_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default8 m/ |3 k; ~/ R' [+ B* G  e2 }
& t0 l  }. I9 f- c2 V1 k$ Y2 c
service neutron-server restart) ]; _' `) B# V6 }7 V% B
! h" ]; }' ~5 {) B& G4 i. w
修改 /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py:'enable_firewall': True
/ N! U- \) d9 l0 O网络节点上 5 E* r+ l; _  m+ X$ n& \/ L
修改 /etc/neutron/fwaas_driver.ini:
5 U2 K6 b0 i# a5 A- O! _[fwaas]
9 t2 L+ X; a# F: N  `/ f/ Bdriver = neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver
- M& D& @2 }  @, kenabled = True
4 I3 Q' U9 m" I0 F+ g# ]& z 0 y& R0 J& e9 f8 J! ?9 P9 B/ c
service neutron-l3-agent restart
% G4 }( Q' v- ?* u# \  J$ A  s7 W
& N: a9 n- }+ _. Y) u' _# [3 K1 q2.3 实现
; x1 [# y4 ~# b0 t4 @目前的实现中,FWaas 是通过在其所在 tenant 中的所有 Virtual Router 上添加 iptbales 规则来实现对进出数据网络的网络包进行控制的。* \" d( |6 E) T& @* e' E

. \, n( U$ M. w4 v6 Z代码实现:. O: }: T# B( t+ V
控制节点上(class FirewallPlugin):
( ^4 a( _7 p& @# H: p9 j* j: o6 G(1)create rule:纯数据库操作,将 rule 保存到数据中。6 v9 v8 M9 d7 J/ n
(2)create policy:纯数据库操作,将 policy 保存到数据中。. O8 L& P- X, B8 h% f
(3)如果将 rule 添加到一个已经添加到 firwall 的 policy,或者将一个 policy 加入一个存在的 firewall,在数据库操作后,通过 RPC fanout 到所有的 L3 Agent host:
2 w6 g4 @  h, x2 g9 T: K9 J{'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'}, m+ W) f6 A: @% I
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
5 |; x& F" G1 Ycreate_firewall -> Firewall_db_mixin.create_firewall -> FirewallAgentApi.create_firewall/ ?8 G: w1 L- O) K8 X0 X  v8 Q; Q6 v
update_firewall -> Firewall_db_mixin.update_firewall -> FirewallAgentApi.update_firewall# d3 i4 u& ]/ e- D
delete_firewall -> Firewall_db_mixin.delete_firewall -> FirewallAgentApi.delete_firewall
3 `* a  @$ i6 z" s+ i0 l( k# e% IFirewallAgentApi.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$ i/ S& `; B" P  A7 ^
网络节点上(class FWaaSL3AgentRpcCallback):6 U- ^6 U# ?- A
(1) 通过 RPC 获取所有的 router,在获取firewall 所在的 tenant 上的 routers
' W% d) M2 P0 ]  X  \4 ](2)调用 IptablesFwaasDriver.update_firewall,依次更新每个 router 的 iptables 规则% Z! E0 y2 g0 `1 d
(3)首先删除已有规则,然后根据配置的 rules 重新生成规则
$ b; P6 j7 G& ?复制代码8 x  m4 w1 ^9 G* s9 s' `$ H( x
root@network:/var/cache# ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 iptables -t filter -S8 d) K- R1 _9 e+ q, c7 s5 [
-P INPUT ACCEPT
# \& M  Q8 o1 w; P4 a' }3 F-P FORWARD ACCEPT8 G+ {3 L% s! @( J. d
-P OUTPUT ACCEPT
% B2 ~: \# `, {0 w-N neutron-filter-top( g0 h" T: c8 q+ h+ k4 c8 e2 i  _
-N neutron-l3-agent-FORWARD
* F6 l4 O& t0 B0 b( z-N neutron-l3-agent-INPUT
  x  Q6 l% {& l- _, A-N neutron-l3-agent-OUTPUT( M6 N) U: R7 L. ~
-N neutron-l3-agent-fwaas-defau #新增的 firewall chain
4 p1 F/ S$ F' e: J& J1 t+ J-N neutron-l3-agent-iv4aa85bd66 #新增的 firewall chain
' V) S' H+ k; R/ L6 m, P% u2 |-N neutron-l3-agent-local
, ~8 `( v% X) a' E% k  n0 h! A) V-N neutron-l3-agent-ov4aa85bd66 #for firewall- U2 x4 a$ k7 L& X# d4 N+ `
-A INPUT -j neutron-l3-agent-INPUT
* N# G; H# V$ M; k- K5 W" D  i4 F-A FORWARD -j neutron-filter-top! w- [6 r1 \, [$ W7 u: q
-A FORWARD -j neutron-l3-agent-FORWARD #将 forward 转到 neutron 的chain; @4 z" _5 ^6 s3 p% }& j
-A OUTPUT -j neutron-filter-top, O7 d* H* y, _
-A OUTPUT -j neutron-l3-agent-OUTPUT
6 ^3 i) K% O" o* |) g-A neutron-filter-top -j neutron-l3-agent-local
! Z1 z! `0 A5 z9 p. s$ i-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-iv4aa85bd66 #进数据网络的包& i9 M0 c$ h  m0 M- ?0 n2 P' i
-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-ov4aa85bd66 #出数据网络的包
) a3 ^, E5 u( K7 V" s-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-defau #进数据网络的包的默认处理 chain0 `+ w* M6 P; q) S5 \
-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-defau #出数据网络的包的默认处理 chain
, f" Q& j5 F0 k' T-A neutron-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT8 F! l4 U4 t8 ~6 C+ S" J
-A neutron-l3-agent-fwaas-defau -j DROP                             #默认丢弃没有被以上规则处理的所有包
4 f8 m2 @0 T! {5 B9 n-A neutron-l3-agent-iv4aa85bd66 -m state --state INVALID -j DROP7 H1 _) A6 O7 b
-A neutron-l3-agent-iv4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT #接受状态为 RELATED, ESTABLISHED (已建立的连接)的包
4 j5 n" d  d# Z# h" I0 M0 y; S& ?; t$ {-A neutron-l3-agent-iv4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT             #根据定义的 FWaas rule,接受目的端口为 80 的 tcp 包( v9 g) c- n& q0 E$ c- Y
-A neutron-l3-agent-ov4aa85bd66 -m state --state INVALID -j DROP' D. z: `0 e" z- g
-A neutron-l3-agent-ov4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT
7 B' [$ U3 @  I' X2 o-A neutron-l3-agent-ov4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT             #根据 FWaas rule,接收目的端口为 80 的 tcp 包
0 X" f& n$ c0 q% Q7 D  W! Z# @  u复制代码) y& ^1 D2 W7 S# O- f
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

站长推荐上一条 /4 下一条

北京云银创陇科技有限公司以云计算运维,代码开发

QQ|返回首页|Archiver|小黑屋|易陆发现技术论坛 点击这里给我发消息

GMT+8, 2026-4-8 10:34 , Processed in 0.067489 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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