易陆发现互联网技术论坛

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

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

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

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

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

x
关于openstack中虚拟机VNC访问安全问题; _3 X1 b7 j$ C  B9 V4 n
前几天收到甲方给出的文件信息,线上OpenStack环境的物理机VNC端口能够自由访问,要求整改。
1 x, z: w- c# B2 i7 o. Y) g2 I( ^随机抽查了两台宿主机的VNC端口,确实很多业务的同学使用noVNC后没有退出终端的习惯,往往都是用完了就直接关闭窗口。不得不说这样隐患很大啊,首先不说通过外部方式规避风险,如果内网里面有一些script kiddie随时都能将我们线上的虚拟机VNC端口扫出来干些坏事。我这里也用过nmap测试了下开发环境的网络端口,如下:
5 S% S0 B4 y' ^  c[root@controller1 ~]# nmap 10.161.53.1
$ S0 n! f* @6 I" d& q2 x- N/ ]! }* g4 zStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST+ Y6 T( ~. v& B; ?3 y, [# C
Nmap scan report for compute10 (10.161.53.1), `( s: z5 s. ~8 {1 B. l  j& W' }1 E4 x9 q
Host is up (0.000080s latency).
; W: V. f: \; p4 [# _Not shown: 989 closed ports! S# I2 T4 I( O( u. t+ O
PORT     STATE SERVICE
/ J$ ^/ q: j& a: N! a22/tcp   open  ssh
! {! z( }/ W5 A* s0 t4 J; g5900/tcp open  vnc, X9 N0 V% z3 ]1 s9 R7 a
5901/tcp open  vnc-1, z$ e: K3 b! L7 O8 m* e% i
5902/tcp open  vnc-2
- V+ M! i8 k' b1 o& v: Z5903/tcp open  vnc-3
  K) E# w; V; K& I6 E6 I" N5904/tcp open  unknown
6 ~3 |  Q5 K/ L9 @  E8 z5906/tcp open  unknown
; d- R  J$ C7 p+ x) w; T, W5907/tcp open  unknown
+ `+ F- W- @3 `+ M3 j" R$ O: q; i5910/tcp open  cm
0 v+ d/ `" o/ B( \  c" d5911/tcp open  cpdlc
+ m7 u( H5 L; d8 I: g7 y8022/tcp open  oa-system4 |$ U& Y5 a5 k" E4 |& j" L
MAC Address: D4:5D:64:08:45:02 (Unknown)* z4 n# I) D/ l- |  P" n6 T
Nmap done: 1 IP address (1 host up) scanned in 1.65 seconds
! [) j5 r: j: `. `0 j1 m' M4 _[root@controller1 ~]# nmap 10.161.53.2
' d! C: H" L# E# hStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST( X( g1 b8 m; ~+ I7 X* _
Nmap scan report for compute11 (10.161.53.2)
/ x: M! Q5 I/ F% h0 H( mHost is up (0.000070s latency).. u) Q  d$ l% b- t  X. l" l! j; \
Not shown: 989 closed ports- z" X- |9 O, Z  T8 q# O8 v9 [
PORT     STATE SERVICE
# B& T' m( ~3 S$ A7 N$ P22/tcp   open  ssh0 W/ w4 a) X9 o( E7 f+ s
5900/tcp open  vnc( V+ `; N/ Y7 F! U
5901/tcp open  vnc-1
' ?" F/ [" ]8 R$ a, X# N/ k: t5902/tcp open  vnc-2+ ]+ k6 e% T$ H% k. q* T" j7 W/ ~
5903/tcp open  vnc-3" M' p1 |( z. V/ k
5904/tcp open  unknown
8 v' G: l  W; C$ e) _# l) W5906/tcp open  unknown
: H8 e- W3 C3 t6 o) X( e9 y! V8 J5907/tcp open  unknown* }: J& u: w) c9 O- M
5911/tcp open  cpdlc- e, r0 Z7 v6 J; m
5915/tcp open  unknown% y% u5 h6 E; r* Q- k2 H, L
8022/tcp open  oa-system; t- A) n; b# n* H
MAC Address: D4:5D:64:07:B3:DA (Unknown)
: s& ?1 C6 r! [# V7 CNmap done: 1 IP address (1 host up) scanned in 1.67 seconds
9 K; O# j( F: O1 Y" M( c[root@controller1 ~]# nmap 10.161.53.3. A$ {+ C& X7 J0 z
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST8 ]. X) e$ k% n3 ~  C, s% s
Nmap scan report for compute01 (10.161.53.3)4 ]/ C6 E9 Q7 t- J
Host is up (0.000076s latency).* h  w: d+ L; n% U7 y! k
Not shown: 992 closed ports
. w* I8 V! q+ o1 ^$ {- W# rPORT     STATE SERVICE7 ^0 `! N* U0 _2 }2 L
22/tcp   open  ssh
3 [) G* o; `+ a# H, Y. h5900/tcp open  vnc" L5 i" U- [8 `; d7 p0 G0 q, E
5901/tcp open  vnc-1
; W# u+ ?( y& w5902/tcp open  vnc-2
# F" |0 M9 i) x. Y! Z8 q# z5903/tcp open  vnc-3
8 m  [) q2 x1 h/ a$ W5904/tcp open  unknown) \: M  h$ x# u
5906/tcp open  unknown& N7 T( J2 h% C3 m3 l7 U. v
8022/tcp open  oa-system# b, U9 s. g3 `/ m
MAC Address: D4:5D:64:08:45:5E (Unknown)
: l/ P; g) ]+ l  S9 E9 H% b4 Q: @Nmap done: 1 IP address (1 host up) scanned in 1.68 seconds
' o8 |  I% @1 ^2 g  u# q[root@controller1 ~]# nmap 10.161.53.4
. |4 [+ R/ |- w( H1 j2 m/ EStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:46 CST# Y1 w0 x2 M, O$ Y4 p8 \/ H! w
Nmap scan report for compute02 (10.161.53.4)* v. \4 j7 |9 E- J
Host is up (0.000081s latency).
' Q! x* K- Q7 @Not shown: 988 closed ports
, w1 g0 X0 G. e1 ePORT     STATE SERVICE: m$ y# Z% u- g2 l, C
22/tcp   open  ssh
" }  x7 p4 @' Z: O( g3 J  f" c5900/tcp open  vnc4 L% ^- v3 {: x; p5 x" g! p6 m
5901/tcp open  vnc-14 f7 O1 V3 J1 e6 m7 y
5902/tcp open  vnc-2; E5 O/ w# F, l* C$ |" Y: }- P
5903/tcp open  vnc-3
% w( t& }! [6 f. |8 e. m9 i1 g5904/tcp open  unknown
2 t5 N9 Y# d* i! y+ i5906/tcp open  unknown
+ P! y- y% b3 @1 N5907/tcp open  unknown
1 d  U+ b% R0 C/ f6 F& z& ^5910/tcp open  cm
6 E& c# R: r" z5911/tcp open  cpdlc
' D* U$ C8 f/ b& c5915/tcp open  unknown
; o0 N; N; Q% H( x4 {# y" O1 z8022/tcp open  oa-system$ r3 r! P3 u" s* a' Q9 f2 S" z
MAC Address: D4:5D:64:08:45:D6 (Unknown)
, G5 `$ b6 h1 X4 \/ pNmap done: 1 IP address (1 host up) scanned in 1.67 seconds) h: b5 ?# q) d% B
[root@controller1 ~]# nmap 10.161.53.5* h( d* g1 o7 Y* M
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
& u, f- k+ @0 \7 W8 B2 ZNmap scan report for compute03 (10.161.53.5)7 o  I5 m5 R6 z* H( H
Host is up (0.000082s latency).
3 L5 z; d; j4 j! @; ZNot shown: 993 closed ports
1 Q. I8 ?# Z& v- C. R% a; |PORT     STATE SERVICE& K; z; T! k1 `/ v6 l0 R0 x
22/tcp   open  ssh! ?# O8 s# H0 `$ u$ D8 [+ H
5900/tcp open  vnc" V/ X  h. L- z5 A8 c4 o
5901/tcp open  vnc-1' C/ ~0 G( V4 l, b
5902/tcp open  vnc-2! O+ c: o3 i0 F* A/ D  k' w
5903/tcp open  vnc-3
- d  u0 }/ ?* i5 B" G8 U2 h- X5 S5904/tcp open  unknown& H& e' n7 l. o/ }( L
8022/tcp open  oa-system5 @4 ?8 a/ Z2 X# v" G; \4 _
MAC Address: D4:5D:64:08:44:DE (Unknown); Q" z/ H, F+ h% w8 O+ @, W/ |
Nmap done: 1 IP address (1 host up) scanned in 1.67 seconds
, Q0 x0 H6 w; H1 H; {8 `9 q[root@controller1 ~]# nmap 10.161.53.6  [/ I6 C. N2 b0 M
Starting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
/ V' q- b9 \6 [1 Z) ?' X3 E. f/ ~Nmap scan report for controller1 (10.161.53.6)5 q8 s9 t' F" w' h0 y  g4 H& Z1 ~' M" n
Host is up (0.000014s latency).& k. V9 X8 G& U
Not shown: 992 closed ports0 T  |/ N6 Y4 J& P
PORT     STATE    SERVICE  k, e1 P; m$ O0 W" O# U, {8 h* H* p5 c
22/tcp   open     ssh
! }2 A+ D  r; T7 [0 K80/tcp   open     http2 S# I( W9 W& n& d5 j  Z, I, j
1984/tcp open     bigbrother9 o  _" |! W8 x$ b2 J
3306/tcp open     mysql
$ w" r* c7 u! e" g4000/tcp filtered remoteanything
% O7 A5 U" D5 ~) C( b2 ]: X4567/tcp open     tram- Q( }+ n* c; _/ j5 d
5000/tcp open     upnp7 d5 s  X% ~, |  @2 y" N' i0 \0 W
5001/tcp open     commplex-link
$ V+ E% C  g4 q+ o8 r" g: Q/ ANmap done: 1 IP address (1 host up) scanned in 2.75 seconds
: }2 z5 ?: ~, M1 L2 T" K* z1 W[root@controller1 ~]# nmap 10.161.53.7
2 ~& W+ Q1 @6 L2 QStarting Nmap 6.40 ( http://nmap.org ) at 2022-01-17 09:47 CST
6 I+ S6 E7 Z5 g3 _1 \4 QNmap scan report for controller2 (10.161.53.7)
0 ]+ |" Q0 ]+ G' z2 m6 f, aHost is up (0.000078s latency).+ c: ^, r+ f- d$ ?, K5 `
Not shown: 993 closed ports( e" g) V4 @+ Z# W% B; M
PORT     STATE SERVICE
; w0 d. v& ]) S+ v4 A% z8 m22/tcp   open  ssh
) K5 e: u+ X1 j. }# p9 M80/tcp   open  http# h8 z! {+ w0 o- r- m6 @
1984/tcp open  bigbrother* J/ d8 _; `- u# ~
3306/tcp open  mysql
8 u5 s; p5 s  i) H4567/tcp open  tram
" f1 [: e6 x; ?2 q5000/tcp open  upnp2 H4 @( r+ ~2 k, T' m
5001/tcp open  commplex-link
/ ]" Q; y8 I( f6 H2 p; ^MAC Address: D4:5D:64:08:45:0A (Unknown)
6 a) r  ~7 C7 iNmap done: 1 IP address (1 host up) scanned in 1.55 seconds8 P- ?  U& V7 V/ |

2 }& g0 v, ?. o结果太恐怖了吧,如果有业务同学在使用noVNC之后没有退出终端,那么另一个人如果知道了宿主机的IP和端口是完全可以登录这台虚拟机的,直接操作虚机,后果不堪设想:
4 A) D% o7 L& Q5 s- L9 r+ N4 s; f7 j% |' y6 M7 N0 ?, M
解决
# [) b4 t2 H3 v# m知道了问题,那就有对应的解决方案!8 n. D; p* L$ O% i$ x6 M
目前我们暂时只想到两个方法来解决这个问题,其他方法还有待大牛给予指导:, J0 b, `" }% A) r  C8 D

. j( P' v: [7 [1 c1 Z& D  `方案一1 d: r. U+ v! }$ u7 @
通过firewalld限制INPUT表对5900:6000的访问规则, J0 ~! {8 w' q) _/ ?9 o& o
方案二
2 d, N3 l, Z  ^; q添加密码访问VNC& q6 |$ x' P* Q  [) E. }! R

( U% h% n! B* |7 R0 j; C操作1 a# ^' }2 m; w" }3 i
firewalld
8 c3 T3 V3 ~; j! j3 n我们知道OpenStack通过VNC Proxy将管理网和业务网隔离开来,以便我们可以使用管理网络的6080端口访问虚拟机VNC,同时提供Token用于验证访问的合法性。一个VNC Proxy在OpenStack里的处理流程如下:

- R8 E% [1 L4 i4 e- U9 ]0 Z2 OVNC Porxy处理流程& k  a4 s7 Y+ _8 a
1. 一个用户试图从浏览器里面打开连接到虚拟机的VNC Client- W( V; y) S5 F  ~
2. 浏览器向nova-api发送请求,要求返回访问vnc的url' a" F" q3 M' B  J5 G9 I. [
3. nova-api调用nova-compute的get vnc console方法,要求返回连接VNC的信息  n7 u2 {3 `3 V
4.nova-compute调用libvirt的get vnc console函数
2 h( m0 h( r7 v/ ]5.libvirt会通过解析虚拟机运行的/etc/libvirt/qemu/instance-0000000c.xml文件来获得VNC Server的信息5 ?7 g$ i: ]9 _
6.libvirt将host, port等信息以json格式返回给nova-compute0 A. G7 P0 K( K& B
7.nova-compute会随机生成一个UUID作为Token7 B  I0 H9 x) e4 n8 b- E, x0 Z) q
8.nova-compute将libvirt返回的信息以及配置文件中的信息综合成connect_info返回给nova-api
  ~6 u& _3 k; p% A9.nova-api会调用nova-consoleauth的authorize_console函数/ G/ T0 G: _! M
10.nova-consoleauth会将instance –> token, token –> connect_info的信息cache起来$ y$ @7 w& Z$ _5 c
11.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
( E1 z* c3 [  `1 l) I+ ?1 O12.浏览器会试图打开这个链接9 e' X& |) `' C% y; L3 `5 S3 m
13.这个链接会将请求发送给nova-novncproxy6 ~$ {' d4 c( w0 x2 c
14.nova-novncproxy调用nova-consoleauth的check_token函数
0 _/ i( @2 P; z( [0 _* F15.nova-consoleauth验证了这个token,将这个instance对应的connect_info返回给nova-novncproxy
5 u- J' }# |2 W1 {" U* n! r16.nova-novncproxy通过connect_info中的host, port等信息,连接compute节点上的VNC Server,从而开始了proxy的工作

3 R  ~% u! q/ Y2 j' Z8 h这里重要的就是第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。5 o' b4 |4 c5 p$ \# c0 g! ]) g
那么也就是说,计算节点的VNC端口只需要让nova-novncporxy服务能够访问就行,有了这个就好办了。
$ u+ f3 V: Y6 [- c
操作firewalld
* `) b: c# B/ C1 {2 t# ]* [在所有计算节点firewalld的INPUT表中添加如下规则:
# k0 l5 H( C# _/ a. k' `) C* p% y8 [0 @7 c9 A5 f/ B! s
检查防火墙是否启动:
! d6 ^8 r3 t" e: ]( P% H+ ^2 \
systemctl status firewalld.service
0 _' ]6 C: \) b9 c, {启动防火墙:5 R( E% W0 u# S, c3 _3 C* i6 _
systemctl start  firewalld.service
: r) Y4 A/ K6 w3 U2 Z1 Y6 _; o
0 I6 `3 n' T" Z- U1 A0 i
: X% s4 v4 Y1 |( P1 a' _0 _; G
开机启动防火墙:7 {. e" N& N/ x4 d5 }4 _6 t2 d, J
systemctl enable firewalld.service
1 o' l) `1 Z! b0 d: z添加规则:9 y- r5 f: I+ n' m( W& m' p
  firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.6" port protocol="tcp" port="5900-6000" accept"
4 a- t+ A# l' e( g5 r   firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.100" port protocol="tcp" port="5900-6000" accept": A3 p7 f8 _& G  d( w) t
firewall-cmd --reload
4 r! L% ^! S+ B' t! {9 v1 [, E' o firewall-cmd --list-all
, r7 p  S9 x  l" }2 ]- o删除规则:& N1 ~5 R+ v; }: T0 ^8 K
  firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="10.161.53.6" port protocol="tcp" port="5900-6000" accept"
5 X( k4 w+ D+ x& K2 @: |2 \4 f; \
firewall-cmd --reload 5 C# O3 N' \" y
firewall-cmd --list-all
' X5 F  ~8 O# `
( N# J: p5 E" {6 p2 c  P6 v$ ^; S
添加防火墙规则:" I0 [8 |2 z( l( t- q
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="10.161.53.31/27" port protocol="tcp" port="5900-6000" accept"
! C  r% q8 z( Q4 K# T& S2 e( g& d0 I0 [7 {
firewall-cmd --reload
! k: l# n' q/ p/ {  Q8 Y% d# I2 ^! v4 @0 P
通过测试上面开启的firewalld会导致业务无法访问。
9 A6 R% b8 `8 i; a  s: o- v5 @这里改变方式使用iptables的规则吧:6 w. T- M8 ^/ ~5 ~! n: \8 b
* t% ?+ o) V' l6 f/ K
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" [$ a4 a9 f! f2 e% D' f+ O! X( \
iptables -L; M) K+ ], ?0 m
iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable, h4 W; U1 O( k, X5 R; G6 s4 k! @# ]

5 H! \8 S% t$ m" _; s' v5 S7 h- }! h8 S( K

& F1 ^3 U) F" ^2 ]( b9 h
 楼主| 发表于 2022-1-17 10:59:40 | 显示全部楼层
4.解决方案
$ _  \8 y5 i/ [/ h7 Y5 D0 ^% x; u  f) U; y) K. [, z
①从交换和防火墙的ACL控制IP访问
, q6 D1 H. Y- Z9 ^②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题
! e* I5 `: [2 i* y! S$ E$ d③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口% N! |5 U% t" T
④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁6 E& E; a' V7 ^& G: S1 y+ x4 [
⑤vnc增加访问密码8 U/ z2 [6 h/ Z* A# Z" g- V; U
8 d* [. g; \/ Z8 x4 V8 t
下面针对方法④和方法⑤进行详细的说明。
% ]& j8 f% a8 Q4 E) ~( _④配置IPtables1 P% m0 T  j5 d! B+ t
根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。$ C+ N" S9 h. c
在所有计算节点IPTABLES的INPUT表中添加如下规则:
! i3 `7 b! t0 P, `) R( v9 u5 ?, T& n" x. N/ m
 楼主| 发表于 2022-1-17 14:49:23 | 显示全部楼层
①从交换和防火墙的ACL控制IP访问6 q% H- Y% v) u( Q4 _+ M8 n
②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题
8 [' T, O# R" j* I0 {③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口
6 e$ `2 }% S; e0 {& e' H④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁
8 E6 a3 i# {. h5 I% K6 }) M0 [⑤vnc增加访问密码0 \# |* P4 J' _; Q# v
下面针对方法④和方法⑤进行详细的说明。
4 L3 C* F% k- N. C④配置IPtables& V( S& h8 N5 |, }! {: [
根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。
, A* ^* n0 L: \" q4 c6 F9 l0 X+ u$ d1 |9 T
在所有计算节点IPTABLES的INPUT表中添加如下规则:
# I8 R: \0 l" d( q% w- G0 ]$ S! l9 m
- K+ k7 f; t1 e$ E: f* |( \  @. R$ 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 a$ j8 }9 v- i) b9 Q3 Y( U8 o: c& F1 D/ g
$ iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable
- B- y# u$ M9 Z1 g8 B0 q, O8 F8 w: f, Z) y
意思就是只允许控制节点访问本机的5900-5999端口,其他的一律拒绝。( T9 \- J; H5 Y0 t
当再次使用nmap进行扫描时,便不能看到VNC的端口。
. T% {$ e0 ^/ o2 f+ j9 l) Z8 I4 M) h  }
$ nmap 10.161.53.1 5900
. l) H, M5 q  ^" _6 R# X$ Z6 `' y⑤VNC添加访问密码  c- p' J) I5 b4 d1 L
对应的配置文件为:virt/libvirt/config.py8 k, {2 A# Y! S/ `

+ T: P* U* r+ H+ I4 U7 x% ~* v8 b# X/ Glibvirtd在<graphics>域里面是支持配置VNC的访问密码
0 k  D; e: @; `* Z% e9 t, u  N% K9 S! W3 m6 ]
..." P6 c" N; g) T
<graphics type='vnc' port='-1' autoport='yes' listen='192.168.23.59' passwd='YOUR-PASSWORD-HERE' keymap='en-us'/>
. h; F$ D( P1 R. I( X: g5 n...
) D" R2 {  [+ _8 {' V' T,那么Nova在创建虚拟机配置的方法中也可以找到对应graphics的代码,我这里修改得很简单,直接在返回的dev列表里面添加个passwd的value,而value就是VNC的访问密码。9 A# m, c7 \5 i: j/ e! J

/ @) q) p  |+ B; o4 o9 y/ ]; aclass LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice):
" `! l# m4 E  S& p9 }9 L
" J$ ~3 J% v/ z5 v    def __init__(self, **kwargs):( o" o2 b$ o- s1 w( e1 W
         super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics",0 F5 ?% ?" S8 l
                                                          **kwargs)  I) U2 Z) H, b# y! r% [; P6 L" F

  r3 J9 r" D& a, x6 a         self.type = "vnc"
7 L- |) r7 V" n- D4 C         self.autoport = True
- X6 v8 C, r) y         self.keymap = None
- X3 U) l0 p9 G6 Z. q* U, Z/ K         self.listen = None+ S- p' L  I2 p9 ~; _% p6 q& q
8 z( E. x& }& l7 |9 g) m
     def format_dom(self):3 ]8 ?1 J6 @6 }( a+ E
         dev = super(LibvirtConfigGuestGraphics, self).format_dom()
" e/ p. H8 [6 R6 s " a, G% _# U; }
         dev.set("type", self.type)
8 \8 S: L, V0 N& W, Z; c8 Y         if self.autoport:: H% G6 r' Z7 e& a. {; \
             dev.set("autoport", "yes")4 {8 }8 C' `8 W9 l* ?
         else:
& O$ F" z6 @/ G7 X             dev.set("autoport", "no")2 A7 B4 r4 F0 Z* t- C: p
         if self.keymap:* v( O5 s+ M0 O9 Q9 Z' W0 C+ h
             dev.set("keymap", self.keymap)
4 b# `! N) l! |* b         if self.listen:6 p$ E  ^1 k! Y( g5 m
             dev.set("listen", self.listen)
$ V, E" }' t& A7 x #       dev.set("passwd", "123456")4 p) a6 l5 A9 {+ r: S  ?: Q
         return dev7 U; _9 F  C" |* ^
其中dev.set("passwd", "123456")是新加入的一行,如果不需要vnc访问输入密码,直接注释掉即可。
5 I& T! }+ }3 Q3 Z( b3 }/ l下面是一次解决过程,因开发环境使用的是容器化部署,文件路径比较长。
' @2 [% r! W# Q( w6 C) s7 i' {解决过程  g# x8 X2 g! @
查找文件) e' c$ l( z9 q& E' {$ b) x* W7 e8 u! s

; A+ N% g0 h3 S7 P$ zroot@controller1:~# find /var/lib/docker/aufs/diff  -name config.py | grep nova
( D# ~( w! y  ]0 ~4 c7 v/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/config.py5 @5 N. [! w* ?! s9 V$ k) r/ I
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/config.py. Y% w/ _) w% y9 D, X
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/common/config.py. Y2 b2 D* s: e7 m& M
进入配置文件所在路径& h- f* h$ }9 `8 I* i, l$ v3 o
5 D% p9 v# f  v5 e
root@controller01:~# cd /var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/
1 i& i8 v3 M- V. j6 X7 mroot@controller01:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# ls, V* R$ |2 e4 I) v' h& k
blockinfo.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
7 J# R: e/ w6 u, V9 n# y$ Nblockinfo.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- u9 m4 Y6 Q$ F9 O
修改配置文件4 }1 o6 `% s, N  j* o6 T7 c
, o1 B# j! ~) l, l  P/ D& Q/ b
root@controller1:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# vim config.py/ Z/ h+ v/ f0 Q; U5 S
在这里插入图片描述
( _& g5 V" @' H: b7 J修改后,重启nova-compute服务,即在下次创建虚拟机的时候生效,其结果如下:
  g4 w& y- E2 G在这里插入图片描述8 W- p4 m% F9 R- H2 \0 E
输入密码virt/libvirt/config.py配置中新增的密码123456即可正进入虚拟机。! P6 d6 b6 F+ W  O  U$ }. i
 楼主| 发表于 2022-1-17 17:05:37 | 显示全部楼层
4.解决方案5 f3 Q' i) H  g) V$ F6 A" J! I" u% Q
①从交换和防火墙的ACL控制IP访问
0 X9 w2 w$ o5 ^1 w3 b②修改各计算节点 nova.conf中 vncserver_listen 配置为内网 IP ,保证新建虚机没问题
" J' D- g9 a9 G% @5 s; ?③现有以及之后新建的的虚拟机,修改 libvirt.xml 中的 vnc 的监听端口,保证虚机重启后不会向公网开放端口0 u3 m, A4 O. G1 m" c) J
④修改IPtables配置规则,屏蔽端口访问,把除内网以外网段的5900~5999端口给封禁/ v# Q/ M& u! q1 ~$ D  M4 e6 Q
⑤vnc增加访问密码. o* \* e1 e7 C1 p1 z5 n
下面针对方法④和方法⑤进行详细的说明。1 ^6 V6 w# |# {4 b% n; q
④配置IPtables! i0 C7 e" P9 i( x5 ]" U
根据OpenStack VNC Proxy 流程分析中的,第16步, nova-novncproxy是通过连接host:vncport的方式提供vnc访问服务。即,计算节点的VNC端口只需要允许让nova-novncporxy服务能够访问就行。
5 m6 k! o' X) o4 Q& A1 ]3 R. T; G" h  H6 B2 I2 R: A) Y
在所有计算节点IPTABLES的INPUT表中添加如下规则:' t; |" o/ g! \% v- [- X

