-
Notifications
You must be signed in to change notification settings - Fork 322
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
548 additions
and
431 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
------------------------------------------------- | ||
File Name: root_rdp | ||
Description: | ||
Author: Administrator | ||
date: 2019-01-21 | ||
------------------------------------------------- | ||
Change Activity: | ||
2019-01-21: | ||
------------------------------------------------- | ||
""" | ||
from utils.guacamole import MyGuacamole | ||
from utils.crypt_pwd import CryptPwd | ||
from assets.models import ServerAssets | ||
|
||
|
||
class AdminGuacamole(MyGuacamole): | ||
def __init__(self, *args, **kwargs): | ||
super(AdminGuacamole, self).__init__(*args, **kwargs) | ||
self.server = ServerAssets.objects.select_related('assets').get(id=self.scope['path'].split('/')[3]) | ||
self.ip = self.server.assets.asset_management_ip | ||
self.port = self.server.port | ||
self.username = self.server.username | ||
self.password = CryptPwd().decrypt_pwd(self.server.password) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,14 @@ | ||
# -*- coding: utf-8 -*- | ||
import paramiko | ||
import threading | ||
import time | ||
import os | ||
from socket import timeout | ||
from assets.tasks import admin_file | ||
from channels.generic.websocket import WebsocketConsumer | ||
from assets.models import ServerAssets, AdminRecord | ||
from django.conf import settings | ||
from utils.ssh import MySSH | ||
from utils.crypt_pwd import CryptPwd | ||
from conf.logger import fort_logger | ||
from assets.models import ServerAssets | ||
|
||
|
||
class MyThread(threading.Thread): | ||
def __init__(self, chan): | ||
super(MyThread, self).__init__() | ||
self.chan = chan | ||
self._stop_event = threading.Event() | ||
self.start_time = time.time() | ||
self.current_time = time.strftime(settings.TIME_FORMAT) | ||
self.stdout = [] | ||
|
||
def stop(self): | ||
self._stop_event.set() | ||
|
||
def run(self): | ||
while not self._stop_event.is_set() or not self.chan.chan.exit_status_ready(): | ||
time.sleep(0.1) | ||
try: | ||
data = self.chan.chan.recv(1024) | ||
if data: | ||
str_data = data.decode('utf-8', 'ignore') | ||
self.chan.send(str_data) | ||
self.stdout.append([time.time() - self.start_time, 'o', str_data]) | ||
except timeout: | ||
self.chan.send('\n由于长时间没有操作,连接已断开!', close=True) | ||
self.stdout.append([time.time() - self.start_time, 'o', '\n由于长时间没有操作,连接已断开!']) | ||
break | ||
|
||
def record(self): | ||
record_path = os.path.join(settings.MEDIA_ROOT, 'admin_ssh_records', self.chan.scope['user'].username, | ||
time.strftime('%Y-%m-%d')) | ||
if not os.path.exists(record_path): | ||
os.makedirs(record_path, exist_ok=True) | ||
record_file_name = '{}.{}.cast'.format(self.chan.host_ip, time.strftime('%Y%m%d%H%M%S')) | ||
record_file_path = os.path.join(record_path, record_file_name) | ||
|
||
header = { | ||
"version": 2, | ||
"width": self.chan.width, | ||
"height": self.chan.height, | ||
"timestamp": round(self.start_time), | ||
"title": "Demo", | ||
"env": { | ||
"TERM": os.environ.get('TERM'), | ||
"SHELL": os.environ.get('SHELL', '/bin/bash') | ||
}, | ||
} | ||
|
||
admin_file.delay(record_file_path, self.stdout, header) | ||
|
||
login_status_time = time.time() - self.start_time | ||
if login_status_time >= 60: | ||
login_status_time = '{} m'.format(round(login_status_time / 60, 2)) | ||
elif login_status_time >= 3600: | ||
login_status_time = '{} h'.format(round(login_status_time / 3660, 2)) | ||
else: | ||
login_status_time = '{} s'.format(round(login_status_time)) | ||
|
||
try: | ||
AdminRecord.objects.create( | ||
admin_login_user=self.chan.scope['user'], | ||
admin_server=self.chan.host_ip, | ||
admin_remote_ip=self.chan.remote_ip, | ||
admin_start_time=self.current_time, | ||
admin_login_status_time=login_status_time, | ||
admin_record_file=record_file_path.split('media/')[1] | ||
) | ||
except Exception as e: | ||
fort_logger.error('数据库添加用户操作记录失败,原因:{}'.format(e)) | ||
|
||
|
||
class SSHConsumer(WebsocketConsumer): | ||
class SSHConsumer(MySSH): | ||
def __init__(self, *args, **kwargs): | ||
super(SSHConsumer, self).__init__(*args, **kwargs) | ||
self.ssh = paramiko.SSHClient() | ||
self.server = ServerAssets.objects.select_related('assets').get(id=self.scope['path'].split('/')[3]) | ||
self.host_ip = self.server.assets.asset_management_ip | ||
self.width = 150 | ||
self.height = 30 | ||
self.t1 = MyThread(self) | ||
self.remote_ip = self.scope['query_string'].decode('utf8') | ||
self.chan = None | ||
|
||
def connect(self): | ||
if self.scope["user"].is_anonymous: | ||
self.close(code=1007) | ||
else: | ||
self.accept() | ||
|
||
username = self.server.username | ||
try: | ||
self.ssh.load_system_host_keys() | ||
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | ||
self.ssh.connect(self.host_ip, int(self.server.port), username, | ||
CryptPwd().decrypt_pwd(self.server.password), timeout=5) | ||
except Exception as e: | ||
fort_logger.error('用户{}通过webssh连接{}失败!原因:{}'.format(username, self.host_ip, e)) | ||
self.send('用户{}通过webssh连接{}失败!原因:{}'.format(username, self.host_ip, e)) | ||
self.close() | ||
self.chan = self.ssh.invoke_shell(term='xterm', width=self.width, height=self.height) | ||
# 设置如果3分钟没有任何输入,就断开连接 | ||
self.chan.settimeout(60 * 3) | ||
self.t1.setDaemon(True) | ||
self.t1.start() | ||
|
||
def receive(self, text_data=None, bytes_data=None): | ||
self.chan.send(text_data) | ||
|
||
def disconnect(self, close_code): | ||
try: | ||
self.t1.record() | ||
self.t1.stop() | ||
finally: | ||
self.ssh.close() | ||
self.ip = self.server.assets.asset_management_ip | ||
self.port = self.server.port | ||
self.username = self.server.username | ||
self.password = CryptPwd().decrypt_pwd(self.server.password) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from utils.guacamole import MyGuacamole | ||
from assets.models import ServerAssets | ||
from fort.models import FortServerUser | ||
|
||
|
||
class GuacamoleConsumer(MyGuacamole): | ||
def __init__(self, *args, **kwargs): | ||
super(GuacamoleConsumer, self).__init__(*args, **kwargs) | ||
self.fort_server = ServerAssets.objects.select_related('assets').get(id=self.scope['path'].split('/')[3]) | ||
self.fort_user = FortServerUser.objects.get(id=self.scope['path'].split('/')[4]) | ||
self.ip = self.fort_server.assets.asset_management_ip | ||
self.username = self.fort_user.fort_username | ||
self.password = self.fort_user.fort_password | ||
|
||
def connect(self): | ||
if self.scope["user"].is_anonymous: | ||
self.close(code=1007) | ||
else: | ||
self.accept('guacamole') | ||
|
||
server_protocol = self.fort_user.fort_server.server_protocol | ||
if server_protocol == 'vnc': | ||
self.client.handshake(protocol=server_protocol, | ||
hostname=self.ip, | ||
port=self.fort_user.fort_vnc_port, | ||
password=self.password, width=self.width, height=self.height, | ||
dpi=self.dpi) | ||
elif server_protocol == 'rdp': | ||
self.client.handshake(protocol=server_protocol, | ||
hostname=self.ip, port=self.fort_server.port, | ||
password=self.fort_user.fort_password, | ||
username=self.username, width=self.width, height=self.height, dpi=self.dpi) | ||
self.send('0.,{0}.{1};'.format(len(self.group_name), self.group_name)) | ||
self.guacamole_thread.setDaemon(True) | ||
self.guacamole_thread.start() |
Oops, something went wrong.