|
|
1. Nova 安全组
8 U5 g R3 n" ]: @ {4 ?; X L1.1 配置4 ?3 ~6 g1 H; {% M
节点 配置文件 配置项 说明/ {( V; h6 n0 L2 |) N5 T C O
controller /etc/nova/nova.conf security_group_api = nova 是的 nova secgroup* 命令使用的是 nova 安全组的 API
9 d0 H' Q: f8 Y" V+ _7 A* K/etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组3 y% Z6 Y, N! v0 {) T
nova-compute + d$ i5 Y: ^' { ?) K4 ^: u) r
/etc/nova/nova.conf. q$ D# \4 E% {% [3 D! t
/etc/nova/nova-compute.conf# G0 T' t5 r; H5 N& v
firewall_driver = nova.virt.firewall.IptablesFirewallDriver 指定 Nova 安全组的驱动,可以是IptablesFirewallDriver 或者 NWFilterFirewall。默认是 IptablesFirewallDriver。见下面的说明。+ W# H$ c* R7 i3 _
/etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组. s) f8 J* ]# i+ J6 s' }* z+ d j
network /etc/neutron/plugins/ml2/ml2_conf.ini enable_security_group = False 禁止 Neutron 安全组- c+ }8 _# i: U: _/ Y
nova 提供两种实现方式:使用 libvirt's nwfilter 的实现以及使用 linux iptables 的实现,默认的方式是使用 linux iptables。可以通过设置配置项 firewall_driver 的值指定。需要注意的是,即使使用 iptables,依然使用了部分 nwfilter 功能。参见 https://ask.openstack.org/en/question/19456/how-security-group-is-implemented/* J' {' p3 x! P- G: i
firewall_driver=nova.virt.libvirt.firewall.IptablesFirewallDriver, a$ v; @6 a0 h1 A% p6 \
firewall_driver=nova.virt.libvirt.firewall.NWFilterFirewall9 K4 @ q9 F3 i$ H
1.2 CLI" e) g% V9 ]4 m7 N, ~( G u
复制代码5 q" Y) ^3 C6 m/ v0 P" [9 O
列表安全组:
+ M% Q; j' C% C! R2 F8 ws1@controller:~$ nova secgroup-list-rules novasg11 `' [2 D# \5 N3 H) \2 V+ Q
+-------------+-----------+---------+-----------+--------------+
9 B5 e! {6 K/ |+ J# L8 X| IP Protocol | From Port | To Port | IP Range | Source Group |
4 O. n6 G8 }0 C8 q& |$ i+-------------+-----------+---------+-----------+--------------+
* \8 S P( z' Z| tcp | 22 | 22 | 0.0.0.0/0 | |8 m) \! g) w# T
+-------------+-----------+---------+-----------+--------------+
+ R% m2 T: I3 i7 i% l, S/ L* e创建一个安全组规则:
6 ?4 ^7 Z! n) Q) J, f/ js1@controller:~$ nova secgroup-add-rule novasg1 udp 53 53 100.1.100.0/24) u4 `# S6 v8 j# u' B: I
+-------------+-----------+---------+----------------+--------------+) i% g% Y t0 V1 B {+ G
| IP Protocol | From Port | To Port | IP Range | Source Group |
4 S! Q4 N( \4 ?! s+-------------+-----------+---------+----------------+--------------+
$ C% ]4 T3 O9 p3 D| udp | 53 | 53 | 100.1.100.0/24 | |
2 w0 i5 h1 m1 R0 B$ Y) E! j+-------------+-----------+---------+----------------+--------------+) S! }3 [7 R3 j' B* V) K Y
删除虚机的安全组:' s$ e7 y" s- k* j
s1@controller:~$ nova remove-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
" X8 k! w6 m7 F添加安全组到虚机:
5 V2 \1 }; y9 R1 O2 B6 d5 D5 is1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg1
2 T9 E0 c5 }* z9 x9 D! P0 g创建第二个安全组:
3 V* i( h! J) m# j* ~, {0 fs1@controller:~$ nova secgroup-add-rule novasg2
1 R( t) T1 I8 {2 W6 L) ^添加规则:& l0 C9 R# ?% M- y
s1@controller:~$ nova secgroup-add-rule novasg2 icmp -1 -1 0.0.0.0/0
3 a9 ~4 a- H& H% ~1 V+-------------+-----------+---------+-----------+--------------+* M8 e$ \1 W6 w# s ~
| IP Protocol | From Port | To Port | IP Range | Source Group |9 ]. R$ M: J) d" c" | _4 J
+-------------+-----------+---------+-----------+--------------+
3 h5 n! i( y1 O; U% m2 U| icmp | -1 | -1 | 0.0.0.0/0 | |3 Z- x. e$ ]5 o2 f$ v
+-------------+-----------+---------+-----------+--------------+
$ E' t' k- U; ?再添加安全组到虚机:
7 d9 G* x0 x4 us1@controller:~$ nova add-secgroup 2c59a875-bc23-4605-ad70-5315d7a3f8e2 novasg2+ S1 i( J' E- ^* E; _( g3 {( P, J7 x
复制代码1 y2 ^& v/ J' o3 q0 _' w
1.3 iptables 链
" C& n6 K- c Z* j n7 h7 K8 FNova-compute 增加了 filter 表的 INPUT,OUTPUT 和 FORWARD 链:1 R; t: H. U. D; T: z
; K, {. t4 G: I" m& r
复制代码
x% j3 v7 e5 y- ]* B-N nova-compute-FORWARD7 c( w, ~2 Q- i0 B; z1 P
-N nova-compute-INPUT* R- i7 x4 M9 O/ G6 a- t% Z
-N nova-compute-OUTPUT
; K2 D' ]& @$ ]1 C" m6 U$ S-N nova-compute-inst-122 #每个虚机一个链,命名规则是 ”inst“-<instance 在数据库中的 id>
; o+ Q, j# V9 F9 |8 V-N nova-compute-local n/ x7 L3 _& w/ ^3 |) k$ ]
-N nova-compute-provider
/ D& j# U( U: J6 @-N nova-compute-sg-fallback
9 l: O" R2 f c" W-N nova-filter-top
" t8 p6 Q8 H! b6 s. b: [( F7 h-A INPUT -j nova-compute-INPUT
+ z0 a2 p/ P( A4 f8 ]7 s! q. s-A FORWARD -j nova-filter-top
8 S. S: m) H" M-A FORWARD -j nova-compute-FORWARD
1 |1 N( z; j8 ~2 }-A OUTPUT -j nova-filter-top9 M5 a- j& X+ L3 t/ R! t
-A OUTPUT -j nova-compute-OUTPUT& W) r4 e, E, p6 E' h
-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 广播
1 ~0 L9 K. V5 T8 G. p-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 广播包
6 ?& d6 s& V( P( D8 H4 c-A nova-compute-inst-122 -m state --state INVALID -j DROP9 o i3 U; x8 F
-A nova-compute-inst-122 -m state --state RELATED,ESTABLISHED -j ACCEPT6 _# o9 J3 x1 _! H2 S. P1 {7 f
-A nova-compute-inst-122 -j nova-compute-provider
; ?" R# F- a3 v' r-A nova-compute-inst-122 -s 91.1.180.2/32 -p udp -m udp --sport 67 --dport 68 -j ACCEPT #接受该虚机所在子网的 DHCP Server 返回的包2 o" I' D, u" p! @4 [) z
-A nova-compute-inst-122 -s 91.1.180.0/24 -j ACCEPT #在配置项 allow_same_net_traffic = true 的情况下接受同网段虚机的来访包
5 L- u: p! w t! k+ J6 l6 r-A nova-compute-inst-122 -p tcp -m tcp --dport 22 -j ACCEPT #用户安全组规则指定的来访包4 @# u. s1 a" E" l! x) R6 X+ U9 n
-A nova-compute-inst-122 -s 100.1.100.0/24 -p udp -m udp --dport 53 -j ACCEPT #用户安全组规则指定的来访包
1 J+ J' O2 l7 _2 b-A nova-compute-inst-122 -p icmp -j ACCEPT #用户安全组规则指定的来防爆
7 P" g3 }- {4 V/ e2 O, E-A nova-compute-inst-122 -j nova-compute-sg-fallback #没被上面规则处理的其它来访包
% y4 X4 | f1 r D4 |, G7 z* p-A nova-compute-local -d 91.1.180.14/32 -j nova-compute-inst-122 # “-d“ 决定了 nova 安全组只检查进入虚机的网络包# K4 q' u" |& u* T5 h
-A nova-compute-sg-fallback -j DROP #丢弃其它包,只允许上述规则指定的网络访问
8 A& I/ S! M: W6 A$ w/ u-A nova-filter-top -j nova-compute-local
5 w! J8 C( k! N u复制代码4 `7 z: k, {/ ]4 D
2. FWaas) B, o- L p! e5 _: D
2.1 概念
" O2 a- Y& C2 I( D3 n- K 从 Havana 版本开始,Neutron 提供一种基于 Neutron L3 Agent 的一种网络四层防火墙虚拟化参考实现 Firewall-as-a-service,简称 FWaas。本文的分析是基于 OpenStack Juno 版本进行的。Juno 版本中,FWaas 是分租户的,但是可以在多个租户之间共享。每个租户只允许一个防火墙。与物理的防火墙类似,FWaas 也有三个主要概念:
$ [7 | R+ g6 U) ~' X/ U, ] (1)规则(Rule):允许用户指定所要匹配的名称,描述,针对的协议(TCP, UDP, ICMP, ANY),行为(Allow,Deny),源/目的 IP 地址/子网 和 端口号/端口号区间。
( E; R: z6 H( F( w9 e+ H) b: H. F% _' I5 o* O; u
与 neutron 安全组中的规则的区别是,这里需要指定被匹配到的数据包的处理行为是通过(ALLOW)和不通过(DENY),但是不能指定网络方向。FWaas 会将规则同时应用到进出网络的网络包上。, ]/ G7 a( k' ]; f% d% p; ?- Q
(2)策略(Policy):规则的逻辑集合。Policy 可以是共享的 和 被审计的(Audited)。目前,FWaas 只是把 “audited” 保存到 DB 中,并没有对它做任何处理。; l3 J" s. y6 l8 i
9 Y+ }4 V/ Z% @4 Q) P
(3)防火墙(Firewall):策略的逻辑集合。见上面右图。Juno 版本中,每个租户只能拥有最多一个 Firewall。防火墙可以是共享的。
7 @. _$ y8 q+ ]( F: B2 n! H% M) l 这里需要说明的是 FWaas 和 Security Group (安全组) 的区别。安全组规则在连接到一个实例的计算节点上的Linux桥 qbr 上实施,FWaaS 创建的防火墙规则在租户网络边缘实现的虚拟路由器上实施。 FWaaS 并不旨在取代安全组的功能,并且它提供更为补充安全组,特别是在其当前实现状态下。 FWaaS 目前缺乏安全组提供的一些功能,包括无法指定通信的方向等。与此相反,安全组,也因为他们缺乏创建特定规则拒绝所有流量的能力,因此需要 FWaas 作为补充。
! [2 r! `, f9 d9 l5 U4 p9 b- l& l+ y; {6 ~* l; h; j/ F
r* u; b8 v8 Z& `4 S2 O2.2 配置7 }3 E% T5 G/ D( _ X" J% ?
节点 配置和操作% s, `& ]( ~7 l, H7 x; m$ A
控制节点上 ; I5 R) P3 c+ B& T/ f/ @- t+ E
修改 /etc/neutron/neutron.conf:' _6 F* T% H0 c! V' S
[default]
/ M3 L9 `9 ?- b5 d& cservice_plugins = router,lbaas,firewall. p$ W b& n2 M8 Q/ w
[service_providers]
. y) y" P" x& Wservice_provider = FIREWALL:Iptables:neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver:default5 g- [) {1 t) b, V& X; s
0 u5 j. r4 ~8 D9 [3 G" kservice neutron-server restart/ S. u* t6 ]9 Y0 e2 M
# |1 T$ N5 b* a! _6 k# O
修改 /usr/share/openstack-dashboard/openstack_dashboard/local/local_settings.py:'enable_firewall': True4 {' a: q6 K' R( r" n5 L3 X9 x+ l
网络节点上
$ d6 k- X5 y5 o修改 /etc/neutron/fwaas_driver.ini:
) ?2 x# o7 V' G( z3 D. j[fwaas]
( e" J/ s! S a2 Odriver = neutron.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver
+ ~' z0 g! o2 ]5 Renabled = True
4 G- s" x" Y' c, S1 ?8 f g
! s; Q% U8 C1 N, zservice neutron-l3-agent restart2 _0 g& z; K, T. L& P
- q: k" U) I. `5 q! |5 @: ` ?2.3 实现& v3 P& A; b/ U7 m3 H# o
目前的实现中,FWaas 是通过在其所在 tenant 中的所有 Virtual Router 上添加 iptbales 规则来实现对进出数据网络的网络包进行控制的。5 Q! h+ v( Y& F! C
& z% K* c/ |6 `) p6 u代码实现:
* L3 ?# Q$ \+ V6 U# l2 ?控制节点上(class FirewallPlugin):0 i! U9 t2 ~& ^" i! u3 U, Z+ q
(1)create rule:纯数据库操作,将 rule 保存到数据中。
3 x+ _9 P# v3 Y9 S(2)create policy:纯数据库操作,将 policy 保存到数据中。0 \1 d& P+ v+ q) e
(3)如果将 rule 添加到一个已经添加到 firwall 的 policy,或者将一个 policy 加入一个存在的 firewall,在数据库操作后,通过 RPC fanout 到所有的 L3 Agent host:% m! _1 ]* D* q6 e. i1 Y" Q1 C t8 Q
{'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'}! E! X0 B- X {2 t
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" g ?" m. ~4 G! f9 f
create_firewall -> Firewall_db_mixin.create_firewall -> FirewallAgentApi.create_firewall
' s0 L4 r9 j+ Z8 Nupdate_firewall -> Firewall_db_mixin.update_firewall -> FirewallAgentApi.update_firewall
# {8 S" U+ p3 }$ zdelete_firewall -> Firewall_db_mixin.delete_firewall -> FirewallAgentApi.delete_firewall
7 a$ h& d/ Y7 V9 f ~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_api7 d1 C; H3 p p) m7 p+ S
网络节点上(class FWaaSL3AgentRpcCallback):
6 w* W' `1 T/ p4 C7 R' V* ]5 i1 ?(1) 通过 RPC 获取所有的 router,在获取firewall 所在的 tenant 上的 routers
+ J! w2 Y/ t$ \ h- p(2)调用 IptablesFwaasDriver.update_firewall,依次更新每个 router 的 iptables 规则1 r$ [* v4 u2 r3 v3 \, j' C' [
(3)首先删除已有规则,然后根据配置的 rules 重新生成规则
5 z5 S; ~6 X' W3 s+ _. ?5 d复制代码( K7 I5 d$ e1 u2 G+ v
root@network:/var/cache# ip netns exec qrouter-e438bebe-6795-4b68-a613-ec0df38d3064 iptables -t filter -S& r- B- V! g7 `
-P INPUT ACCEPT' a1 E# G- Y- `9 n( h! ?; k
-P FORWARD ACCEPT
- ~& W2 f- p$ u! _ Z-P OUTPUT ACCEPT% p& x2 R6 w( V% `; E
-N neutron-filter-top
/ ~( Z% p& ]( ?$ \$ ~-N neutron-l3-agent-FORWARD& u& r% {" T7 [1 ?+ F+ ~7 O+ g
-N neutron-l3-agent-INPUT5 r, m/ u3 e. ~7 ?
-N neutron-l3-agent-OUTPUT5 f( G( N+ V$ }0 B+ h* }
-N neutron-l3-agent-fwaas-defau #新增的 firewall chain7 z& t9 z: W8 R4 b. r- O/ S
-N neutron-l3-agent-iv4aa85bd66 #新增的 firewall chain' a$ ?7 _2 H& }6 M3 x
-N neutron-l3-agent-local% X6 U& _5 z7 ?$ j0 [
-N neutron-l3-agent-ov4aa85bd66 #for firewall
. j! x2 D% O' C7 C9 C8 W/ m. D-A INPUT -j neutron-l3-agent-INPUT' s. n @! A1 Q z4 W
-A FORWARD -j neutron-filter-top) C$ ], }1 ~7 R
-A FORWARD -j neutron-l3-agent-FORWARD #将 forward 转到 neutron 的chain7 {$ V9 `; P2 e5 u/ v+ o8 x
-A OUTPUT -j neutron-filter-top
1 K& Y& ^3 y- S- u-A OUTPUT -j neutron-l3-agent-OUTPUT
/ g+ o% o P. R' m7 N! @* l0 C-A neutron-filter-top -j neutron-l3-agent-local1 D: V' U" I' ^* ~4 x
-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-iv4aa85bd66 #进数据网络的包
+ a6 q, s9 D4 K7 Y8 q-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-ov4aa85bd66 #出数据网络的包/ W' v8 W I, |; n8 h# {( f
-A neutron-l3-agent-FORWARD -o qr-+ -j neutron-l3-agent-fwaas-defau #进数据网络的包的默认处理 chain
/ J! G. s* D3 e0 H3 }. V-A neutron-l3-agent-FORWARD -i qr-+ -j neutron-l3-agent-fwaas-defau #出数据网络的包的默认处理 chain- W( M; [9 y% r
-A neutron-l3-agent-INPUT -d 127.0.0.1/32 -p tcp -m tcp --dport 9697 -j ACCEPT: h+ O% ]6 l8 H1 U2 g1 l
-A neutron-l3-agent-fwaas-defau -j DROP #默认丢弃没有被以上规则处理的所有包
+ K5 ?: E8 W; R2 A9 V$ L0 ^-A neutron-l3-agent-iv4aa85bd66 -m state --state INVALID -j DROP
' q4 t" _( v3 ?! f% ]/ h-A neutron-l3-agent-iv4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT #接受状态为 RELATED, ESTABLISHED (已建立的连接)的包
9 P. Q5 W. I, L" J-A neutron-l3-agent-iv4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT #根据定义的 FWaas rule,接受目的端口为 80 的 tcp 包 G4 m3 L r" l1 @( W8 H
-A neutron-l3-agent-ov4aa85bd66 -m state --state INVALID -j DROP" d! f4 r, I, Z$ D# i
-A neutron-l3-agent-ov4aa85bd66 -m state --state RELATED,ESTABLISHED -j ACCEPT
+ N9 X' h4 n7 }-A neutron-l3-agent-ov4aa85bd66 -p tcp -m tcp --dport 80 -j ACCEPT #根据 FWaas rule,接收目的端口为 80 的 tcp 包
6 u& V3 Z1 G" x复制代码8 [0 [' ^) h7 G
|
|