- 积分
- 16840
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
1. Nova 安全组
9 S* L, ]$ \2 ?% b* {) p, H1 U1.1 配置
8 ?. L7 v4 ^7 D% f) K @3 r节点 配置文件 配置项 说明
$ q2 I( L( l9 r. F8 [: c: v& ccontroller /etc/nova/nova.conf security_group_api = nova 是的 nova secgroup* 命令使用的是 nova 安全组的 API
' {/ P2 F) A+ g' d. I/etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组
' c/ W1 |8 Q# Z6 [# onova-compute 5 L) D6 Z' _9 d
/etc/nova/nova.conf" ^( Z+ `/ Q6 o7 S( c( n8 B
/etc/nova/nova-compute.conf0 G5 S4 F' u1 @) f1 _
firewall_driver = nova.virt.firewall.IptablesFirewallDriver 指定 Nova 安全组的驱动,可以是IptablesFirewallDriver 或者 NWFilterFirewall。默认是 IptablesFirewallDriver。见下面的说明。
1 u4 _. W" Y& O5 e) D( b/ z /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组
! i8 g4 A+ S4 `# {5 l5 @% A$ @4 unetwork /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组
' ~4 }% J7 I: x: r+ D$ ~/ t5 O nova 提供两种实现方式:使用 libvirt's nwfilter 的实现以及使用 linux iptables 的实现,默认的方式是使用 linux iptables。可以通过设置配置项 firewall_driver 的值指定。需要注意的是,即使使用 iptables,依然使用了部分 nwfilter 功能。参见 https://ask.openstack.org/en/question/19456/how-security-group-is-implemented/
) t1 X2 e0 E% h# J2 Qfirewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver, F0 G/ \0 w( ^" ? j
firewall_driver=nova.virt.libvirt.firewall.NWFilterFirewall
8 @6 A8 h7 i7 |, A) M, z1.2 CLI
' R8 L0 v& W8 { u R# |0 ~复制代码0 Z% }! U3 m( z
列表安全组:3 I3 i0 O V3 M" [2 R" N/ a3 Y0 r
s1@controller:~$ nova secgroup-list-rules novasg1& N$ U3 u! Y5 i5 P9 @/ ^
+-------------+-----------+---------+-----------+--------------+
- L7 S8 ?, g3 y; e& v| IP Protocol | From Port | To Port | IP Range | Source Group |/ R2 d1 Y0 s) H) y1 L& d D
+-------------+-----------+---------+-----------+--------------+! u2 T8 _7 k+ o: k8 u( \; Z; P
| tcp | 22 | 22 | 0.0.0.0/0 | |) \! A, B, U* R
+-------------+-----------+---------+-----------+--------------+
4 a: V' f s* {: P3 o9 i: S2 O. q创建一个安全组规则:
% E; Z2 ` C2 l9 J3 D+ @, Y. qs1@controller:~$ nova secgroup-add-rule novasg1 udp 53 53 100.1.100.0/24
9 L& ]2 x( R& h. M, E" R- U+-------------+-----------+---------+----------------+--------------+
; @ S5 {+ k, X% z' M4 F1 D* m: x+ a| IP Protocol | From Port | To Port | IP Range | Source Group |
* i/ b# U, A8 M+-------------+-----------+---------+----------------+--------------+
! q0 S8 o$ F; ?/ b& ~/ O| udp | 53 | 53 | 100.1.100.0/24 | |
. o% S# e1 x5 w, `3 e4 R6 e5 w+-------------+-----------+---------+----------------+--------------+2 {% X4 Q* ~8 y" B q& | ~. V* `
删除虚机的安全组:; y6 J* ]" f! a& j0 J/ L
s1@controller:~$ nova remove-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
J; S. `2 b4 Y( O' B' x添加安全组到虚机:" r2 Y( F, q' s+ e3 N0 a
s1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1# u3 L, @) ^8 G1 k
创建第二个安全组:% p2 r- L; B1 I% i* B
s1@controller:~$ nova secgroup-add-rule novasg2
' L0 H# v; w) O1 K ?添加规则:, c4 a) e( {5 }% A: D+ Z
s1@controller:~$ nova secgroup-add-rule novasg2 icmp -1 -1 0.0.0.0/0( a. q1 I) Y/ U- X9 p. v
+-------------+-----------+---------+-----------+--------------+/ |0 c% z9 T* O1 b( z- w
| IP Protocol | From Port | To Port | IP Range | Source Group |% N8 A4 j) D- z* s
+-------------+-----------+---------+-----------+--------------+
4 i0 s; f# p& L; v! R, ?" R) V| icmp | -1 | -1 | 0.0.0.0/0 | |
" |8 ]3 ?7 H6 s# X7 `+-------------+-----------+---------+-----------+--------------+
+ a/ K' N8 l, G ~: ]2 u再添加安全组到虚机:" B$ N- d+ [9 a J
s1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg26 m5 z. M3 O8 W( M8 U
复制代码
8 Z2 j5 e: M6 X5 l1.3 iptables 链4 {) D% Z& ]; T0 E7 d6 ^
Nova-compute 增加了 filter 表的 INPUT,OUTPUT 和 FORWARD 链:$ i: q7 |4 p9 }7 M3 L3 G' k
5 Q# w' n; V# n+ r* a0 K0 k
复制代码
! b. k7 t! L7 f) ?) A4 U-N nova-compute-FORWARD
6 ~- a3 F7 b6 G. I. W: o-N nova-compute-INPUT
* r+ B/ H1 k2 i; u9 o-N nova-compute-OUTPUT _2 o$ e1 \ J8 M1 Q [4 j" }; p& O0 h
-N nova-compute-inst-122 #每个虚机一个链,命名规则是 ”inst“-<instance 在数据库中的 id>; X/ v; U4 f0 p; o5 i/ f: |: o
-N nova-compute-local2 G7 ]4 G' i4 i# S+ K
-N nova-compute-provider
/ l* J. Y4 R( M! J0 p. c-N nova-compute-sg-fallback {0 Q/ G7 C o. \. W9 X, D
-N nova-filter-top. [5 c$ }+ W$ C$ R% D, F8 t
-A INPUT -j nova-compute-INPUT& E, E' H: p& ?# t
-A FORWARD -j nova-filter-top& }3 m" T, B) ]: K# h" R6 ~; Z2 y
-A FORWARD -j nova-compute-FORWARD( ]: V' [$ u) M3 [% B ]
-A OUTPUT -j nova-filter-top
3 M2 g0 T1 _+ {6 T-A OUTPUT -j nova-compute-OUTPUT$ r8 }! F, y8 g
-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 广播
( p4 y4 m. u) [2 J4 r4 l6 v" K* h9 s" f-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 广播包
3 n7 ~! P _: T) W5 y7 r' D: U, F3 `-A nova-compute-inst-122 -m state --state INVALID -j DROP
& G8 a$ c$ [# Q-A nova-compute-inst-122 -m state --state RELATED,ESTABLISHED -j ACCEPT
1 n/ f5 `, s1 ~9 c$ }3 v; L-A nova-compute-inst-122 -j nova-compute-provider! Z) f9 p& _$ H5 U
-A nova-compute-inst-122 -s 91.1.180.2/32 -p udp -m udp --sport 67 --dport 68 -j ACCEPT #接受该虚机所在子网的 DHCP Server 返回的包9 g, ^) s7 d$ |7 t; }+ ~3 E5 T
-A nova-compute-inst-122 -s 91.1.180.0/24 -j ACCEPT #在配置项 allow_same_net_traffic = true 的情况下接受同网段虚机的来访包
4 Z2 |7 w0 J9 o6 c& M2 s" K-A nova-compute-inst-122 -p tcp -m tcp --dport 22 -j ACCEPT #用户安全组规则指定的来访包
* k. K8 M% J, Z* A n-A nova-compute-inst-122 -s 100.1.100.0/24 -p udp -m udp --dport 53 -j ACCEPT #用户安全组规则指定的来访包
. t; Q. Z) i+ I; b: \: d-A nova-compute-inst-122 -p icmp -j ACCEPT #用户安全组规则指定的来防爆' j6 w) s M/ P# B: {5 f
-A nova-compute-inst-122 -j nova-compute-sg-fallback #没被上面规则处理的其它来访包 , L& D$ }( \- X8 K
-A nova-compute-local -d 91.1.180.14/32 -j nova-compute-inst-122 # “-d“ 决定了 nova 安全组只检查进入虚机的网络包
. [' ]: i' P+ H-A nova-compute-sg-fallback -j DROP #丢弃其它包,只允许上述规则指定的网络访问
: H: T. x5 f( {4 v! x-A nova-filter-top -j nova-compute-local
{$ Y& p, H$ b复制代码4 C1 x. `+ M/ n; t, {1 g5 q/ \
2. FWaas
- G9 ]( M- F: K- I2.1 概念! r1 V t/ G' N$ d1 d, C2 b9 X# d
从 Havana 版本开始,Neutron 提供一种基于 Neutron L3 Agent 的一种网络四层防火墙虚拟化参考实现 Firewall-as-a-service,简称 FWaas。本文的分析是基于 openstack Juno 版本进行的。Juno 版本中,FWaas 是分租户的,但是可以在多个租户之间共享。每个租户只允许一个防火墙。与物理的防火墙类似,FWaas 也有三个主要概念:
( `2 i/ ]0 K# @4 S! A* _; y8 L (1)规则(Rule):允许用户指定所要匹配的名称,描述,针对的协议(TCP, UDP, ICMP, ANY),行为(Allow,Deny),源/目的 IP 地址/子网 和 端口号/端口号区间。
1 T7 I. _/ O: h1 p: Q. ]: C5 d, e* w4 t& T1 ?
与 neutron 安全组中的规则的区别是,这里需要指定被匹配到的数据包的处理行为是通过(ALLOW)和不通过(DENY),但是不能指定网络方向。FWaas 会将规则同时应用到进出网络的网络包上。
7 P: u F8 S0 c4 y8 v" ](2)策略(Policy):规则的逻辑集合。Policy 可以是共享的 和 被审计的(Audited)。目前,FWaas 只是把 “audited” 保存到 DB 中,并没有对它做任何处理。( c# K5 p8 @. w$ h6 ^ R
6 S* l% k( N' j$ y(3)防火墙(Firewall):策略的逻辑集合。见上面右图。Juno 版本中,每个租户只能拥有最多一个 Firewall。防火墙可以是共享的。
1 k( z/ [) h/ f- R# W6 \ 这里需要说明的是 FWaas 和 Security Group (安全组) 的区别。安全组规则在连接到一个实例的计算节点上的Linux桥 qbr 上实施,FWaaS 创建的防火墙规则在租户网络边缘实现的虚拟路由器上实施。 FWaaS 并不旨在取代安全组的功能,并且它提供更为补充安全组,特别是在其当前实现状态下。 FWaaS 目前缺乏安全组提供的一些功能,包括无法指定通信的方向等。与此相反,安全组,也因为他们缺乏创建特定规则拒绝所有流量的能力,因此需要 FWaas 作为补充。
& c0 ]% }% l4 E" [7 C; @/ Y R) |
6 J f4 d/ D/ @/ W' T; E" Z" N; i0 X* [/ r* ~, w4 T( C5 B" P9 b
2.2 配置. o5 t+ m8 m8 O5 F9 H
节点 配置和操作
! C% t+ J' P( p v- N& Y x控制节点上 + T R6 D# R, K9 \" S' r( ~
修改 /etc/neutron/neutron.conf:1 l1 p( ]( y4 `
[default]3 K3 P4 K) \7 B8 ^2 o' U
service_plugins = router,lbaas,firewall' d/ ]$ U2 q2 A, [* X: ^( \
[service_providers]9 F- t; h3 |& N: V: o8 K7 W
service_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default1 y9 K6 V/ h3 Y Z
4 X4 R3 \* O; \2 W4 Cservice neutron-server restart; x! n0 B' j% T. v' Q+ f
$ s3 c6 ?# @& E修改 /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py:'enable_firewall': True
3 t* k8 @7 E; S4 I( b网络节点上
H! b+ ~4 i, S0 g- N* i修改 /etc/neutron/fwaas_driver.ini:
" [7 f. e( }. s5 |) |[fwaas]9 ~/ D" S M. b+ r
driver = neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver
/ K: b: s7 D* B/ i; A& a @6 Uenabled = True
! d, j! L% U# |- S
/ i: A9 O8 N3 X! V% Sservice neutron-l3-agent restart4 z3 z/ ]- { `' r0 H
. `/ V$ y, w% D# i' p/ |9 T5 G4 q
2.3 实现
3 P* ?% ?4 ^8 W目前的实现中,FWaas 是通过在其所在 tenant 中的所有 Virtual Router 上添加 iptbales 规则来实现对进出数据网络的网络包进行控制的。& D% u: Q4 J1 T; V v3 _! S/ c
# d1 M8 K! t) u$ C5 p$ Y3 k1 B6 g代码实现:$ ?# C/ j" m/ _( E# ?, n
控制节点上(class FirewallPlugin):
+ p; s9 V+ A! E. q(1)create rule:纯数据库操作,将 rule 保存到数据中。
/ q& O k. _/ ~; `* M(2)create policy:纯数据库操作,将 policy 保存到数据中。5 _, K) V* u7 a+ T$ t: t2 Q; e6 K
(3)如果将 rule 添加到一个已经添加到 firwall 的 policy,或者将一个 policy 加入一个存在的 firewall,在数据库操作后,通过 RPC fanout 到所有的 L3 Agent host:# t. I- B( }$ I+ A5 {# e* k7 A
{'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'}, Z: S# k; c: H9 i$ }% H
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
- f8 o" {# V4 C7 R( f: hcreate_firewall -> Firewall_db_mixin.create_firewall -> FirewallAgentApi.create_firewall @2 A* a) @3 E5 U: X5 `
update_firewall -> Firewall_db_mixin.update_firewall -> FirewallAgentApi.update_firewall6 P$ [: L& g0 x3 U# c
delete_firewall -> Firewall_db_mixin.delete_firewall -> FirewallAgentApi.delete_firewall! J8 N' g2 b: a
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
- m, N# m Y: }2 k0 q. K* u/ L 网络节点上(class FWaaSL3AgentRpcCallback):( Z$ q' S" o2 l5 M% g: W
(1) 通过 RPC 获取所有的 router,在获取firewall 所在的 tenant 上的 routers% k+ V7 S$ h4 @& H5 X3 ~
(2)调用 IptablesFwaasDriver.update_firewall,依次更新每个 router 的 iptables 规则
* O, _2 \' `8 B% s! y3 @- Z(3)首先删除已有规则,然后根据配置的 rules 重新生成规则
3 u8 s3 T. M8 s; W8 {' Z2 o' R* v复制代码
# O6 h7 {) A' h$ `$ Q" L1 H" Iroot@network:/var/cache# ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 iptables -t filter -S
9 I I& v4 y H$ t-P INPUT ACCEPT. T' I8 S, k& q
-P FORWARD ACCEPT
- g( M- x5 a$ k' f' O, V-P OUTPUT ACCEPT
+ F% s X$ V8 f6 Z, Q2 t-N neutron-filter-top
' o3 R {6 k+ Q% A, u2 g2 [-N neutron-l3-agent-FORWARD, `- T7 O$ X" O) x: x
-N neutron-l3-agent-INPUT
2 c( ~- t. t1 j-N neutron-l3-agent-OUTPUT
. P0 k/ ]7 \# v-N neutron-l3-agent-fwaas-defau #新增的 firewall chain+ Y" P5 A J$ n
-N neutron-l3-agent-iv4aa85bd66 #新增的 firewall chain1 Y. j6 c$ p( q n/ I6 r2 P
-N neutron-l3-agent-local
4 c j7 x* _; ~$ i-N neutron-l3-agent-ov4aa85bd66 #for firewall
0 ? F: K2 _! S8 _" i-A INPUT -j neutron-l3-agent-INPUT
5 y7 g5 @, c2 X! E-A FORWARD -j neutron-filter-top6 }# F5 l2 y0 h ^2 @
-A FORWARD -j neutron-l3-agent-FORWARD #将 forward 转到 neutron 的chain/ d5 k$ E3 \* B' N/ Q# D
-A OUTPUT -j neutron-filter-top' y+ }7 @. Q$ x
-A OUTPUT -j neutron-l3-agent-OUTPUT
4 n; Q, ?& E g3 h/ e-A neutron-filter-top -j neutron-l3-agent-local
3 J6 b& O8 j7 c: `-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-iv4aa85bd66 #进数据网络的包
3 t- Q2 |+ s7 S* g. N& q3 a$ K-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-ov4aa85bd66 #出数据网络的包) \/ M# } D9 I. [; t
-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-defau #进数据网络的包的默认处理 chain
* r* _6 ?! c# Q5 C) j-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-defau #出数据网络的包的默认处理 chain& }# z2 ?7 F6 ^5 x/ U
-A neutron-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT2 g* P* d+ |" Z. l' O1 N
-A neutron-l3-agent-fwaas-defau -j DROP #默认丢弃没有被以上规则处理的所有包$ `0 A# | G% t
-A neutron-l3-agent-iv4aa85bd66 -m state --state INVALID -j DROP! P8 H# J; ?5 [/ V- L/ Y& a
-A neutron-l3-agent-iv4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT #接受状态为 RELATED, ESTABLISHED (已建立的连接)的包
' l2 J& K2 g n* z1 [-A neutron-l3-agent-iv4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT #根据定义的 FWaas rule,接受目的端口为 80 的 tcp 包
! Q T1 r& u) Q, p4 {5 \- e-A neutron-l3-agent-ov4aa85bd66 -m state --state INVALID -j DROP
- j, |6 B6 i0 ]/ X! b b1 A-A neutron-l3-agent-ov4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT
/ ^% N' [7 t' D6 z- e$ F- H-A neutron-l3-agent-ov4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT #根据 FWaas rule,接收目的端口为 80 的 tcp 包" v3 n7 M3 m* k# ]4 e
复制代码) k' ]1 f2 v, ~2 S! V0 }1 w
|
|