|
|
关于OpenStack中虚拟机VNC访问安全问题
2 L2 |* y3 J+ e前几天收到甲方给出的文件信息,线上OpenStack环境的物理机VNC端口能够自由访问,要求整改。
& y! J: F' |5 ~/ d1 c$ _" h! O随机抽查了两台宿主机的VNC端口,确实很多业务的同学使用noVNC后没有退出终端的习惯,往往都是用完了就直接关闭窗口。不得不说这样隐患很大啊,首先不说通过外部方式规避风险,如果内网里面有一些script kiddie随时都能将我们线上的虚拟机VNC端口扫出来干些坏事。我这里也用过nmap测试了下开发环境的网络端口,如下:
* k8 o. u5 q5 ^4 g9 J- x6 z; Z* d[root@controller1 ~]# nmap 10.161.53.1
5 ?" B8 B! |7 o! S7 y# N: ]/ UStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST; O! j: |0 s0 \) @2 k4 u* e
Nmap scan report for compute10 (10.161.53.1)! j1 q5 p U+ g4 i% D$ [8 F. s) K% l
Host is up (0.000080s latency).
) @$ N+ p3 l, yNot shown: 989 closed ports
- \8 ^+ K$ o- M% XPORT STATE SERVICE* \: Q& ^9 g' @8 z; F1 E$ g+ {5 i
22/tcp open ssh# I8 T( O+ Q4 A! a2 P' C
5900/tcp open vnc) ?5 G. _' k, `; W2 b
5901/tcp open vnc-1& c& F' K( B1 {$ @# y% y/ h
5902/tcp open vnc-2; @- E) @0 u9 t5 T- W: A# _0 A
5903/tcp open vnc-3
: q0 c+ m; Y8 U) r4 f X3 J5904/tcp open unknown- [& \* T- F) ~5 x1 n+ ^" f8 q
5906/tcp open unknown
9 a. c. K# _! O6 J: U5907/tcp open unknown6 U/ Y" j9 j' a& b" o
5910/tcp open cm
/ [9 U! e6 f* b) J( K4 I9 E5911/tcp open cpdlc
" w" R( Q% @& b4 j# C8022/tcp open oa-system
7 o( P) y$ p5 a8 Q" CMAC Address: D4:5D:64:08:45:02 (Unknown)
, E7 t- c& n- ?* [2 QNmap done: 1 IP address (1 host up) scanned in 1.65 seconds* H, F; L/ U# c: f/ w K# L% h9 v
[root@controller1 ~]# nmap 10.161.53.2
; X$ y2 F- x2 ^) T' W2 }Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST
2 \. A; ]0 n2 ^& P5 m* ONmap scan report for compute11 (10.161.53.2)( R& e, X9 w' F( a5 n8 q
Host is up (0.000070s latency).
% s6 Y* V y" Z. y6 R& h" b4 oNot shown: 989 closed ports. ?4 d& z' |' R4 G* a* w6 g6 b. L
PORT STATE SERVICE
2 _. k, q; S' X7 u22/tcp open ssh" d! f6 c' X" P# `/ G9 _
5900/tcp open vnc5 o+ |$ _) ?1 _
5901/tcp open vnc-1
: v0 a- y# j# L5902/tcp open vnc-2
; _$ ]2 J5 i3 I* ]. p5903/tcp open vnc-3
" y' [# g( P7 I8 A5904/tcp open unknown
4 h0 F5 `5 N, }7 L* R5906/tcp open unknown% k, e, V# s- }2 ` Z
5907/tcp open unknown
1 M/ j8 X3 S0 P: s5911/tcp open cpdlc( E2 C8 `; S* m+ k2 I2 M3 T
5915/tcp open unknown1 g+ p2 e( f* s# E" s: Z8 L0 o
8022/tcp open oa-system" R0 S- X5 X6 Y9 W
MAC Address: D4:5D:64:07:B3:DA (Unknown)
' m H/ d, A% D5 W" r& xNmap done: 1 IP address (1 host up) scanned in 1.67 seconds5 @/ F9 c* I, E# Q8 R0 ?! H) m3 e
[root@controller1 ~]# nmap 10.161.53.3! F ~, p4 \0 u- h$ Z, y1 N- X1 n: H
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST9 X' \; z) r& @: l0 l+ Q# z
Nmap scan report for compute01 (10.161.53.3)! c9 @# Y9 w& d; R2 b5 @4 E5 Y' C
Host is up (0.000076s latency).
/ ~! d; O, Z. }& sNot shown: 992 closed ports+ g* a, W M+ \ w7 g6 P4 Y
PORT STATE SERVICE6 }7 \" x0 U. K# \- x
22/tcp open ssh$ h9 V) Q7 ]7 w' W: Y
5900/tcp open vnc, h* O I0 A. u' {9 C6 d" f# Z
5901/tcp open vnc-1% @- L& T' w# w
5902/tcp open vnc-2
' X- D" Z* w. d# H: W. i5903/tcp open vnc-3
2 S2 \- g8 k0 O; i% S5904/tcp open unknown5 c) z- J8 ?' e. W
5906/tcp open unknown
: h# o# b: y H9 ^1 Z6 I8022/tcp open oa-system+ K3 r! Z! W# P! H9 s
MAC Address: D4:5D:64:08:45:5E (Unknown)
1 }. a- D* b0 W$ uNmap done: 1 IP address (1 host up) scanned in 1.68 seconds
" q+ Y8 s. W8 A[root@controller1 ~]# nmap 10.161.53.4
. B: H& N9 p7 Z9 O) C, F6 e% IStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST( h4 u) z9 `, _9 L2 w$ v: i! h
Nmap scan report for compute02 (10.161.53.4)4 u: O4 I7 H3 o( S& l
Host is up (0.000081s latency).
& [6 }$ b8 r W( \2 WNot shown: 988 closed ports
4 q* y; C! V: a# L- n5 _PORT STATE SERVICE5 v+ S; }7 R+ O2 L! g! Z
22/tcp open ssh
% D2 G$ \# g& J1 ]! j. @5900/tcp open vnc, U; A, n! D E/ c( [: r
5901/tcp open vnc-1
. ]+ Y" T6 J6 i; Q$ ]: E0 m5902/tcp open vnc-2. u1 F: b9 G: B+ n" t, s
5903/tcp open vnc-3
0 P0 o# y5 e6 ]/ ~9 o. ^. L$ ^2 [5904/tcp open unknown% _9 R% H8 P3 \2 ^: W
5906/tcp open unknown
* K$ g/ @0 F2 I) `* s! A5907/tcp open unknown
; B n5 D0 s# y0 R" o1 A5910/tcp open cm: J* Z! N G) v2 K
5911/tcp open cpdlc
: W/ D9 t H+ a! B1 K5915/tcp open unknown9 M4 N( L/ g. H, y' Q- t6 ]
8022/tcp open oa-system
+ m+ |4 ?: _8 ~& QMAC Address: D4:5D:64:08:45:D6 (Unknown)
E. i- J' A j, i5 JNmap done: 1 IP address (1 host up) scanned in 1.67 seconds
* ^+ x/ w# v" e6 w' j, d2 X1 g7 k/ x[root@controller1 ~]# nmap 10.161.53.5
4 d3 J- E) `" d8 c7 Y; BStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST- H8 q( I$ w) @# J/ h& ~: D
Nmap scan report for compute03 (10.161.53.5)
9 O. s1 J) x* i# _$ iHost is up (0.000082s latency).
/ _) B! c* S8 j* B5 s5 TNot shown: 993 closed ports, @. J' g+ Y C9 y
PORT STATE SERVICE
( |; G: j9 b8 x; |22/tcp open ssh3 `7 F8 ?( ]* H/ j8 e" H3 a% ]+ q
5900/tcp open vnc/ y& [. W0 r: g5 C9 M
5901/tcp open vnc-1+ B# Y$ v) m! k& C* L
5902/tcp open vnc-2
' C" W1 s; P2 ^2 x6 a; T! L1 U) q8 f5903/tcp open vnc-31 d5 O) u. Y) i
5904/tcp open unknown
/ X6 f/ n4 B4 I1 W6 Y2 g( b8022/tcp open oa-system8 x/ S. Q% ` t. ?: \
MAC Address: D4:5D:64:08:44:DE (Unknown)4 j% k6 d' ?$ _, @6 C* W
Nmap done: 1 IP address (1 host up) scanned in 1.67 seconds
( A# r* S1 S: ]/ H[root@controller1 ~]# nmap 10.161.53.6, F; J; X) Q3 q
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST1 j( K% K' ?/ _" p0 u4 u
Nmap scan report for controller1 (10.161.53.6)
" }4 b* o0 P( H1 z7 ZHost is up (0.000014s latency).
/ y/ S2 @ s0 U5 B0 ?8 R% Z8 R4 zNot shown: 992 closed ports
3 @' f( x9 F( v; Z B* ZPORT STATE SERVICE
" r; i% U# x. i" a O, N22/tcp open ssh
+ x& R' `* V O4 X( p80/tcp open http
2 y7 |% m6 M: G, y- X1984/tcp open bigbrother; X( n/ ~) y: n5 y# X6 ^
3306/tcp open mysql+ u4 n! U7 W9 X X, @8 i4 K- a
4000/tcp filtered remoteanything# M0 Q1 S3 f' G8 [' }3 i
4567/tcp open tram A$ v: r* l" s* _; h0 W
5000/tcp open upnp
. z& `! g$ j8 ^4 H' b2 _5001/tcp open commplex-link
) ^: d" q- a+ F3 sNmap done: 1 IP address (1 host up) scanned in 2.75 seconds
) j+ |+ c) f/ y/ n# }[root@controller1 ~]# nmap 10.161.53.7
* j( [" O' o/ d7 \Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
0 [0 [3 N5 b; k/ X2 oNmap scan report for controller2 (10.161.53.7)1 @; }0 U2 d4 c8 U! E
Host is up (0.000078s latency).' A9 a) j3 S4 c* M( g9 Y
Not shown: 993 closed ports
/ P T8 c. ^/ a/ cPORT STATE SERVICE& Y4 t% M1 U" K4 l& |' B, Z
22/tcp open ssh+ m" f& Q( r( d3 ^1 K7 @0 N9 j; U
80/tcp open http
: G( Y# g" |" a7 `; o- D1984/tcp open bigbrother
( U) o# K2 t2 D( m, \3306/tcp open mysql
5 @1 G1 G* m% B, m) G4567/tcp open tram+ c3 l! W2 d/ R$ u
5000/tcp open upnp
0 s/ `9 v1 `+ h9 n i5001/tcp open commplex-link( J# X; k( O' w& [; A
MAC Address: D4:5D:64:08:45:0A (Unknown)1 C' b2 N/ U9 V
Nmap done: 1 IP address (1 host up) scanned in 1.55 seconds) v: n+ ^$ I" ^% M1 {2 f
# }& t8 z4 |$ X! A$ n/ ?4 |4 e结果太恐怖了吧,如果有业务同学在使用noVNC之后没有退出终端,那么另一个人如果知道了宿主机的IP和端口是完全可以登录这台虚拟机的,直接操作虚机,后果不堪设想:
+ h3 ?. Z6 _' w9 r
1 f2 [" S: k5 {0 Y8 s# k, I7 x解决- |7 S% S h- l
知道了问题,那就有对应的解决方案!8 Q) _) L. O' |- L
目前我们暂时只想到两个方法来解决这个问题,其他方法还有待大牛给予指导:
h, l' Z4 ~% R% G* |& W
+ W0 t* R6 |/ B( r3 i. v方案一) X, v% m0 b5 g& s5 S0 }; ~: T
通过firewalld限制INPUT表对5900:6000的访问规则5 H" Z+ \# [1 \" N t
方案二) i, Y" R- u) s( J; p" Z
添加密码访问VNC8 T' x4 m5 V+ G
) B7 }% y# K$ c U2 |$ t& j) [/ R, e7 \
操作
6 i8 H" W8 Y, D) |: V: N( mfirewalld! D: n+ _% G% U: Q2 M- i
我们知道OpenStack通过VNC Proxy将管理网和业务网隔离开来,以便我们可以使用管理网络的6080端口访问虚拟机VNC,同时提供Token用于验证访问的合法性。一个VNC Proxy在OpenStack里的处理流程如下:" T8 y$ d1 L/ p8 C' g
VNC Porxy处理流程# q( o0 l; z* _: k
1. 一个用户试图从浏览器里面打开连接到虚拟机的VNC Client, |1 G- G: H3 Y% G4 x1 Y2 p
2. 浏览器向nova-api发送请求,要求返回访问vnc的url% w& ^2 P! g5 ]' b* o; Q
3. nova-api调用nova-compute的get vnc console方法,要求返回连接VNC的信息
. p7 b# _2 f Z& j& G3 }; m! w: P4.nova-compute调用libvirt的get vnc console函数
2 @) N2 V) p+ T3 U5.libvirt会通过解析虚拟机运行的/etc/libvirt/qemu/instance-0000000c.xml文件来获得VNC Server的信息; o: a$ b- [+ h+ |! ~
6.libvirt将host, port等信息以json格式返回给nova-compute
& y# a8 r9 h' ]/ q5 R" J6 M7.nova-compute会随机生成一个UUID作为Token
' \% z( m! i/ t3 k! \, U+ j5 e, |8.nova-compute将libvirt返回的信息以及配置文件中的信息综合成connect_info返回给nova-api7 G: F! ^4 E! v2 C7 x% _: C: A
9.nova-api会调用nova-consoleauth的authorize_console函数. T" I, M0 |' n# y9 [0 c
10.nova-consoleauth会将instance –> token, token –> connect_info的信息cache起来
; c$ l* D/ a( A( R( s% J# O$ W* h- g11.nova-api将connect_info中的access url信息返回给浏览器:http://contorller:6080/vnc_auto.html?token=7efaee3f-eada-4731-a87c-e173cbd25e98&title=helloworld%289169fdb2-5b74-46b1-9803-60d2926bd97c%290 @ m+ y3 G' t: ]3 H, |: S8 O3 t. T
12.浏览器会试图打开这个链接( W5 C3 q* l8 ]5 U( W+ `) l5 s! K
13.这个链接会将请求发送给nova-novncproxy
! c& U3 i' \$ H* `14.nova-novncproxy调用nova-consoleauth的check_token函数
9 |9 |& v3 S8 h0 R15.nova-consoleauth验证了这个token,将这个instance对应的connect_info返回给nova-novncproxy; A3 w8 d1 k# \8 L
16.nova-novncproxy通过connect_info中的host, port等信息,连接compute节点上的VNC Server,从而开始了proxy的工作/ |% T+ H1 ^- d( \, F* _& S6 X
这里重要的就是第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。
& N& V4 r5 T6 g- G% q那么也就是说,计算节点的VNC端口只需要让nova-novncporxy服务能够访问就行,有了这个就好办了。
# t$ l3 Q6 v3 B0 t2 m; J; L操作firewalld$ x: O5 Q) {0 ~6 o% _& R
在所有计算节点firewalld的INPUT表中添加如下规则:" m6 o( k& k4 p4 z1 |: R
2 O+ W4 `2 R. t( |1 q' t
检查防火墙是否启动:" r# |' W/ {5 N1 }+ O
systemctl status firewalld.service( p7 m4 J7 u' k8 m
启动防火墙:4 ~0 \8 l+ v1 M
systemctl start firewalld.service0 q' F& x5 ?5 {
; j I5 z! F$ n9 o3 L' X
2 c3 E0 z$ K: s' \" x
开机启动防火墙:
5 F; g5 ~' M* i" i& ksystemctl enable firewalld.service& C4 _ A% W% H' M1 w) U8 B
添加规则:5 c% n- O7 {9 N6 p
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.6" port protocol="tcp" port="5900-6000" accept"
/ A% X' I# [+ ~" ?% m firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.100" port protocol="tcp" port="5900-6000" accept": t5 X5 }3 f' A
firewall-cmd --reload
1 [4 V6 {4 ?; d7 o# J1 q: ^ firewall-cmd --list-all
4 j4 r' m& ^- B删除规则:' T. A) m1 w* A: b. J' L
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="10.161.53.6" port protocol="tcp" port="5900-6000" accept"9 k( z" `$ B' s% V: I6 g" Y& l
! `0 w" D& R( t5 V# V( ]
firewall-cmd --reload , M* @3 b9 V8 N$ H$ w
firewall-cmd --list-all; M) J* H2 _; @# {" T1 ^ N8 A
$ w/ X5 H" p0 p0 X9 r
: q3 H, ]* r$ P4 \3 ~4 h( P添加防火墙规则:
7 E8 Q3 |2 J8 v, V, a1 C( Yfirewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.31/27" port protocol="tcp" port="5900-6000" accept"- _& Q- @4 j, `6 e" F' F6 U# k
& i6 l5 |$ }! Y3 e6 q
firewall-cmd --reload ! x" ~! r1 m. C, V
" L2 {- Q! K% O& g( t通过测试上面开启的firewalld会导致业务无法访问。
3 q5 c5 l' a; j这里改变方式使用iptables的规则吧:
# h/ y, x/ C! p7 y. F8 k- ?& E
; D+ G& v( p9 t8 h/ A iptables -A INPUT -s 10.161.53.31/27 -p tcp -m multiport --dports 5900:5999 -m comment --comment "ACCEPT VNC Port only by Controller Node" -j ACCEPT8 Z5 x2 e X6 v; P0 ~& e0 f4 C
iptables -L) Q" g* M+ v! j
iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable9 G7 K" D7 _% r4 k
" _/ k4 V' p+ }! Q6 G: e. Z
$ [. S6 t- t1 T; e0 P8 r- O# P f) u
2 m5 K* [9 q! b8 X |
|