/ z$ F* Y) h5 l* `" f" @$ 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 ACCEPT9 Y# [- H1 e4 G: U& }5 S3 A

3 l/ D; V/ @# P9 @9 v$ iptables -A INPUT -p tcp -m multiport --dports 5900:5999 -j REJECT --reject-with icmp-port-unreachable) k; |% W6 }; ^7 k! ^. V
意思就是只允许控制节点访问本机的5900-5999端口,其他的一律拒绝。. K: ~  ?9 S$ P3 h5 k/ V7 F; ?6 `5 I
当再次使用nmap进行扫描时,便不能看到VNC的端口。1 O+ A: o9 |  _# w; m, P; _8 ^

" g# _) w) w% ^5 C/ ~5 ], ]( x$ nmap 192.168.23.12
. x8 I7 j( L! I# u  [⑤VNC添加访问密码
. G; {9 J7 G  `+ S" B3 X- I对应的配置文件为:virt/libvirt/config.py
4 A+ {' e& B: m7 h$ L" z  N
/ @$ S- Y3 t8 H0 ~; Mlibvirtd在<graphics>域里面是支持配置VNC的访问密码
; T( B- Y/ F: E+ W. V0 F8 R+ q  R: L4 E. F
...
4 ~3 [9 v( @. ]1 g: _ <graphics type='vnc' port='-1' autoport='yes' listen='192.168.23.59' passwd='YOUR-PASSWORD-HERE' keymap='en-us'/>
- m& `0 K# l9 n+ T( |...
% R- }( W+ Z) b( E,那么Nova在创建虚拟机配置的方法中也可以找到对应graphics的代码,我这里修改得很简单,直接在返回的dev列表里面添加个passwd的value,而value就是VNC的访问密码。. _6 X  V% \8 n

: _1 i7 M! j" r8 P1482 class LibvirtConfigGuestGraphics(LibvirtConfigGuestDevice):
: G  ^0 E8 M; U9 A* t1483 ! `" P7 Y1 h, d0 t; u) s$ p
1484     def __init__(self, **kwargs):
8 l1 j. Z8 P3 u5 z% X$ ~- p1485         super(LibvirtConfigGuestGraphics, self).__init__(root_name="graphics",! I# Z6 j; @& G6 \
1486                                                          **kwargs)) z* t+ Y  m0 U$ f: v" t
1487 6 A) B1 N0 W/ b4 ~9 d& ^0 t
1488         self.type = "vnc"
7 d! R2 D* x* z% _1 f# ~* R1489         self.autoport = True4 g/ z' Q& J! }: \( {
1490         self.keymap = None/ b$ u( k# w6 i2 G" Q
1491         self.listen = None+ G# Z% M! r  |  e
1492 8 y+ P8 O+ W. H6 |& l! w9 F
1493     def format_dom(self):9 @/ {' H1 S& U& R' W
1494         dev = super(LibvirtConfigGuestGraphics, self).format_dom()
; ?" {- z$ D$ w, |5 h) D1495
% V- V/ H  M! x- U1496         dev.set("type", self.type)
0 X9 H( @( z# e9 @& b1497         if self.autoport:
; J! a4 K7 p# E" }1 n  q' \3 @9 u1498             dev.set("autoport", "yes")$ Y* D, z, \- @( b0 ^7 ~$ e
1499         else:
6 R; s# J: F; ^+ f; ]1500             dev.set("autoport", "no")
7 _% I9 b+ z" a5 ?4 c& T) p+ d# z, c1501         if self.keymap:- m. Z/ y9 [3 Z6 J  `
1502             dev.set("keymap", self.keymap)5 }, U6 i5 l2 r4 t& O* ^$ ^) T) u
1503         if self.listen:
( U; y8 L" G4 a' U8 z1 j# m3 D" p1504             dev.set("listen", self.listen)$ Z  c# |& g7 q4 ]7 m8 {
1505 #       dev.set("passwd", "123456")
$ O8 b1 M7 g- Y: n0 ^1506         return dev$ ^9 @5 |: ~# C* C) [3 k3 n
其中dev.set("passwd", "123456")是新加入的一行,如果不需要vnc访问输入密码,直接注释掉即可。8 @, V, b7 B" q" E5 ?0 ?
下面是一次解决过程,因开发环境使用的是容器化部署,文件路径比较长。0 ~* P: @- I( L+ h' M- a3 z; G
解决过程
8 w9 m" r# X* w查找文件
# R7 P: u7 E" S1 c% Q# T: c) [, _0 w8 L' e" Q0 C
root@controller1:~# find /var/lib/docker/aufs/diff  -name config.py | grep nova3 |0 G& m8 N3 G& C+ `: W
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/config.py, n  W: J4 O: h; _% i5 I1 m4 d7 [
/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/config.py
  J$ Z. t9 u3 Z  K+ b; o6 o/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/common/config.py3 M" {( B, V3 A; G, Z1 x/ z$ j5 S8 [
进入配置文件所在路径
3 L7 T  h0 Y3 R" _6 Z. O" p$ M% N
root@controller01:~# cd /var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt/: G/ w0 L* a  u2 J5 [: d' ~: v
root@controller01:/var/lib/docker/aufs/diff/pr0XDEZwLDflwwzUPc0mNVYwf6b3wJ4wxEwxNBRlmKMD7qRurdlBck41J8hAkjd3/usr/lib/python2.7/dist-packages/nova/virt/libvirt# ls
' y( i$ @  V6 V# G" d; z* F$ ~blockinfo.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
& W; ^  \0 B1 @' j% B: {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- o/ A& @$ p; m! d
修改配置文件
2 r; E0 l9 s% K, ^  U, O- r. e2 {0 W) o2 l7 d3 f, x# q
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.045288 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2012-2025 Discuz! Team.

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