景知识简介
虚拟机的VNC是非常重要的功能,能够不依赖于虚拟机操作系统的网络进行远程访问与控制。当虚拟机操作系统出现故障或者网络不通等情况时,往往需要通过VNC进行远程连接修复。
noVNC是一个支持HTML5的VNC客户端,主要作用就是与远端的vnc server进行互通,从而实现对于远端主机的控制。我们可以通过VNC客户端或者支持HTML5的浏览器访问远端安装了vnc server的服务器桌面从而进行控制。
而在使用vnc这种便捷的远程访问技术的过程中,敏感数据的安全保障一直是开发人员绕不开的一个话题。而使用密码对用户进行身份认证是保护数据安全的常用手段之一。同时,为了进一步提升安全性能,防止密码被非授权用户轻易获取利用,我们通常会采取对明文密码进行加密的方式,这样既达到了数据安全性的要求,同时也可以避免明文密码保存在服务器上,极大地提高了系统的安全性。让用户在使用时可以更加放心。
问题场景
在业务的开发测试过程中,很多同事使用noVNC后不会退出终端,总是用完了就直接关闭窗口。而使用nmap命令可以获取节点的端口信息,这样的话,如果非授权人员知道了宿主机的IP和端口,是完全可以登录这台虚拟机进行篡改、泄露信息等非法操作的。这对于存放有重要信息的虚拟机来说显然是存在安全隐患的。
VNC密码加解密流程分析
对VNC登录密码加解密流程参考如下:
1、用户创建虚拟机时,需要配置vnc密码;
2、用户自定义密码明文P;
3、使用公钥对明文密码P进行加密,输出密文并存储起来;
4、当用户执行vnc登录等操作,需要身份验证时,系统获取密文;
5、使用私钥对密文进行解密操作,得到明文;
6、对用户输入的密码与解密得到的明文进行比较,如果一样,则用户通过身份验证,可以进入vnc操作虚拟机。
WebSocket 是一个持久化的协议,通过第一次 HTTP Request 建立连接之后,再把通信协议升级成 websocket,保持连接状态,后续的数据交换不需要再重复请求。websocket 可以看成一种类似 TCP/IP 的 socke t技术,在 web 应用中实现、并获得同 TCP/IP 通信一样的双向通信功能,因此客户端既和服务器可以发送消息也可以接收消息,同时还支持多路复用的功能,由于它借用了 HTTP 协议的一些概念,所以被称为 WebSocket。
webSocket API定义了web应用和服务器进行通信的公共接口,具体的构造函数创建对象、对象的属性、方法、事件及它的意义,在上一篇《HTML5(十一)——WebSocket 基础教程》文章中已详细介绍。
WebSocket 协议可分为两部分:握手阶段和数据通信阶段。
WebSocket 为应用层协议,定义在 TCP/IP 协议栈之上,连接服务器的 url 是以 ws 或 wss 开头的。ws 开头的默认TCP端口为80,wss 开头的默认端口为443。
ws(websocket)是不安全的,容易被窃听,只要别人知道你的ip和端口号,任何人都可以去连接通讯。
wss(web socket secure)是websocket的加密版本。
2.1、建立连接
客户端去与服务器建立 TCP 连接,客户端生成 websocket 对象,然后使用 API 建立连接,代码如下:
let ws=new WebSocket('ws://localhost:8888')
ws.onopen=function(){
console.log("连接")
}
2.2、握手阶段
客户端与服务器建立连接之后,客户端发送握手请求,随后服务器发送握手响应即完成握手阶段。
客户端握手请求如下:
'GET / HTTP/1.1',
'Host: localhost:8888',
'Connection: Upgrade',
'Pragma: no-cache',
'Cache-Control: no-cache',
'Upgrade: websocket',
'Origin: file://',
'Sec-WebSocket-Version: 13',
'Accept-Encoding: gzip, deflate, br',
'Accept-Language: zh-CN,zh;q=0.9',
'Sec-WebSocket-Key: In1aAp/ya9Lkv+tsUtXLXQ==',
'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits',
服务器握手响应如下:
Status Code: 101 Switching Protocols
Connection: Upgrade
sec-websocket-Accept: HBMDBbZMiS59r3aAITpGtJ64Mfc=Upgrade: websocket
2.3、数据通讯
WebSocket 握手连接成功之后。可以使用 send 进行发送数据,onmessage 接收数据,如下发送“你好”:
let ws=new WebSocket('ws://localhost:8888')
ws.onopen=function(){
console.log("连接成功")
ws.send("你好")
}
ws.onmessage=function(res){
console.log('接收到的消息',res)
}
服务器打印接收到的数据,如:<Buffer 81 86 af 87 53 b4 4b 3a f3 51 0a 3a>。
websocket 在发送数据时,被组织为一串数据帧,然后进行发送。传送的帧包含两部分:数据帧和控制帧。数据帧可以携带文本数据或者二进制数据,控制帧包含关闭帧和 Ping/Pong 帧。
把接收到的buffer十六进制数据转成二进制数据,控制帧与上述各个类型帧进行对比解析其意义。
2.4、关闭连接
任何一端可以关闭连接。客户端关闭连接如下:
ws.close()
然后发送关闭帧给对方,通常会带有关闭连接的状态码,常见的状态码如下:
3.1、客户端创建websocket对象,并建立连接之后发送数据。其中 ws 地址根据后台服务端口对应。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let ws=new WebSocket('ws://localhost:8888')
ws.onopen=function(){
console.log("连接")
ws.send("你好")
}
ws.onmessage=function(res){
console.log('res',res)
}
</script>
</body>
</html>
3.2、使用 node.js 创建一个 websocket 服务,如创建一个serve.js文件,代码如下:
const http=require("http")
const net=require("net") //原生的websocket
const crypto=require('crypto') // 安全性校验
let serve=net.createServer(sock=>{
//只握手一次
sock.once('data',(data)=>{
console.log("hand shake start") // 开始握手
let str=data.toString();
let lines=str.split('\r\n')
//舍弃第一行和最后两行
lines=lines.slice(1,lines.length-2)
let headers={}
lines.forEach(line=>{
let [key,val]=line.split(': ')
headers[key.toLowerCase()]=val
})
if( headers['upgrade']!='websocket' ){
console.log("其他协议")
sock.end()
}else if(headers['sec-websocket-version']!=13){
console.log("版本不对")
sock.end()
}else{
let key=headers['sec-websocket-key']
let mask='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
//sha1(key+mask) -> base64=>client
let hash=crypto.createHash('sha1')
hash.update(key+mask)
let key2=hash.digest('base64')
sock.write(`HTTP/1.1 101 Switching Protocols\r\nUpgrade:websocket\r\nConnection:Upgrade\r\nsec-websocket-Accept:${key2}\r\n\r\n` )
console.log("hand shake end") // 握手结束
//真正的数据
sock.on('data',res=>{
console.log("真正接收数据",res)
//数据解析
let FIN=res[0]&0x001;
let opcode=data[0]&0x0F0;
let msak=data[1]&0x001;
let payload=data[1]&0x0FE;
})
}
})
//断开
sock.on('end',()=>{
console.log("连接已断开")
})
})
serve.listen("8888")
使用命令 node serve.js 或node serve 启动服务,服务启动成功之后可以使用localhost:8888访问服务。
启动服务之后,访问前边创建的html文件访问websocket服务。
互联网历史长河里,能够留下大名的技术并不多,而Adobe Flash注定是其中一个。在被官方宣布在2020年寿终正寝之后,Flash这款曾经最为普及的软件也只能无奈离去。这款软件叱咤互联网超过20年,也曾经被苹果掌门人乔布斯痛骂,那么他的崛起和衰落是怎样的经历呢?
如果把Flash的发展履历做一个总结的,大致可分为四个阶段,
第一阶段,萌芽期,1995年到1999年,这段时间是Flash从一个插件发展到拥有大量粉丝的工具;
第二阶段,发展期,1999年到2008年,这段时间Flash借助动画的发展一举蜕变成为互联网中不可或缺的一部分;
第三阶段,繁盛期,2008年到2011年,这段时间Flash涉足各个领域,达到了制高点;
第四阶段,衰落期,2011年到2020年,在这段时间中,由于移动互联网的兴起和网络世界的发展,Flash失去了存在的必然性,也逐步开始被遗弃,庆幸的在于,Flash的东家Adobe给出了他的最终死亡时间。
一代宗师的崛起
1995年,一款由简单工具和时间线组成的软件工具Future Splash Animator出现,它作为交互制作软件Director和Authorware的一个小型插件得到了应用,而当时正处于现代互联网的萌芽时期,Windows系统刚刚从DOS系统手中夺权成功,而相应的,Windows系统配套软件开发完善度不足,这就给了flash兴起一个机会。
Macromedia Flash是Flash的乳名
1996年11月,美国Macromedia公司收购了Future Wave,并将这款软件改名为Flash。这款软件也真的像闪电一样迅速得到了各方的认可。由于当时互联网的限制性,HTML的功能限制性很大,而且很难达到人们预期的设计,因此,各种脚本语言开始发掘,网页的设计多样化需求增强,而程序设计需要flash这样一种简单、直观、功能强大的动画设计工具。
Macromedia Flash在推出后,先后在工具中加入了库、影片剪辑,Javascript插件,透明度,独立播放器,文本输入框流媒体,MP3,智能剪辑和HTML文本格式等功能,让flash player几乎成为网络的标准。尤其在1999年flash 4中嵌入的ActionScript函数调用功能,让flash在交互应用中的便捷得到了网络认可,从而发展为全球性方便易用的矢量工具、动画工具、结合矢量位图动画的编程工具。
Flash的崛起与21世纪初的网络状况有密切关联,在当时,网络速度远没有现如今光纤和高速宽带的便捷,用户网络速度普遍在64K/128K/512K/1024K的情况下,称霸互联网的还是各种各样的GIF图片,而想要通过浏览器看视频还需要下载各种各样的播放器插件,这些插件普适性较差,这也给了flash机会。
Flash插件的大小仅有数百KB到几MB大小,却可以提供基于矢量的放大画质保真效果,支持流式播放,支持截取播放等各种播放方式。而且,flash是当时网络上仅有的可以网络在线流畅播放视频的插件,因此其成为了当时时代最火爆的网络插件。
二、网页游戏助飞升空
2005年12月3日,Macromedia Flash 正式被被Adobe公司收购,Adobe Flash的名号打响的同时,也将这款软件推向了最高峰。
2015年Flash改换门庭
Adobe Flash采用的是遮罩、补间动画、逐帧动画和以影片剪辑为主的原件混合后而形成的画质,这种动画中由于不同元素的搭配,形成了多种多样的变化效果。同时,Flash以流式控制技术和矢量技术为基础,制造的动画小而逼真,精度较高,从而在网页动画行业领域中成为了顶梁柱。
而网页动画技术的成熟引发了另一个行业的震动,那就是游戏行业。游戏行业从来与动画行业都是密不可分的,在flash崛起之前,因为画质和宽带等问题的限制,网页游戏一直都是以文字和简单图片为主体的。
Flash Player可以将工作成果输出为exe格式文件,从而即便是在没有安装Flash播放器的电脑上也可以流畅的浏览Flash动画。而且,在巅峰时期,Adobe宣称全世界97%的网络浏览器都内置Flash播放器。有了动画的支持,各类页游开始大肆成长。
QQ农场是典型的flash游戏
在Flash为基础的页游中,腾讯的qq农场可谓个中翘楚。在当时,偷菜成为了网络中最为流行的游戏之一,其火爆程度和话题性甚至能与现如今腾讯的另一款游戏《王者荣耀》相提并论。偷菜的成功便是得益于Flash技术的成熟,Flash拥有完善的IDE工具和活跃的社区,兼容性强,编程语言简单,综合性能强大,直接成为引爆网页游戏的关键。
三、成也萧何败也萧何
软件技术的发展普遍是存在上限的,Flash也不例外。Flash因动画、游戏等崛起,也因其而衰落,由于Flash自身的限制性因素的存在,这款软件逐步进入了消退的时期。
Flash以小而精著称,这一点对于最初的发展年代十分重要。而随着网络情况的不断改良,Flash技术也随之进行的变革,例如增强了性能水准,强化语言能力,并且在企业开发和交互站点中进行了更多层次上的尝试和推广。
Flash Player 7提出了FLV格式视频
Flash已经发展的足够迅速,而问题在于,环境也是变化的。从Flash player 7开始,视频被单独作为一种文件格式开始提取出来,这就是FLV格式的视频。FLV这种视频格式迅速引燃互联网,各种播放器和视频网站如雨后春笋般迅速冒出;更重要的是,支持FLV格式的两套代码是开源的,各大网站间都在后台运行视频格式的转化工具,而在前台以Flash Player播放。这一技术在当时成为了主流,但是在网速不断提升的时代,也事实上架空了Flash。
而另外一个战场网页游戏中,Flash的限制性也开始出现。一些Flash用户发现,在游戏的运行过程中,Flash游戏越玩越卡,这一点是因为Flash弃用了DirectX和OpenGL等底层图形加速,在运算时编译和解释的速度都很难跟上,图形处理速度成为了其最大瓶颈。
Flash动画开始落后
Flash基于二维平面的开发环境而设计,三维效果虽然能达到但是会增加设计的复杂程度和实时计算量从而导致更为卡顿。Flash不能随意访问本地硬盘数据,读写数据量都十分有限,采用的本地共享对象虽然能够提供一些存储能力,但是其无法大量存储游戏进度与玩家信息,从而使得游戏体验感差强人意。
这些原因的存在,决定了Flash只能打造简单的小型游戏,大型页游显然不是他的菜。而就在Flash的原有疆域被压缩时,一个更麻烦的情况来了,Flash的根基PC的网络地位遭到了强有力的挑战,这就是移动互联网的崛起。
四,决战移动端的惨败
Flash最火爆的时代里,手机的功能还只是简单的收发短信、接打电话,即便上网也不过就是浏览一些图片、音乐或者新闻。谁能想到,智能手机的异军突起几乎颠覆了整个互联网的基础,Flash所依赖的根基也被动摇。
Adobe Flash Platform进军移动端的策略是由PC向移动设备渗透,通过Flash Player授权进行收费,然后在每台移动设备中嵌入Flash Player,预收一美金,包括了诺基亚、安卓和苹果都是这个规矩。问题在于,Flash本身就是一个完全封闭的系统,以PC的渗透率来参考移动端显然是个完全失败的想法,而问题在于,当时的智能手机领头羊诺基亚接受了这一条款,这让Adobe坚定了这一策略。可是马上乔布斯老爷子就不干了。
乔布斯:Flash你走吧我不想骂你
谈及Flash的倒下,2010年乔布斯的炮轰可谓是一个转折点。乔布斯的公开信中明确将iPhone、IPad、iPod Touch与Flash划清了界限。尽管苹果在PC领域与Flash的合作不少,可是乔布斯在移动端毅然封杀了Flash。因为苹果也iPhone和iOS系统形成的也是封闭生态,两种完全封闭的生态碰撞很难相容。
苹果的拒绝让人们认清了Flash在移动端绝非不可替代,Flash本身就是为了PC时代而生的产物,一旦用于移动端将变得格格不入。Flash的问题是全方面的, 除了封闭问题外,移动端的生态体系完全与pc端不同,PC端盛行的Flash游戏和视频在移动端既没有需求也没有必要,移动端新兴的手机游戏完全可以摆脱Flash进行。
一山不容二封闭
Flash作为一种陈旧的技术,对性能消耗用于移动端时并不合适。而且从网络安全重视度开始后,Flash的精简变的漏洞百出,安全记录常年倒数。而且在智能手机的触摸屏中,Flash为鼠标而设计的很多功能并不适用,这给相关应用的开发造成了困难。
综合来看,移动时代适用于低功耗、触摸屏和开放网络的技术,Flash已经落后。而真正给予了Flash致命一击的,还当属HTML5技术的成熟。
HTML5:Flash的掘墓人
2012年,Adobe正式宣布放弃移动端仅有的支撑安卓系统,而转为支持HTML5,这意味着Flash在移动端战场的溃败,也意味着HTML5在一个战场中彻底的击溃了Flash。
HTML5之所以成功取代Flash,是因为其提供了新的框架和平台,包括免插件音视频、图像动画、本体存储以及其他功能,这些功能使得应用标准化和开放化,贴切用户的使用习惯,优化用户体验。换言之,HTML5是一种新的技术,而Flash受到框架限制多年来缺乏变革和新意。
HTML5需要成为下一代传奇
HTML5的兼容性极强。Flash需要插件支持,而且不支持跨平台,应用环境窄。而HTML5搭建的站点和应用能够兼容PC端与移动端、Windows与Linux、安卓与IOS。HTML5可以移植到不同的开放平台及应用平台中,与目前主流的编程语言HTML、CSS、DOM、JS等无缝结合,也得到了开发者的认可。
在性能方面,HTML5注重各种引擎的优化,加载速度要比需要插件的Flash快许多。同时,因为各大浏览器注重javascript引擎的优化,在代码运行效率上足够高,因而应用范围宽广,运行效果优质。
安全方面,Flash与HTML5无法相提并论。Adobe Flash的漏洞之多基本已经是公认的,其中很大一部分可能导致严重后果,可致用户遭遇木马病毒的攻击。HTML5可以将代码全部加密,应用时只需解密就可以,提高了安全性能。从开发者培养角度来看,学习Flash成本要大些,而HTML5与原本熟悉的HTML语法相似度很高,无需花费太多时间研习。
基于这些问题的存在,HTML5在移动端彻底赶跑了Flash以后,在PC领域也基本完成了取代。在Adobe宣布了Flash的大限之后,这款超过20岁的软件终于要迎来他生命的终点。从兴起到衰落,Flash经历了PC时代的狂欢,也经历了移动时代的蜕变,这款软件的离去是一代经典的终结,但也是开启下一代经典的钥匙。
Flash,王熙凤,终为聪明累
在最后,用《红楼梦》中王熙凤的曲子形容如今的Flash可谓十分贴切,
“枉费了、意悬悬半世心,
好一似、荡悠悠三更梦。
忽喇喇似大厦倾,
昏惨惨似灯将尽。
呀!一场欢喜忽悲辛。
叹人世,终难定!”
*请认真填写需求信息,我们会在24小时内与您取得联系。