易陆发现互联网技术论坛

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

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

[复制链接]
发表于 2022-1-17 09:55:59 | 显示全部楼层 |阅读模式

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

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

x
关于openstack中虚拟机VNC访问安全问题
  _- f# Q" b* r& C/ u7 |, r. l前几天收到甲方给出的文件信息,线上OpenStack环境的物理机VNC端口能够自由访问,要求整改。
7 g  b- q1 H1 S9 d  u- f2 P4 Z随机抽查了两台宿主机的VNC端口,确实很多业务的同学使用noVNC后没有退出终端的习惯,往往都是用完了就直接关闭窗口。不得不说这样隐患很大啊,首先不说通过外部方式规避风险,如果内网里面有一些script kiddie随时都能将我们线上的虚拟机VNC端口扫出来干些坏事。我这里也用过nmap测试了下开发环境的网络端口,如下:
/ S* o% w0 b3 E0 Y$ v[root@controller1 ~]# nmap 10.161.53.10 h/ @0 C2 Z% N" N. |
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST; d( y% G( B; [+ a* d
Nmap scan report for compute10 (10.161.53.1)' T  A2 ?4 l0 _+ r: f; r. e
Host is up (0.000080s latency).
' s$ o1 U. I. a2 V! NNot shown: 989 closed ports8 ?* m4 @* e" f
PORT     STATE SERVICE2 |# K, O( o0 |- Y3 C
22/tcp   open  ssh5 t* X9 M' g6 ^3 z- D/ y) }9 a
5900/tcp open  vnc9 z5 b& n! w0 S$ _  Q0 a" u
5901/tcp open  vnc-1
: I! r$ G5 f8 k5902/tcp open  vnc-2
) @) U* W# ~0 p' ^. v$ K: _. W5903/tcp open  vnc-3( K, z' J% q- M4 n" g% r& O6 L
5904/tcp open  unknown
: J$ N) p. ]3 \  o( H8 H" T+ B5906/tcp open  unknown
" t2 W: K$ m- T6 d5907/tcp open  unknown, i$ ], }8 k" c1 y) n
5910/tcp open  cm
  Y9 H0 J5 m# o- M0 O7 _& h5911/tcp open  cpdlc
8 b3 F) h! D; \  h/ J. q# m8 m8022/tcp open  oa-system
# l% n9 X, j7 F$ Y, e7 G5 Q8 lMAC Address: D4:5D:64:08:45:02 (Unknown)
6 n! t. b- r2 f0 @Nmap done: 1 IP address (1 host up) scanned in 1.65 seconds
0 Y% y! A5 n- w+ @; U[root@controller1 ~]# nmap 10.161.53.21 y7 e  B% o7 E4 d: |
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST$ x& ~" D, h- Q& ^3 E. |
Nmap scan report for compute11 (10.161.53.2), b5 H/ g/ }* ~: \! X) U0 X- K
Host is up (0.000070s latency).5 p# A" ?/ \' ]1 y* u$ }
Not shown: 989 closed ports
6 F. p# p6 Y6 g3 ?- n: g' _; \PORT     STATE SERVICE
0 Z3 I8 m# q# J22/tcp   open  ssh3 l5 N5 c# T0 ~
5900/tcp open  vnc% ~" r) P. M& c; t3 i( O, A( _
5901/tcp open  vnc-1! t6 [5 v1 t1 L, i
5902/tcp open  vnc-2
, K$ i. u7 a& V5903/tcp open  vnc-3) g# ^% `5 p  u: K% m4 @
5904/tcp open  unknown1 E1 V  v5 b# ~6 I/ m: t
5906/tcp open  unknown
+ n7 N1 E- s6 O5907/tcp open  unknown
- Q' W, @6 @  E- C: l7 ~9 Y  Z% A) W5911/tcp open  cpdlc/ H: S# N2 i  `; A+ O  R9 q
5915/tcp open  unknown
2 F: o. I, I+ G+ o2 `9 ^8022/tcp open  oa-system
/ j0 ~1 k: i# @/ y% K+ F$ VMAC Address: D4:5D:64:07:B3:DA (Unknown)
/ j/ C2 [/ |) t2 kNmap done: 1 IP address (1 host up) scanned in 1.67 seconds
0 X) }) e3 @* C2 F" i( q8 ?9 R[root@controller1 ~]# nmap 10.161.53.3, P5 W. d  P, r& @2 D0 w+ C
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST( B  C" w, T/ ?% G  N
Nmap scan report for compute01 (10.161.53.3)* H: q9 Z  W/ P0 u
Host is up (0.000076s latency).: q# n& q" u5 t! J$ M! {4 a/ ?
Not shown: 992 closed ports1 f' Z. P4 L4 G/ d
PORT     STATE SERVICE
7 T, F$ X( D5 x+ i' u22/tcp   open  ssh
. S: v7 T; M+ O, A3 n! p/ _. A5900/tcp open  vnc  M) g# m' l) @  a! e
5901/tcp open  vnc-1
$ p2 z8 o  U" g% }, N1 ?5902/tcp open  vnc-2
& f2 f" t6 q- q5903/tcp open  vnc-3
8 o. W3 |* R+ k) s6 _0 j' o5904/tcp open  unknown: b. R, @, @' ?2 n( E# \
5906/tcp open  unknown6 N0 t( }1 p' w, p, k$ F
8022/tcp open  oa-system
8 ^$ n7 Z- Y) h9 M% IMAC Address: D4:5D:64:08:45:5E (Unknown)7 v2 D- o* p& Q! |! w# y2 I1 O* U7 J
Nmap done: 1 IP address (1 host up) scanned in 1.68 seconds% t: ^# L& J/ j5 f5 g: d; }
[root@controller1 ~]# nmap 10.161.53.4
4 w  z$ l6 X% @2 JStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST+ y6 L8 }; y% r$ [6 ~' k5 I' N
Nmap scan report for compute02 (10.161.53.4)
+ s; ~/ R% |2 _& A/ D# E/ |/ o/ c' gHost is up (0.000081s latency).3 P; z7 m8 m& L4 L0 r
Not shown: 988 closed ports6 n; q4 T+ b. B/ f* e9 J( i
PORT     STATE SERVICE# ^& u+ p* A* B9 r  @; L4 ?# [
22/tcp   open  ssh2 ~. K2 L' z! o
5900/tcp open  vnc# }' ?6 L  P# c( ?( s
5901/tcp open  vnc-15 |9 ]0 t* R- |
5902/tcp open  vnc-2) i( R2 j8 ~* T) i$ `
5903/tcp open  vnc-3) s( D: r! X' g$ n5 ~  M; V
5904/tcp open  unknown1 w; ?* M5 D3 p0 d3 Z* W+ K
5906/tcp open  unknown' F4 R$ s; p* B& z8 d0 w5 _+ E
5907/tcp open  unknown, x- i- r6 a. v# A) t8 [& j
5910/tcp open  cm+ i5 O1 X6 W' j. ?  H" x; T' p# C
5911/tcp open  cpdlc6 j5 \/ O; ]* i: {  y# Z9 s% q- V% ^
5915/tcp open  unknown, |1 t& o8 K5 [, {0 R% P
8022/tcp open  oa-system8 f' d% \2 |1 X9 c) g" v
MAC Address: D4:5D:64:08:45:D6 (Unknown)
. T7 n& p0 J+ G: F5 v6 O& F# N; K" R* gNmap done: 1 IP address (1 host up) scanned in 1.67 seconds
; O! d+ }2 Y1 X  l8 S: ?( o9 G  b[root@controller1 ~]# nmap 10.161.53.51 L( D; X; [# K
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
; t. w2 i5 S8 ]4 h. `Nmap scan report for compute03 (10.161.53.5)1 ?. M. y# ]1 a) @  H7 m/ J
Host is up (0.000082s latency)." L% d) ]+ @" R7 x6 P
Not shown: 993 closed ports* U4 r, L7 M# d/ M( A
PORT     STATE SERVICE& Q- {5 q6 }, \5 t  s
22/tcp   open  ssh
, c1 B5 w9 @  p* n, g, ]. o5900/tcp open  vnc( H4 U& y6 j1 X8 T/ h; d
5901/tcp open  vnc-1
( c4 }/ X+ z1 X1 [. @/ T( c/ Q# A5902/tcp open  vnc-2
$ A5 J5 D% a! U5903/tcp open  vnc-3
' P8 A# m3 t( L5904/tcp open  unknown" [. J1 h: V4 c) P8 |) g
8022/tcp open  oa-system: d- o0 E+ U5 _1 Q
MAC Address: D4:5D:64:08:44:DE (Unknown)
9 `, W9 F- H+ e& KNmap done: 1 IP address (1 host up) scanned in 1.67 seconds9 e6 {9 ]0 p* N3 D: T
[root@controller1 ~]# nmap 10.161.53.67 `+ D  e6 ^" W' k$ P  [* Z" j
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
! R# D( D0 T1 |1 s) oNmap scan report for controller1 (10.161.53.6)
3 t0 l) O+ E# r, ?2 o" T* RHost is up (0.000014s latency).( Z! i. s) o6 o0 f' A8 }1 @" L1 V
Not shown: 992 closed ports
! d& \. Y9 h' i8 J% _PORT     STATE    SERVICE
) S. W3 A$ @% V: z3 Q' H22/tcp   open     ssh; L; u  J% Q5 k" `% H% Z# y; o" J7 S' L
80/tcp   open     http6 I6 j6 h& o; z( L: G
1984/tcp open     bigbrother
% `7 w2 q2 T( P3 {$ h. [: g3306/tcp open     mysql
0 Q, V- e# o3 M) F2 F4000/tcp filtered remoteanything! ^' v) L! K/ G, P
4567/tcp open     tram; j: s" ~6 }2 u: A2 g7 y
5000/tcp open     upnp
" p. r+ N  `9 o" o5 x5001/tcp open     commplex-link0 _) O. D- g8 r' N" o6 g$ d. p% i
Nmap done: 1 IP address (1 host up) scanned in 2.75 seconds# Y4 I  I5 ]+ l# a- [( v2 R
[root@controller1 ~]# nmap 10.161.53.7
9 B% r$ ?# C$ v7 W) z) NStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
3 e6 j: w$ `( I/ @* Y3 b+ R6 V. D, v9 @Nmap scan report for controller2 (10.161.53.7)
3 L  |4 g* l0 d0 Y% G# a) zHost is up (0.000078s latency).) F6 d5 D/ A- l- n" n
Not shown: 993 closed ports+ z  h  O) K4 W; G; X+ w' i, t
PORT     STATE SERVICE+ Y5 n! o1 P4 p- A. T9 s( n  }
22/tcp   open  ssh6 l$ g. k; D! b, w
80/tcp   open  http
% M0 {" Q  T5 ]3 H( a- U1 M1984/tcp open  bigbrother0 Z+ u1 M# b9 O) A% G
3306/tcp open  mysql
# E- y2 I9 x4 Z4567/tcp open  tram
* w4 f: R. Y: u5000/tcp open  upnp" x( J7 I3 P7 f' t7 E; M
5001/tcp open  commplex-link# w* q# e  H3 J0 _9 L6 c' J* Y
MAC Address: D4:5D:64:08:45:0A (Unknown)
+ h) J- {* F; C1 A2 TNmap done: 1 IP address (1 host up) scanned in 1.55 seconds6 M/ C5 |( j4 k( a

8 Z* o* t( c; n* u6 W4 z结果太恐怖了吧,如果有业务同学在使用noVNC之后没有退出终端,那么另一个人如果知道了宿主机的IP和端口是完全可以登录这台虚拟机的,直接操作虚机,后果不堪设想:
$ b3 O7 V5 M6 f8 R1 o# V; H3 n9 O6 `6 Y1 |, @
解决
+ D% _& y. c' L* M* B+ i: ?% m知道了问题,那就有对应的解决方案!
9 d+ @; W# J3 ^/ q( Y+ }8 ]$ }目前我们暂时只想到两个方法来解决这个问题,其他方法还有待大牛给予指导:
; n5 p( Q5 E& Q& e
1 g2 G' I' U: \4 Q4 o* m方案一' f8 F+ n% ~3 c* Y
通过firewalld限制INPUT表对5900:6000的访问规则
( E2 \! w8 U8 n9 }方案二3 |7 ?( v/ C9 D% G' e4 M/ k
添加密码访问VNC& d0 n8 E* S2 C

9 j% y& l! d1 S9 m2 v2 `  l+ p操作) R- k5 M' `  f8 }
firewalld2 |/ @. V2 W( G. Z
我们知道OpenStack通过VNC Proxy将管理网和业务网隔离开来,以便我们可以使用管理网络的6080端口访问虚拟机VNC,同时提供Token用于验证访问的合法性。一个VNC Proxy在OpenStack里的处理流程如下:
4 j) o, I$ e; V$ l
VNC Porxy处理流程
) L9 v6 k1 _6 Z  v1. 一个用户试图从浏览器里面打开连接到虚拟机的VNC Client5 N6 m3 X  k. w0 w+ `7 q
2. 浏览器向nova-api发送请求,要求返回访问vnc的url9 s& [: w# E4 D, v  `
3. nova-api调用nova-compute的get vnc console方法,要求返回连接VNC的信息4 q; j8 _, V( k" Q7 M
4.nova-compute调用libvirt的get vnc console函数* A4 v. N4 ~5 a) I4 g3 t
5.libvirt会通过解析虚拟机运行的/etc/libvirt/qemu/instance-0000000c.xml文件来获得VNC Server的信息# l' r8 [9 T- V8 G4 ^0 c
6.libvirt将host, port等信息以json格式返回给nova-compute2 R3 Y6 C# R( O% `4 [* R2 j3 F
7.nova-compute会随机生成一个UUID作为Token9 X; k- f5 H; p8 P$ g# V
8.nova-compute将libvirt返回的信息以及配置文件中的信息综合成connect_info返回给nova-api
/ x2 u: O: y- }5 e  w* e& w9.nova-api会调用nova-consoleauth的authorize_console函数- S7 R& `- z7 z& f
10.nova-consoleauth会将instance –> token, token –> connect_info的信息cache起来
0 D: b/ f7 _7 N6 _2 A4 Y( O11.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%29
: a  o0 M7 Z- i3 E9 Z% j# {12.浏览器会试图打开这个链接
& S8 y1 _. y" T13.这个链接会将请求发送给nova-novncproxy/ D$ Q3 A& _" w7 r. e8 C3 a
14.nova-novncproxy调用nova-consoleauth的check_token函数2 `6 T3 Z( S  |/ P" ?/ b/ w
15.nova-consoleauth验证了这个token,将这个instance对应的connect_info返回给nova-novncproxy
) C$ b) O& _, h; h6 v16.nova-novncproxy通过connect_info中的host, port等信息,连接compute节点上的VNC Server,从而开始了proxy的工作
- _  T; j( m  O5 L
这里重要的就是第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。# A7 v8 R/ y+ j: K4 L) Y
那么也就是说,计算节点的VNC端口只需要让nova-novncporxy服务能够访问就行,有了这个就好办了。
; V- Q9 T( Y, g
操作firewalld3 Y4 [) t1 ^' p$ _2 W, p! d& s
在所有计算节点firewalld的INPUT表中添加如下规则:  ~) n9 ?2 r. `
6 Y' c' }& B$ j+ e6 e2 m. m
检查防火墙是否启动:
6 W: m& f4 f' c" v9 ^4 K
systemctl status firewalld.service
, K) T' |: N9 m4 y2 `2 Q/ F' i. L启动防火墙:+ a6 ]! F( l; _9 U
systemctl start  firewalld.service
# S$ f3 S1 B$ s$ L% n( Z
! {  }& O2 B7 @: o" E6 }) S
$ e/ o9 j) U0 E$ `
开机启动防火墙:
0 D* S' X: O6 e/ g; `systemctl enable firewalld.service
! W4 f6 L, A/ B, _. B: a添加规则:
2 `1 y/ F0 Q# `& l. ^
  firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.6" port protocol="tcp" port="5900-6000" accept"
