Commit 24730ebd authored by ibuler's avatar ibuler

web terminal记录日志

parent 43c07707
This diff is collapsed.
...@@ -15,7 +15,7 @@ import getpass ...@@ -15,7 +15,7 @@ import getpass
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
config.read(os.path.join(BASE_DIR, 'jumpserver.conf')) config.read(os.path.join(BASE_DIR, 'jumpserver.conf'))
DB_HOST = config.get('db', 'host') DB_HOST = config.get('db', 'host')
......
# coding: utf-8 # coding: utf-8
import time import time
import datetime
import json import json
import os import os
import sys import sys
...@@ -25,6 +26,8 @@ from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE ...@@ -25,6 +26,8 @@ from pyinotify import WatchManager, Notifier, ProcessEvent, IN_DELETE, IN_CREATE
import struct, fcntl, signal, socket, select, fnmatch import struct, fcntl, signal, socket, select, fnmatch
import paramiko import paramiko
from connect import Tty
from connect import TtyLog
try: try:
import simplejson as json import simplejson as json
...@@ -124,12 +127,6 @@ class MonitorHandler(tornado.websocket.WebSocketHandler): ...@@ -124,12 +127,6 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
MonitorHandler.threads.append(thread) MonitorHandler.threads.append(thread)
self.stream.set_nodelay(True) self.stream.set_nodelay(True)
print len(MonitorHandler.threads), len(MonitorHandler.clients)
def on_message(self, message):
self.write_message('Connect WebSocket Success. <br/>')
# 监控日志,发生变动发向客户端
try: try:
for t in MonitorHandler.threads: for t in MonitorHandler.threads:
if t.is_alive(): if t.is_alive():
...@@ -143,6 +140,12 @@ class MonitorHandler(tornado.websocket.WebSocketHandler): ...@@ -143,6 +140,12 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
MonitorHandler.clients.remove(self) MonitorHandler.clients.remove(self)
MonitorHandler.threads.remove(MonitorHandler.threads[client_index]) MonitorHandler.threads.remove(MonitorHandler.threads[client_index])
print len(MonitorHandler.threads), len(MonitorHandler.clients)
def on_message(self, message):
# 监控日志,发生变动发向客户端
pass
def on_close(self): def on_close(self):
# 客户端主动关闭 # 客户端主动关闭
# self.close() # self.close()
...@@ -153,28 +156,34 @@ class MonitorHandler(tornado.websocket.WebSocketHandler): ...@@ -153,28 +156,34 @@ class MonitorHandler(tornado.websocket.WebSocketHandler):
MonitorHandler.threads.remove(MonitorHandler.threads[client_index]) MonitorHandler.threads.remove(MonitorHandler.threads[client_index])
class WebTty(Tty):
def __init__(self, *args, **kwargs):
super(WebTty, self).__init__(*args, **kwargs)
self.login_type = 'web'
self.ws = None
self.input_r = ''
self.input_mode = False
class WebTerminalHandler(tornado.websocket.WebSocketHandler): class WebTerminalHandler(tornado.websocket.WebSocketHandler):
tasks = [] tasks = []
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.chan = None self.term = None
self.ssh = None self.channel = None
self.log_file_f = None
self.log_time_f = None
self.log = None
super(WebTerminalHandler, self).__init__(*args, **kwargs) super(WebTerminalHandler, self).__init__(*args, **kwargs)
def check_origin(self, origin): def check_origin(self, origin):
return True return True
def open(self): def open(self):
self.ssh = paramiko.SSHClient() self.term = WebTty('a', 'b')
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.term.get_connection()
try: self.channel = self.term.ssh.invoke_shell(term='xterm')
self.ssh.connect('127.0.0.1', 22, 'root', 'redhat') WebTerminalHandler.tasks.append(MyThread(target=self.forward_outbound))
except:
self.write_message(json.loads({'data': 'Connect server Error'}))
self.close()
self.chan = self.ssh.invoke_shell(term='xterm')
WebTerminalHandler.tasks.append(threading.Thread(target=self._forward_outbound))
for t in WebTerminalHandler.tasks: for t in WebTerminalHandler.tasks:
if t.is_alive(): if t.is_alive():
...@@ -186,37 +195,50 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): ...@@ -186,37 +195,50 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler):
data = json.loads(message) data = json.loads(message)
if not data: if not data:
return return
if 'resize' in data: if data.get('data'):
self.chan.resize_pty( self.term.input_mode = True
data['resize'].get('width', 80), if str(data['data']) in ['\r', '\n', '\r\n']:
data['resize'].get('height', 24)) TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=self.term.remove_control_char(self.term.input_r)).save()
if 'data' in data: self.term.input_r = ''
self.chan.send(data['data']) self.term.input_mode = False
self.channel.send(data['data'])
def on_close(self): def on_close(self):
self.write_message(json.dumps({'data': 'close websocket'})) print 'On_close'
self.log_file_f.write('End time is %s' % datetime.datetime.now())
self.log.is_finished = True
self.log.end_time = datetime.datetime.now()
self.log.save()
self.close()
def _forward_outbound(self): def forward_outbound(self):
""" Forward outbound traffic (ssh -> websockets) """ self.log_file_f, self.log_time_f, self.log = self.term.get_log_file()
try: try:
data = '' data = ''
pre_timestamp = time.time()
while True: while True:
r, w, e = select.select([self.chan, sys.stdin], [], []) r, w, e = select.select([self.channel, sys.stdin], [], [])
if self.chan in r: if self.channel in r:
recv = self.chan.recv(1024) recv = self.channel.recv(1024)
print recv
if not len(recv): if not len(recv):
return return
data += recv data += recv
try: try:
self.write_message(json.dumps({'data': data})) self.write_message(json.dumps({'data': data}))
now_timestamp = time.time()
self.log_time_f.write('%s %s\n' % (round(now_timestamp-pre_timestamp, 4), len(data)))
self.log_file_f.write(data)
pre_timestamp = now_timestamp
self.log_file_f.flush()
self.log_time_f.flush()
if self.term.input_mode and not self.term.is_output(data):
self.term.input_r += data
data = '' data = ''
except UnicodeDecodeError: except UnicodeDecodeError:
pass pass
finally: finally:
self.close() self.close()
if __name__ == '__main__': if __name__ == '__main__':
tornado.options.parse_command_line() tornado.options.parse_command_line()
app = Application() app = Application()
......
...@@ -127,8 +127,20 @@ ...@@ -127,8 +127,20 @@
var file_path = obj.attr('file_path'); var file_path = obj.attr('file_path');
var wsUri = '{{ web_monitor_uri }}'; var wsUri = '{{ web_monitor_uri }}';
var socket = new WebSocket(wsUri + '?file_path=' + file_path); var socket = new WebSocket(wsUri + '?file_path=' + file_path);
var term = new Terminal({
cols: 80,
rows: 24,
screenKeys: false
});
var tag = $('<div id="term" style="height:500px; overflow: auto;background-color: rgba(0, 0, 0, 0);border: none"></div>');
term.open();
term.resize(80, 24);
socket.onopen = function(evt){ socket.onopen = function(evt){
socket.send(file_path) socket.send('hello');
term.write('~.~ Connect WebSocket Success.~.~ \r\n');
}; };
window.onbeforeunload = function(){ window.onbeforeunload = function(){
...@@ -138,29 +150,15 @@ ...@@ -138,29 +150,15 @@
var username = obj.closest('tr').find('#username').text(); var username = obj.closest('tr').find('#username').text();
var ip = obj.closest('tr').find('#ip').text(); var ip = obj.closest('tr').find('#ip').text();
BootstrapDialog.show({message: function(){ BootstrapDialog.show({message: function(){
//服务器端认证 //服务器端认证
{# socket.send('login', {userid:message.id, filename:message.filename,username:username,seed:seed});#} {# socket.send('login', {userid:message.id, filename:message.filename,username:username,seed:seed});#}
var term = new Terminal({
cols: 80,
rows: 24,
screenKeys: false
});
var tag = $('<div id="term" style="height:500px; overflow: auto;background-color: rgba(0, 0, 0, 0);border: none"></div>');
term.open();
term.resize(80, 24);
window.setTimeout(function(){ window.setTimeout(function(){
$('.terminal').detach().appendTo('#term'); $('.terminal').detach().appendTo('#term');
socket.onmessage = function(evt){ socket.onmessage = function(evt){
term.write(evt.data); term.write(evt.data);
}}, 1000); }}, 1000);
tag[0].style.color = "#00FF00";
return tag[0]; return tag[0];
} , } ,
title:'Jumpserver实时监控 '+' 登录用户名: '+'<span class="text-info">'+username+'</span>'+' 登录主机: '+'<span class="text-info">'+ip, title:'Jumpserver实时监控 '+' 登录用户名: '+'<span class="text-info">'+username+'</span>'+' 登录主机: '+'<span class="text-info">'+ip,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment