找回密码
 注册
查看: 1272|回复: 3

关于OpenStack中虚拟机VNC访问安全问题

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2022-1-17 09:55:59 | 显示全部楼层 |阅读模式
关于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

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-1-17 10:59:40 | 显示全部楼层
4.解决方案
6 W1 O& l$ \- s8 [. e9 Y$ {
6 z: r* ~; j  [& l9 J①从交换和防火墙的ACL控制IP访问
/ b9 W( B" }8 H②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题' M* @7 R4 v; l9 Y; [1 Q
③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口4 [3 H# I5 D3 `/ N# Y
④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁
7 X# Z5 u2 H' X/ x4 |% m7 b" C⑤vnc增加访问密码: o* X) {9 I1 C. A0 q+ G' L; V# J

7 N0 T1 F/ z+ t' G2 ?7 [4 {下面针对方法④和方法⑤进行详细的说明。$ \: G2 `$ O. S( `, _
④配置IPtables" K4 c# F1 e. L& ~& e$ ?% s  S
根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。
7 ^0 D$ D& d" ]/ U  O% V% ~在所有计算节点IPTABLES的INPUT表中添加如下规则:
3 X. O/ t/ b4 m1 C7 d! t
8 O( Q" P* P8 I$ z

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-1-17 14:49:23 | 显示全部楼层
①从交换和防火墙的ACL控制IP访问, u8 ^8 D: Y6 R- x9 G0 c1 m
②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题; }! {0 \  A0 k, `! D5 D
③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口9 S# W* j% h. x5 u$ U& O
④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁
" I6 s+ E) |# D5 N9 b4 f4 Q⑤vnc增加访问密码* p( T+ i9 D6 e" d6 }% z) W
下面针对方法④和方法⑤进行详细的说明。
* ~5 i9 T8 e# n/ f! K④配置IPtables3 s* Y9 E. a5 Y/ F
根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。, g1 n  C4 R5 e1 X* |
0 x7 _3 K0 N# h5 R7 X' T8 p
在所有计算节点IPTABLES的INPUT表中添加如下规则:' j4 ]! Q0 _/ t2 ^- W; c+ V

- _1 z% X! [; w8 [& r: S. O$ C3 x$ iptables -A INPUT -s {{ CONTROLLER_NODE_IP }}/32 -p tcp -m multiport --dports 5900:5999 -m comment --comment "ACCEPT VNC Port only by Controller Node" -j ACCEPT
9 s! K) [: h; e3 b
5 M; q7 w: O* ~3 ^7 E9 ^" F0 y7 @$ iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable1 R8 ]/ G" L0 U* v+ y3 n' z
9 U( l" w% a9 q, A6 g! t
意思就是只允许控制节点访问本机的5900-5999端口,其他的一律拒绝。
; v9 F, ]! J# M0 L6 `0 \当再次使用nmap进行扫描时,便不能看到VNC的端口。$ `4 L3 b/ a3 [& v  X3 p
0 @% R4 `+ D$ V# ^0 ?! H. U" i, v
$ nmap 10.161.53.1 5900
0 L6 ^% N" {4 v: K⑤VNC添加访问密码
0 @) [0 T, R% J7 \0 L对应的配置文件为:virt/libvirt/config.py4 {) {7 o& c0 m  r$ z
  a- Y4 W+ U5 ]# T: N. A- I& K
libvirtd在<graphics>域里面是支持配置VNC的访问密码
* y; n" _3 {- a" o
  d. Q$ E, P3 n6 O7 u...% t+ O: W8 e8 f6 v* s3 W/ ?
<graphics type='vnc' port='-1' autoport='yes' listen='192.168.23.59' passwd='YOUR-PASSWORD-HERE' keymap='en-us'/>- P& }2 s6 K* @5 j# e
...+ @" u) o- S! D! m+ k( q3 B% u
,那么Nova在创建虚拟机配置的方法中也可以找到对应graphics的代码,我这里修改得很简单,直接在返回的dev列表里面添加个passwd的value,而value就是VNC的访问密码。; i7 a3 H8 n; E: H: ^  F
/ j! ~; E/ m: h3 L4 O7 u8 y
class LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice):8 A" c1 |  s6 E8 m. @8 a

* c1 c* @7 J! U    def __init__(self, **kwargs):" x$ L8 z3 J/ a+ t! X/ d
         super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics",. _) a6 N! L8 y- s; c- ]: J
                                                          **kwargs)
- t: E, s1 P7 c; W+ z. h
1 f2 B' p/ }" S1 E         self.type = "vnc"
/ y- ?- |" ]+ a) W" J$ b+ d         self.autoport = True9 l% q) g3 l* M! G9 ^, [
         self.keymap = None) J* g9 `1 O, i: |% O/ E3 U1 s
         self.listen = None. Q9 P. ~& B8 l$ i' N4 k

! E: V: w1 L8 Q- N     def format_dom(self):
" d! p: e+ E! k         dev = super(LibvirtConfigGuestGraphics, self).format_dom()
% K1 ?. z0 f- _$ T8 ]6 }# O+ w
2 B4 T4 n! ?0 ?) u! j2 P) ^9 T         dev.set("type", self.type). k& t3 s. r% V" p6 |
         if self.autoport:. f. o( d2 D5 S( m& r
             dev.set("autoport", "yes")
3 M4 c8 U" {" e4 g' h         else:
2 W' v5 k2 t' U  ]9 E0 `             dev.set("autoport", "no")
8 i2 \% M& j9 ?* q5 w         if self.keymap:( K' B# L1 T4 d& S3 V( F6 S5 ~
             dev.set("keymap", self.keymap)
6 f/ ]; I. i8 n. w         if self.listen:" t5 @2 e1 ?/ w. U9 P8 r* J! z2 H. O
             dev.set("listen", self.listen); @! K: w) I2 Z
#       dev.set("passwd", "123456")
% r9 V8 D7 ?! j9 C5 z         return dev- @" _$ u! U( _& r/ k% C; E2 @9 k
其中dev.set("passwd", "123456")是新加入的一行,如果不需要vnc访问输入密码,直接注释掉即可。9 ^; N1 s6 j  U
下面是一次解决过程,因开发环境使用的是容器化部署,文件路径比较长。" C8 v. C+ X# J# m* R
解决过程. S$ \/ c8 e8 F  B" a% i
查找文件* S5 t* A9 Z6 H, ]. b6 G" J* r
, B2 T( I9 k! V8 W
root@controller1:~# find /var/lib/docker/aufs/diff  -name config.py | grep nova6 V; l2 j* s: q( J8 u+ V" O
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/config.py. \$ |/ S; s! p9 F1 {
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/config.py6 j5 q0 [0 R- c5 D( U# Q
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/common/config.py" C' v! ]- t/ ]9 c: v, t
进入配置文件所在路径# e8 z! o; ~. c7 R0 r) k, T
3 @7 ]% _) F# Z
root@controller01:~# cd /var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/
0 {# ^7 B" T2 ?) E3 T( sroot@controller01:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# ls
# n+ r9 [: i& mblockinfo.py   compat.py   config.py          config.pyc   designer.pyc  driver.pyc   firewall.pyc  guest.pyc  host.pyc         imagebackend.pyc  imagecache.pyc  __init__.pyc           instancejobtracker.pyc  migration.pyc  utils.py   vif.py   volume, a/ L& S- _+ v, i/ _/ f* r4 }
blockinfo.pyc  compat.pyc  config.py.bak.ori  designer.py  driver.py     firewall.py  guest.py      host.py    imagebackend.py  imagecache.py     __init__.py     instancejobtracker.py  migration.py            storage        utils.pyc  vif.pyc
/ t( m8 p! `! c& _6 }+ n6 s修改配置文件
$ I- l( Q0 P) S. Z9 z1 a/ x
. ~$ s" g8 b3 ?: H4 U! B  qroot@controller1:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# vim config.py- B% N# m6 z) R( ]3 k7 K4 r
在这里插入图片描述
% U# F, R2 Y# a$ c修改后,重启nova-compute服务,即在下次创建虚拟机的时候生效,其结果如下:
% Z( O1 x0 Y2 S1 @/ P" r在这里插入图片描述/ X+ s$ b  Y9 Y# Y2 h
输入密码virt/libvirt/config.py配置中新增的密码123456即可正进入虚拟机。
% z7 U3 f( g2 E! U  v( R, W

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
 楼主| 发表于 2022-1-17 17:05:37 | 显示全部楼层
4.解决方案
* K9 ?' |/ h' q% Z①从交换和防火墙的ACL控制IP访问
/ T* ?- q/ z6 Q/ w& v$ J! H②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题$ J# N5 K- \' Z1 q8 I! \
③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口- O" c" R6 a3 M, e* i
④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁5 N9 R% {0 K) F. Z" Q
⑤vnc增加访问密码
4 r- W2 y" K* i, s0 x下面针对方法④和方法⑤进行详细的说明。/ ^- K* I9 C: O$ l# l
④配置IPtables
; q( ]8 v' T4 [7 M2 c, |" P/ i- e3 u根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。
" K& m8 V+ ]# n0 g' v8 ?" ]# [
& ^( E# `5 V& T/ Y' s3 ?5 M: {在所有计算节点IPTABLES的INPUT表中添加如下规则:9 N( s# Z. A4 s9 D6 G

5 [7 S2 E7 H  `7 _. E8 Z$ iptables -A INPUT -s {{ CONTROLLER_NODE_IP }}/32 -p tcp -m multiport --dports 5900:5999 -m comment --comment "ACCEPT VNC Port only by Controller Node" -j ACCEPT
4 x2 }; h! c( u: K" o. c: j+ n2 S1 }2 X' f2 @6 K  }  W2 a% ~9 _
$ iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable7 U& \8 H: c- G6 z. R: d
意思就是只允许控制节点访问本机的5900-5999端口,其他的一律拒绝。
  W5 s2 c3 ]9 b+ [: U" F当再次使用nmap进行扫描时,便不能看到VNC的端口。* O, W- k# H; F* U* m7 `8 _2 @
- V" }1 T2 U2 ^4 F5 _# u
$ nmap 192.168.23.129 a' a3 r* ?# d  R+ r. [# Y
⑤VNC添加访问密码" ^: L* O. d/ R  S9 A
对应的配置文件为:virt/libvirt/config.py. X7 R6 v6 Y2 A
6 a5 s8 l4 v( Y# T. ^7 k- G9 `
libvirtd在<graphics>域里面是支持配置VNC的访问密码
3 S& ]) Z7 x0 d; [
' W& L$ }9 X/ V# n2 N) T...! n8 e! B* {3 l/ n' @5 ~3 n& g, o
<graphics type='vnc' port='-1' autoport='yes' listen='192.168.23.59' passwd='YOUR-PASSWORD-HERE' keymap='en-us'/>8 Y1 g. n1 `! X' r8 @  h
...
4 X! I0 V6 E7 l5 D,那么Nova在创建虚拟机配置的方法中也可以找到对应graphics的代码,我这里修改得很简单,直接在返回的dev列表里面添加个passwd的value,而value就是VNC的访问密码。
* J+ |' d6 h* y1 k2 w9 f
4 R7 L( [$ S. |2 G1482 class LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice):2 s" U; }& h( i* R4 K2 O/ s
1483
) |9 \; o+ Y& D' a1484     def __init__(self, **kwargs):2 {( L+ {9 @- O: V5 {+ x7 A" n
1485         super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics",* o, M9 M: [: S$ G% t- n
1486                                                          **kwargs)
9 ~& c  H: h# @- V3 X  q7 n' `1487 , Q! s; r% j  [7 d
1488         self.type = "vnc"7 m4 t4 U/ y) a" h
1489         self.autoport = True# G/ q6 n" N' F+ F7 |' ~) o6 e
1490         self.keymap = None, k0 G: L* K5 L2 r
1491         self.listen = None" \7 P* A7 L, y0 J% w
1492
4 f, S7 i# R( f* V: ?: K1493     def format_dom(self):: d5 W1 @$ P. i8 }& V, \9 h
1494         dev = super(LibvirtConfigGuestGraphics, self).format_dom()
' V; |( V1 W. x# o5 Y/ A" \* C1495 % a9 A  w, {/ F3 F- o& I8 C! i
1496         dev.set("type", self.type)5 n- D& C$ ^( J+ F
1497         if self.autoport:# f5 I+ l+ Q* O7 J9 m# n0 A6 K
1498             dev.set("autoport", "yes"), P1 v7 G  C% W: T7 I/ v
1499         else:( X# u; C, b# e4 N% k$ k
1500             dev.set("autoport", "no")
' ]$ R) ~! A% u4 B& s2 B1501         if self.keymap:
7 y# d. i3 ~3 j: j1502             dev.set("keymap", self.keymap)
) |' \! X2 |1 h3 \/ y1503         if self.listen:" W, h  V! e& t1 c. a4 O7 K) e, J
1504             dev.set("listen", self.listen)* A0 B- X, Q+ u- I6 z
1505 #       dev.set("passwd", "123456")
$ d, Q! i. z, p: {/ x' C1506         return dev
. A+ [5 J2 n2 @& Q( G2 G  s- X其中dev.set("passwd", "123456")是新加入的一行,如果不需要vnc访问输入密码,直接注释掉即可。: K/ R; e$ v' b/ P
下面是一次解决过程,因开发环境使用的是容器化部署,文件路径比较长。
9 m1 [, K! \, S& e3 T解决过程* c0 d+ w% s! e
查找文件" w5 g! S+ U/ h! r: e) \

8 F. O( H( W' Broot@controller1:~# find /var/lib/docker/aufs/diff  -name config.py | grep nova
1 J* N5 h; m- d+ q/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/config.py
/ z; c$ z9 e( g3 B' R! U/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/config.py" _: j! k. n$ A! k  U5 O" X9 G
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/common/config.py
# D7 N$ a/ C7 o- o进入配置文件所在路径; f2 b6 ?: b# t/ U
+ Y- j: F/ V0 u0 x1 y
root@controller01:~# cd /var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/
& p6 e* T7 |& ^) {/ j! I! V- froot@controller01:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# ls
3 O. o" A6 k2 q5 E$ R$ l: hblockinfo.py   compat.py   config.py          config.pyc   designer.pyc  driver.pyc   firewall.pyc  guest.pyc  host.pyc         imagebackend.pyc  imagecache.pyc  __init__.pyc           instancejobtracker.pyc  migration.pyc  utils.py   vif.py   volume- o7 s; q1 N( u1 v/ L9 }
blockinfo.pyc  compat.pyc  config.py.bak.ori  designer.py  driver.py     firewall.py  guest.py      host.py    imagebackend.py  imagecache.py     __init__.py     instancejobtracker.py  migration.py            storage        utils.pyc  vif.pyc
2 p( [, h1 W8 q# p2 @修改配置文件
5 `, }3 |6 G" G+ q; X! L5 s% E7 ]8 h% G6 J8 t1 y! c; G: ^5 F; E
root@controller1:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# vim config.py
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-12 00:07 , Processed in 0.027458 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

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