( s! V5 p& e: A: W: V( f4 x' W   firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.100" port protocol="tcp" port="5900-6000" accept"" Q5 `9 H- s& [2 W3 C  o
firewall-cmd --reload
# [8 C  P4 j. a, H firewall-cmd --list-all% k+ U7 ?/ I8 Y5 R# B9 G
删除规则:
; I  l4 J9 @% w5 b* R  firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="10.161.53.6" port protocol="tcp" port="5900-6000" accept"6 n' v: D" W6 g

( P' P4 B1 x' T1 ~+ i firewall-cmd --reload 1 t+ [2 v$ Q+ j! k
firewall-cmd --list-all
2 C2 x* d$ ]: `8 H. _/ ?7 O' _
1 b8 F- ~! a6 Q: X. z" N- c6 \' |: p' [% ]% O5 V" q+ C+ V( K
添加防火墙规则:* `& |5 S. T, x, y$ X9 I
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.31/27" port protocol="tcp" port="5900-6000" accept"  B1 m2 Y2 z9 `* U

* V8 K; m. F# ?2 X' P  c9 ~  Sfirewall-cmd --reload 9 N& p6 X( E6 t, D/ V! l# Y
( K7 f$ I. m- S6 @7 a* g- l0 Q  w/ i
通过测试上面开启的firewalld会导致业务无法访问。( e# y, h* t8 \6 r
这里改变方式使用iptables的规则吧:
- f  [0 K9 ]7 q+ H1 u$ [2 r+ e# \) a+ X5 ?# z  G# z
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 ACCEPT
1 Z6 K, z) P' ^* j5 l4 ~ iptables -L' _% p  b$ W, P+ R& r
iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable
5 d% z$ M7 v5 T" m: ^
" Q2 O6 j6 F/ B7 J, a1 i- t) [6 @1 n
8 x9 ~9 a0 l8 i( N0 v9 W
 楼主| 发表于 2022-1-17 10:59:40 | 显示全部楼层
4.解决方案
3 H8 H5 V: m  S; H, v( z, J9 `" d6 W. B6 S# Z) L; t& W
①从交换和防火墙的ACL控制IP访问
" p% A, @+ D0 ~0 x2 m②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题2 N2 H6 |1 R/ t' J9 Z) q: O
③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口
& x1 n7 @9 q8 j, j! p$ u$ v④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁
% Q2 B* t3 i% N6 x0 y( D4 Y4 [⑤vnc增加访问密码
$ _* S8 q  g: b2 t& `+ L
" t9 j. k# P& E* N$ i下面针对方法④和方法⑤进行详细的说明。' g4 u! |8 o, h  b' x. a/ L/ g
④配置IPtables$ S* @; ?* y: M
根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。( e' O" K2 E# k9 x' I
在所有计算节点IPTABLES的INPUT表中添加如下规则:
9 t9 Y/ o1 b5 n' Q& p# U% e/ [4 I" \/ y3 `! l4 z9 l" N, `
 楼主| 发表于 2022-1-17 14:49:23 | 显示全部楼层
①从交换和防火墙的ACL控制IP访问! `; \! e0 P; b/ B# j! I- y
②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题: C) y/ L# d5 h( J% t- u7 }, U
③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口
  a, S- E( F" r$ b④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁
2 R& Z# l" g- o⑤vnc增加访问密码
9 B: ?3 B2 o; f) n2 N$ y1 S6 n下面针对方法④和方法⑤进行详细的说明。
! G2 {8 D% G* L- P④配置IPtables
7 R7 L" n$ P+ _* X5 m3 E) ~8 T根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。
- H) f1 ?* j9 s5 o) {1 J( ?& i% Z1 |* \' y5 I% W0 e8 Z9 j: C, h
在所有计算节点IPTABLES的INPUT表中添加如下规则:5 A4 [4 p: J7 ^1 G* ?

  t# J6 t, f( d% Y# j; z5 P$ 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
% G: P5 L9 w( d: l4 J. C; J, X/ c' G: Q! C. W$ c5 d; }9 J3 M; i8 V! r
$ iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable$ |2 c9 I, x# u( N

/ I* g3 o' e0 F7 A, z; v, G' N意思就是只允许控制节点访问本机的5900-5999端口,其他的一律拒绝。
1 E5 U' `5 |3 ~* M# q/ e5 H) v: q3 E当再次使用nmap进行扫描时,便不能看到VNC的端口。& }" x: q6 Z  X- O

# t1 z) Y. L- e' M$ nmap 10.161.53.1 59006 E2 N! h: K" Z3 f* Z5 I: D
⑤VNC添加访问密码
( k" r1 x2 H5 K+ D* X对应的配置文件为:virt/libvirt/config.py
6 t- d' X7 `% f4 E* b0 _- h& [
libvirtd在<graphics>域里面是支持配置VNC的访问密码. ]0 \+ s" n$ i' t; \" B
. f/ E0 B" j  P$ n
...
( t# ^3 d) }$ v4 f <graphics type='vnc' port='-1' autoport='yes' listen='192.168.23.59' passwd='YOUR-PASSWORD-HERE' keymap='en-us'/>5 O; H+ ?# f- w
...; ~6 W$ @5 h3 m2 T5 h+ [& n4 r6 \
,那么Nova在创建虚拟机配置的方法中也可以找到对应graphics的代码,我这里修改得很简单,直接在返回的dev列表里面添加个passwd的value,而value就是VNC的访问密码。( R2 {5 [! ~' Y

7 g: O0 r1 z" f  O6 F. ?7 {- Tclass LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice):
7 Q1 r8 P" K1 D. _8 J' l# d7 u, g0 j: e/ C( U' K# l, c6 [
    def __init__(self, **kwargs):4 J, E0 q2 w$ X- @, T
         super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics",4 e3 P+ U7 [( s6 {$ r% A( _3 [
                                                          **kwargs): }! k9 C4 n* ^6 e
# U* D3 ^% p, L+ @: c0 m/ N( \. y7 H
         self.type = "vnc"! u+ u# y8 C/ s; y  T4 F: }
         self.autoport = True
3 c0 A; h! |, `; O' G+ A+ ^) |# M         self.keymap = None
9 G/ P" W) h1 M, u2 P9 u         self.listen = None2 f& E; q$ n, q9 Q" y7 m+ r
: ^7 o& Y3 e6 M8 B" S
     def format_dom(self):
; d5 d1 `6 q% ~& H* U. r         dev = super(LibvirtConfigGuestGraphics, self).format_dom()6 ?: p' t8 Q/ r" L9 L  \

: D: m5 a$ I" _& |* N         dev.set("type", self.type): _3 f3 l* _# d$ I: z
         if self.autoport:
! s* j8 z  T( m             dev.set("autoport", "yes"), C* _; {" t6 ~( t
         else:) `; H3 P+ l+ U4 X/ T% ]' F
             dev.set("autoport", "no")
: G# s! O5 f1 v9 w         if self.keymap:, b  k7 h* V( @: k0 j. w
             dev.set("keymap", self.keymap)
; k: x# }5 [9 r. S6 W- l         if self.listen:& c, r; z5 K+ }3 e/ T% E! ?4 D: h) T# F
             dev.set("listen", self.listen)5 c' g2 R) C% c
#       dev.set("passwd", "123456")  C- k; n! x1 h8 r0 u' z: A
         return dev) H9 N; u5 z+ b) F
其中dev.set("passwd", "123456")是新加入的一行,如果不需要vnc访问输入密码,直接注释掉即可。9 [; V7 i7 Z* O* n! f8 [
下面是一次解决过程,因开发环境使用的是容器化部署,文件路径比较长。9 b# J+ A4 R, }
解决过程
' K2 u' v8 @4 c8 G, Z' k8 X, ?查找文件8 e3 n6 X8 O4 ?8 Z9 P3 P
7 i; {# d1 Y; P8 R1 g
root@controller1:~# find /var/lib/docker/aufs/diff  -name config.py | grep nova
# Q" a) j6 o& y* ^# G1 h/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/config.py
# a1 D9 ~; X* Y' U" m: g( u' v0 K/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/config.py- \+ M- N! [& s" `6 O( |' ?" w8 @2 }! z
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/common/config.py
% X( f% H# N8 h! z6 P进入配置文件所在路径
5 ^  Q) q4 y6 N# t5 H: B$ f2 \! _: G. q0 P. `
root@controller01:~# cd /var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt// h7 W  X) ?2 C' U' y' c
root@controller01:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# ls
6 ^) y/ _# H, m7 ?0 R0 Pblockinfo.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   volume3 E  t( j1 _$ I# ?
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.pyc9 I( h/ E4 Q+ d( L
修改配置文件
7 l5 S$ ~! A) x+ D6 d/ \1 S6 o
7 H) {) V4 C, Froot@controller1:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# vim config.py
* J3 U6 K  V" U$ _' B在这里插入图片描述
$ ^" Y; X9 Q% N/ U; l/ j6 V8 q& r修改后,重启nova-compute服务,即在下次创建虚拟机的时候生效,其结果如下:3 d! A( x& {6 j* t
在这里插入图片描述' z$ Y4 |5 F7 G3 e4 Z. F1 D: K" H5 e/ o
输入密码virt/libvirt/config.py配置中新增的密码123456即可正进入虚拟机。. J, V+ m! K2 f+ P) j) t( \, F8 v( R6 U
 楼主| 发表于 2022-1-17 17:05:37 | 显示全部楼层
4.解决方案( h# \3 ~+ A$ K
①从交换和防火墙的ACL控制IP访问
% b9 v0 ^7 V8 M②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题1 \2 x9 j, _+ l" g* b* v1 ]
③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口# O! n; L. p& c3 r# \
④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁
0 M# L( X5 x, s( T⑤vnc增加访问密码5 Y/ A0 Y( `& t6 b
下面针对方法④和方法⑤进行详细的说明。
( U  }( a. q5 R  c④配置IPtables
( E6 `$ }( Q& l根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。
0 |" k1 k3 M$ Z; Y1 J6 B9 O" l1 h8 o: U0 z
在所有计算节点IPTABLES的INPUT表中添加如下规则:3 E0 w( u4 v3 h9 p6 T+ g8 ]1 N

0 O1 R  \% G# T, F$ e5 ]  ]+ p2 v$ 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
- k1 @/ ~: x6 }6 N! a* o9 F$ ^' I7 S7 q! V+ [
$ iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable2 Y% d. K5 a- C: D4 ~: z9 {3 p1 F
意思就是只允许控制节点访问本机的5900-5999端口,其他的一律拒绝。4 X' W5 {: m; B
当再次使用nmap进行扫描时,便不能看到VNC的端口。
6 e; T7 ?% ?3 \" \: e: \1 p1 `# s2 n5 ^" k& E! n& N- G# Y
$ nmap 192.168.23.124 M$ C5 c8 C; I1 G2 ]* V
⑤VNC添加访问密码
; z3 M0 C8 Z& J% x对应的配置文件为:virt/libvirt/config.py  G3 q/ L7 E4 e* k) S' c; ~
% j2 S% H4 W4 S5 ?% m  D2 q
libvirtd在<graphics>域里面是支持配置VNC的访问密码
2 x8 f* N! B) c* g$ ?0 a) C
2 B' }3 H. p0 A) }...
6 z2 x# g/ C) P9 C1 i7 b, N) \" { <graphics type='vnc' port='-1' autoport='yes' listen='192.168.23.59' passwd='YOUR-PASSWORD-HERE' keymap='en-us'/>, L, {: n, j# k
...
' c5 b9 N- _9 C,那么Nova在创建虚拟机配置的方法中也可以找到对应graphics的代码,我这里修改得很简单,直接在返回的dev列表里面添加个passwd的value,而value就是VNC的访问密码。5 x0 ~6 c! d3 L  ]4 d- O7 q

0 f) V2 v) T  x9 \9 N1482 class LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice):
# e: Q) G3 z7 L( G6 d1483
0 e6 [5 Z) Q5 d# H& t" a  c2 m1484     def __init__(self, **kwargs):& A3 T3 w' {) [, U9 [0 G
1485         super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics",
# |* U0 r" r8 i9 a8 W, s6 e* c: P1486                                                          **kwargs), G; `* _+ p" s3 q
1487 ; K! ]& o! X; M: {* V
1488         self.type = "vnc"; U8 R- n5 O' ], v# Z( y2 M
1489         self.autoport = True
6 T8 i! \" w8 d6 U+ K$ @' T1490         self.keymap = None& r6 Q# ]! k+ t/ n8 d
1491         self.listen = None$ h; M% @0 ]0 f* v5 P
1492 7 w: S4 E# P/ N" n  ^# F# J* R
1493     def format_dom(self):
$ ?4 F# v: w# ^) q1494         dev = super(LibvirtConfigGuestGraphics, self).format_dom()  F& }- {$ S0 C1 B8 c) i
1495
6 m& B2 {% f7 ^8 w6 _1496         dev.set("type", self.type)
5 O* @# s8 p9 s7 {1497         if self.autoport:2 u* ~3 i' p  B6 }' P3 \: p
1498             dev.set("autoport", "yes")8 S- I1 W. {5 N: D
1499         else:
# i2 I. g9 I, L, v1500             dev.set("autoport", "no")5 |* F8 `1 _. n  O; [
1501         if self.keymap:+ ^) h) D7 G" P" k
1502             dev.set("keymap", self.keymap)7 q' v) W. K1 e; `+ S. ^% D
1503         if self.listen:  U0 R4 K! r7 h1 i) K. q. L
1504             dev.set("listen", self.listen)5 t( {5 q& g4 g1 Q; T7 m
1505 #       dev.set("passwd", "123456")
$ F' J# Q5 \4 Z. Y& x) {1 T1506         return dev
/ q/ C* a, i) L9 P5 S1 R# W其中dev.set("passwd", "123456")是新加入的一行,如果不需要vnc访问输入密码,直接注释掉即可。' ~& _% H4 ?0 u; h+ \
下面是一次解决过程,因开发环境使用的是容器化部署,文件路径比较长。
3 l) Z  b2 c8 ]5 p; r3 s# [解决过程9 Y' G, g% Y7 q! M' a( A) R
查找文件
+ w' Y( e. V6 ?% w$ D: w- W, e. e% f9 w! Q
root@controller1:~# find /var/lib/docker/aufs/diff  -name config.py | grep nova0 L% d( K8 ]1 O) e
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/config.py6 r% h* e3 G  i# ^
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/config.py
8 E1 ?/ s+ O2 g1 M! M5 l/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/common/config.py
+ p0 h  J. X9 y0 R; f进入配置文件所在路径
/ b, D& f9 @. H8 ^8 ]2 m9 S) U  \9 U
4 a  ?  s8 {) `: H3 t) lroot@controller01:~# cd /var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/& b; M, M% J3 q2 {$ H# ^! |" p2 d
root@controller01:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# ls
: ^3 @0 f5 G# H+ P/ iblockinfo.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& }/ t7 r2 O$ K2 @" w. |- n
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: W; I8 G" y! I6 m; `" z  L
修改配置文件
5 \2 U& `6 A! S" f  j6 Q; {2 p( V" ]' P0 f% H
root@controller1:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# vim config.py
您需要登录后才可以回帖 登录 | 开始注册

本版积分规则

关闭

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

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

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

GMT+8, 2026-4-8 15:28 , Processed in 0.048752 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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