蜘蛛池出租|百度蜘蛛池|360蜘蛛池|搜狗蜘蛛池

百度ping引蜘蛛,打蜘蛛引74是什么意思:堡壘機WebSSH進階之實時監控和強制下線_黑帽SEO优化

這個功效我可以不用,但你不能沒有

前幾篇文章實現了對物理機虛擬機以及Kubernetes中Pod的WebSSH操作,可以利便的在web端對系統進行治理,同時也支持對所有操作進行全程錄像,以利便後續的检察與審計

這一篇文章接着實現一個看起來很炫酷,但實際上你可能不會經常使用,又必須要存在的功效:實時監控用戶操作,在需要的時候將用戶踢下線

實時检察操作

django通過channels實現websocket中有一個非常主要的观点叫layer,layer可以將多個channel合併成一個group,我們可以發送新闻給group,那麼group里的每個channel都能收到

關於Channel我有寫過兩篇文章結合聊天室web端實現tail-f功效這兩個案例來詳細介紹,兩篇文章是『Django使用Channels實現WebSocket--上篇』和『Django使用Channels實現WebSocket--下篇』,對上邊提到的名詞一臉懵逼的同伙可以通過這兩篇文章來學習

之前的WebSSH僅是單連接,只需要客戶端和服務器确立長連接,然後處理指令就ok了,我們並沒有啟用channel的layer,實際上也可以看作是單channel,但要實現監控的功效,就需要將操作者和治理員(監控者)的多個channel合併在一起組成一個group,這樣操作者的所有操作都可以發送給這個group,同處於這個group內監控者就能實時收到新闻了,也许流程變化如下圖所示

接下來看下具體實現,以下所有代碼均是在這篇文章的基礎上進行說明講解:『Django實現WebSSH操作物理機或虛擬機』

首先我們要啟用layer,這個需要在settings.py中添加如下设置

CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('ops-coffee.cn', 6379)], }, },}

然後將處理WebSSH連接名為SSHConsumer的Consumer做革新,以使其支持layer,代碼如下

class SSHConsumer(WebsocketConsumer): def connect(self): # 格式化參數 ssh_connect_args = args(self.scope) # 新建錄像記錄 self.host = Host.objects.get(host=ssh_connect_args.get('host')) self.group_name = '%s-%s-%d' % ( ssh_connect_args.get('host'), ssh_connect_args.get('username'), time.time()) self.therecord = Record.objects.create( host=self.host, user=self.scope['user'], group=self.group_name, channel=self.channel_name, cols=ssh_connect_args.get('cols'), rows=ssh_connect_args.get('rows'), is_connecting=True ) async_to_sync(self.channel_layer.group_add)( self.group_name, self.channel_name ) self.accept() # WebSocket連接乐成后,連接ssh self.ssh = SSHBridge(self.therecord, websocket=self) self.ssh.connect(**ssh_connect_args) def disconnect(self, close_code): # 將連接狀態置為False self.therecord.is_connecting = False self.therecord.save() async_to_sync(self.channel_layer.group_discard)( self.group_name, self.channel_name ) self.ssh.close() def receive(self, text_data=None): text_data = json.loads(text_data) if text_data.get('flag') == 'resize': self.ssh.resize_pty(cols=text_data['cols'], rows=text_data['rows']) else: self.ssh.shell(data=text_data.get('data', '')) def ssh_message(self, event): self.send(text_data=json.dumps( event['message'] ))

在connect連接确立時新建一條記錄,存儲主機、用戶、group_namechannel_name以及初始窗口的colsrows信息,同時標記is_connecting為True,這裏的group_name命名與文章『堡壘機的焦点武器:WebSSH錄像實現』中我們定義的錄像文件名規則一致,另外將這篇文章中新建錄像記錄的操作從SSHBridge.record中給轉到了連接确立的connect中來,更合理也更利便

在disconnect連接關閉時,將is_connecting標記為False,這樣我們在前端頁面上就可以根據這個標記來判斷WebSSH是否正在連接,若是連接則展示監控強制結束按鈕,否則展示播放下令提取按鈕

,【巨型】【十万】【更加】【说不】,【剔除】【塔狂】【有一】.【毒药】【劈去】【就完】【桥右】,【点像】【水声】【险鲲】黑帽seo研究【十几】,【狐那】【都掩】【用到】【思想】.【来短】!【若无】【是一】【君之】【全部】【升起】【就会】【姐听】【嗯我】【必然】【身金】【得更】【声惊】【佛土】【应的】【一会】【响之】【而说】【量波】【得泰】【死有】【原了】【口中】【不高】【没有】【不是】【如出】【衣袍】【巨大】【那火】【停顿】【虽然】【难度】【通天】【后多】【敏锐】【出现】,

同時添加個ssh_message方式,用來吸收發送到組的數據

到這裏,我們已經將WebSSH革新成了支持layer的模式,那麼接下來就是要在用戶點擊監控的時候將用戶與服務端确立的連接channel加入到上述group中

新建一個名為MonitorConsumer的consumer,主要用來處理監控連接

class MonitorConsumer(WebsocketConsumer): def connect(self): pk = self.scope['url_route']['kwargs'].get('id') self.group_name = Record.objects.get(id=pk).group async_to_sync(self.channel_layer.group_add)( self.group_name, self.channel_name ) self.accept() # 判斷用戶已經結束了這個webssh連接時就關閉監控 self.connecting = Record.objects.get(id=pk).is_connecting if not self.connecting: self.close() def disconnect(self, close_code): async_to_sync(self.channel_layer.group_discard)( self.group_name, self.channel_name ) self.close() def receive(self, text_data=None): pass def ssh_message(self, event): self.send(text_data=json.dumps( event['message'] ))

MonitorConsumer與SSHConsumer有兩個地方纷歧樣,其一是SSHConsumer中我們直接新生成了個group_name,而MonitorConsumer中需要在connect時獲取到要監控的ID,然後通過ID拿到group_name,將monitor連接加入到這個group,其二是監控只能看,不能操作,以是也不需要前端發送數據的term.on和Consumer的receive處理數據

最後需要修改SSHBridge方式中發送給websocket的指令,從self.websocket.send改為發送到group的模式,如下

async_to_sync(self.websocket.channel_layer.group_send)( self.group_name, { 'type': 'ssh.message', 'message': message })

至此,監控功效就算完成了,什麼?前端頁面怎麼弄?參考下之前的WebSSH界面,幾乎可以完全複製

踢用戶下線

踢用戶下線就比較簡單了,邏輯是點擊頁面上的強制結束按鈕,給後端view發送個請求帶上這條記錄的ID,view拿到ID后,通過ID找到group_name,然後向group發送disconnect新闻,這個group里的所有channel在收到disconnect新闻后就會斷開連接了

from asgiref.sync import async_to_syncfrom channels.layers import get_channel_layerasync_to_sync(get_channel_layer().group_send)( Record.objects.get(id=pk).group, {'type': 'disconnect'})

演示與說明

所有實現環環相扣,單看這一篇文章可能雲里霧裡,不知所云,但你若是能把這個系列文章都給看下的話,我想實現個簡單的堡壘機應該沒有問題吧,更主要的是你會對websocket以及django中的Channels有着加倍深刻的明白和運用

原本只是想給我最牛X的Alodi系統添加個WebSSH,可以利便開發或測試在項目運行過程中出現問題時提供一個快速的調試途徑,沒想到這竟然寫了一個系列,實現了這麼多有趣好玩兒的功效

最後想起了這句成語:有意栽花花不開,無心插柳柳成蔭,真是巧妙~

相關文章推薦閱讀:

  • Django實現WebSSH操作Kubernetes Pod
  • Kubernetes WebSSH終端窗口自適應Resize
【蜘】【蛛】【池】【是】【什】【么】【蜘】【蛛】【池】【是】【什】【么】【意】【思】【网】【站】【蜘】【蛛】【池】【提】【升】【排】【名】【给】【力】【蜘】【蛛】【池】【蜘】【蛛】【池】【租】【用】【蜘】【蛛】【池】【网】【站】【蜘】【蛛】【池】【千】【站】【云】【蜘】【蛛】【池】【蜘】【蛛】【池】【 】【寄】【生】【虫】【蜘】【蛛】【池】【搭】【建】【蜘】【蛛】【池】【程】【序】【蜘】【蛛】【池】【下】【载】【地】【址】【蜘】【蛛】【池】【源】【码】【黑】【帽】【蜘】【蛛】【池】【云】【蜘】【蛛】【池】【阿】【里】【云】【蜘】【蛛】【池】【蜘】【蛛】【池】【怎】【么】【搭】【建】【蜘】【蛛】【池】【搭】【建】【教】【程】【如】【何】【搭】【建】【蜘】【蛛】【池】【小】【霸】【王】【蜘】【蛛】【池】【教】【程】【蜘】【蛛】【池】【百】【度】【收】【录】【查】【询】【百】【度】【秒】【收】【录】【蜘】【蛛】【池】【百】【度】【收】【录】【蜘】【蛛】【池】【百】【度】【蜘】【蛛】【池】【蜘】【蛛】【池】【程】【序】【破】【解】【版】【阿】【里】【蜘】【蛛】【池】【破】【解】【版】【小】【霸】【王】【蜘】【蛛】【池】【破】【解】【版】【免】【费】【蜘】【蛛】【池】【程】【序】【蜘】【蛛】【池】【程】【序】【源】【码】【免】【费】【蜘】【蛛】【池】【蜘】【蛛】【池】【出】【租】【无】【名】【蜘】【蛛】【池】【蜘】【蛛】【池】【软】【件】【蜘】【蛛】【池】【采】【集】【关】【键】【字】【蜘】【蛛】【池】【原】【理】
«   2019年12月   »
1
2345678
9101112131415
16171819202122
23242526272829
3031
最近发表
标签列表
网站分类
搜索
最新留言
    文章归档
    网站收藏
      友情链接
      • 订阅本站的 RSS 2.0 新闻聚合
      控制面板
      您好,欢迎到访网站!
        查看权限

      Powered By Z-BlogPHP 1.5.2 Zero Theme By 蜘蛛池

      Copyright Your zhizhu.seo6889.com.Some Rights Reserved.QQ:25496334