def __set_required_variables(self): host_data = self.host_data # 设置 connection 插件连接方式 self.set_variable('ansible_connection', settings.ANSIBLE_CONNECTION_TYPE) # ssh 连接参数,提升速度, 仅到连接插件为 ssh 时生效,paramiko 模式下不生效 if settings.ANSIBLE_CONNECTION_TYPE == 'ssh': self.set_variable( 'ansible_ssh_args', '-C -o ControlMaster=auto -o ControlPersist=60s') # self.set_variable('ansible_host_key_checking', False) self.set_variable('ansible_ssh_host_key_checking', False) self.set_variable('ansible_host', host_data['ip']) self.set_variable('ansible_port', host_data['port']) if host_data.get('username'): self.set_variable('ansible_user', host_data['username']) # 添加密码和秘钥 if host_data.get('password'): self.set_variable('ansible_ssh_pass', decrypt(host_data['password'])) if host_data.get('private_key'): self.set_variable('ansible_ssh_private_key_file', host_data['private_key']) if settings.ANSIBLE_CONNECTION_TYPE == 'ssh': self.set_variable('ansible_ssh_pipelining', True) # 添加become支持 become = host_data.get('become', False) if become: self.set_variable('ansible_become', True) self.set_variable('ansible_become_method', become.get('method', 'sudo')) if become.get('method', 'sudo') == 'sudo': if settings.ANSIBLE_CONNECTION_TYPE == 'ssh': # ansible_ssh_pipelining 可以加快执行速度,但是不兼容 sudo,仅到连接插件为 ssh 时生效,paramiko 不生效 self.set_variable('ansible_ssh_pipelining', False) self.set_variable('ansible_become_user', become.get('user', 'root')) self.set_variable('ansible_become_pass', decrypt(become.get('pass', ''))) else: self.set_variable('ansible_become', False)
def set_ssh_args(self, hostid): # 准备proxy_client ==>> ssh_server连接参数,用于后续SSH、SFTP # remote_host = RemoteUserBindHost.objects.get(id=hostid, enabled=True) if self.user_role and self.http_user == 'admin': hosts = RemoteUserBindHost.objects.filter(pk=hostid, enabled=True) else: hosts = RemoteUserBindHost.objects.filter( Q(user__username=self.http_user) | Q(group__user__username=self.http_user), pk=hostid, enabled=True ).distinct() if not hosts: raise Exception("不存在的主机") else: remote_host = hosts[0] self.hostname = remote_host.hostname self.superusername = remote_host.remote_user.superusername self.superpassword = decrypt(remote_host.remote_user.superpassword) host = remote_host.ip port = remote_host.port user = remote_host.remote_user.username passwd = decrypt(remote_host.remote_user.password) # self.ssh_args = ('192.168.223.112', 22, 'root', '123456') self.ssh_args = (host, port, user, passwd)
def subscription(self, zmq_message): try: action, encrypted_message = zmq_message; #decrypt the message here zmq_iv = encrypted_message[0:12] zmq_cipher = encrypted_message[12:-16] zmq_tag = encrypted_message[-16:] zmq_decrypted = decrypt(self.hashed_key, "", zmq_iv, zmq_cipher, zmq_tag) message = zmq_decrypted #logging.debug("decrypted message: %s"%message) return self.process_received_message(action, message); except: logging.error("Invalid message: %s"%zmq_message) return False
def load(filename, password=None, zip=True): """ Load previously (compressed if ``zip``) SessionLog XML data from ``filename`` and return an SessionLogRO instance for it. A ``password`` can optionally be passed if data was written in an encrypted fashion. (For information about the XML structure see the documentation for the SeesionLog class). NOTE: parse errors will be reported back as ``IOError`` to keep error handling clean and simple, detailed errors are useless since manual inspection needed anyways to determine cause of corruption. """ if zip: data = gzip.open(filename, "rb").read() else: data = open(filename, "rt").read() if password: data = crypto.decrypt(data, password) try: return SessionLogRO(ET.fromstring(data)) except Exception, e: raise IOError("Corrupt session log")
def decrypt(self, data, data_iv, data_tag): return decrypt(self.db_encryption_key, "", data_iv, data, data_tag)
def session_download(request, pk): def file_iterator(file_name, chunk_size=8192): with open(file_name, 'rb') as f: while 1: c = f.read(chunk_size) if c: yield c else: break os.remove(file_name) terminal_log( username, remote_host.hostname, remote_host.ip, 'sftp', remote_host.port, remote_host.remote_user.username, '下载文件 {}'.format(download_file), 'nothing', request.META.get('REMOTE_ADDR', None), # 客户端 ip request.META.get('HTTP_USER_AGENT', None), start_time, ) download_file = request.POST.get('real_download_file', None) if not download_file: error_message = '参数不正确!' return HttpResponse(error_message) username = request.session.get('username') if request.session['issuperuser'] and request.session['username'] == 'admin': hosts = RemoteUserBindHost.objects.filter(pk=pk, enabled=True) else: hosts = RemoteUserBindHost.objects.filter( Q(user__username=username) | Q(group__user__username=username), pk=pk, enabled=True ).distinct() if not hosts: error_message = '不存在的主机!' return JsonResponse({"code": 400, "error": error_message}) try: start_time = timezone.now() remote_host = hosts[0] download_file_path = os.path.join(settings.MEDIA_ROOT, username, 'download', remote_host.ip) if not os.path.exists(download_file_path): os.makedirs(download_file_path, exist_ok=True) file_path, file_name = os.path.split(download_file) local_file = '{}/{}'.format(download_file_path, file_name) sftp = SFTP( remote_host.ip, remote_host.port, remote_host.remote_user.username, decrypt(remote_host.remote_user.password) ) downloaded = sftp.download_file(download_file, local_file) if not downloaded: error_message = '下载文件错误!' return HttpResponse(error_message) if os.path.getsize(local_file) == 0: os.remove(local_file) error_message = '下载文件错误!' return HttpResponse(error_message) # response = FileResponse(open(local_file, 'rb')) # 使用FileResponse,会占用大内存 response = FileResponse(file_iterator(local_file)) # 使用FileResponse, 并且使用迭代器,不占内存,还可以根据chunk_size控制带宽 response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urlquote(file_name)) # url 编码中文 return response except Exception: error_message = '下载文件错误!' return HttpResponse(error_message)
def session_upload(request, pk): username = request.session.get('username') if request.session['issuperuser'] and request.session['username'] == 'admin': hosts = RemoteUserBindHost.objects.filter(pk=pk, enabled=True) else: hosts = RemoteUserBindHost.objects.filter( Q(user__username=username) | Q(group__user__username=username), pk=pk, enabled=True ).distinct() if not hosts: error_message = '不存在的主机!' return JsonResponse({"code": 400, "error": error_message}) try: remote_host = hosts[0] # upload_file = request.FILES.get('upload_file') upload_file = request.FILES.get('fileBlob') file_name = request.POST.get('fileName') # 使用md5后的文件名保存分段,防止合并时因为文件名的原因出错 file_name_md5 = hashlib.md5(file_name.encode(encoding='UTF-8')).hexdigest() file_chunk_count = request.POST.get('chunkCount') file_chunk_index = request.POST.get('chunkIndex') file_size = request.POST.get('fileSize') upload_file_path = os.path.join(settings.MEDIA_ROOT, username, 'upload', remote_host.ip) if not os.path.exists(upload_file_path): os.makedirs(upload_file_path, exist_ok=True) local_file = '{}/{}'.format(upload_file_path, '{}_{}_{}'.format( file_name_md5, file_chunk_count, int(file_chunk_index) + 1) ) with open(local_file, 'wb') as f: for chunk in upload_file.chunks(): f.write(chunk) complete = file_combine(int(file_size), int(file_chunk_count), upload_file_path, file_name, file_name_md5) uploaded = False remote_path = None if complete: start_time = timezone.now() sftp = SFTP( remote_host.ip, remote_host.port, remote_host.remote_user.username, decrypt(remote_host.remote_user.password) ) uploaded, remote_path = sftp.upload_file(file_name, upload_file_path) os.remove('{}/{}'.format(upload_file_path, file_name)) terminal_log( username, remote_host.hostname, remote_host.ip, 'sftp', remote_host.port, remote_host.remote_user.username, '上传文件 {}/{}'.format(remote_path, file_name), 'nothing', request.META.get('REMOTE_ADDR', None), # 客户端 ip request.META.get('HTTP_USER_AGENT', None), start_time, ) mess = { "code": 200, "chunkIndex": file_chunk_index, "filename": file_name, "complete": complete, "uploaded": uploaded, "remote_path": remote_path } return JsonResponse(mess) # fileinput 分片上传 except Exception: error_message = '上传文件错误!' return JsonResponse({"code": 401, "error": error_message})
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机 :return: """ self.accept() async_to_sync(self.channel_layer.group_add)(self.group, self.channel_name) # 加入组 self.start_time = timezone.now() self.session = self.scope.get('session', None) if not self.session.get('islogin', None): # 未登录直接断开 websocket 连接 self.message['status'] = 2 self.message['message'] = 'You are not login in...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) if 'webssh终端' not in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.message['status'] = 2 self.message['message'] = '无权限' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) self.check_login() query_string = self.scope.get('query_string').decode() ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = ssh_args.get('width') height = ssh_args.get('height') width = int(width) height = int(height) auth = None ssh_key_name = '123456' hostid = int(ssh_args.get('hostid')) try: if not self.session['issuperuser']: # 普通用户判断是否有相关主机或者权限 hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(enabled=True), Q(user__username=self.session['username']) | Q(group__user__username=self.session['username']), ).distinct() else: hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(enabled=True), ).distinct() if not hosts: self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)( self.group, { "type": "chat.message", "text": message, }) self.close(3001) self.remote_host = RemoteUserBindHost.objects.get(id=hostid) except Exception: print(traceback.format_exc()) self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) host = self.remote_host.ip port = self.remote_host.port user = self.remote_host.remote_user.username passwd = decrypt(self.remote_host.remote_user.password) timeout = 15 self.ssh = SSH(websocker=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': timeout, 'pty_width': width, 'pty_height': height, 'password': passwd, } if auth == 'key': ssh_key_file = os.path.join(TMP_DIR, ssh_key_name) with open(ssh_key_file, 'r') as f: ssh_key = f.read() string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek(0) ssh_connect_dict['ssh_key'] = string_io os.remove(ssh_key_file) self.ssh.connect(**ssh_connect_dict) if self.remote_host.remote_user.enabled: if self.remote_host.remote_user.superusername: if '登陆后su跳转超级用户' in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.ssh.su_root( self.remote_host.remote_user.superusername, decrypt(self.remote_host.remote_user.superpassword), 1, ) for i in self.scope['headers']: if i[0].decode('utf-8') == 'user-agent': self.user_agent = i[1].decode('utf-8') break for i in self.scope['headers']: if i[0].decode('utf-8') == 'x-real-ip': self.client = i[1].decode('utf-8') break if i[0].decode('utf-8') == 'x-forwarded-for': self.client = i[1].decode('utf-8').split(',')[0] break self.client = self.scope['client'][0] data = { 'name': self.channel_name, 'group': self.group, 'user': self.session.get('username'), 'host': host, 'username': user, 'protocol': self.remote_host.protocol, 'port': port, 'type': 1, # 1 webssh 'address': self.client, 'useragent': self.user_agent, } TerminalSession.objects.create(**data)
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 telnet 主机 :return: """ self.accept() async_to_sync(self.channel_layer.group_add)(self.group, self.channel_name) # 加入组 self.start_time = timezone.now() self.session = self.scope.get('session', None) if not self.session.get('islogin', None): # 未登录直接断开 websocket 连接 self.message['status'] = 2 self.message['message'] = 'You are not login in...' message = json.dumps(self.message) self.send(message) self.close(3001) if 'webtelnet终端' not in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.message['status'] = 2 self.message['message'] = '无权限' message = json.dumps(self.message) self.send(message) self.close(3001) self.check_login() query_string = self.scope.get('query_string') telnet_args = QueryDict(query_string=query_string, encoding='utf-8') hostid = int(telnet_args.get('hostid')) try: if not self.session['issuperuser']: # 普通用户判断是否有相关主机或者权限 hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(enabled=True), Q(user__username=self.session['username']) | Q(group__user__username=self.session['username']), ).distinct() else: hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(enabled=True), ).distinct() if not hosts: self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)( self.group, { "type": "chat.message", "text": message, }) self.close(3001) self.remote_host = RemoteUserBindHost.objects.get(id=hostid) except Exception: print(traceback.format_exc()) self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) host = self.remote_host.ip port = self.remote_host.port user = self.remote_host.remote_user.username passwd = decrypt(self.remote_host.remote_user.password) timeout = 15 self.telnet = Telnet(websocker=self, message=self.message) telnet_connect_dict = { 'host': host, 'user': user, 'port': port, 'password': passwd, 'timeout': timeout, } self.telnet.connect(**telnet_connect_dict) if self.remote_host.remote_user.enabled: if self.session.get('issuperuser', None): # 超级管理员才能使用 su 跳转功能 if self.remote_host.remote_user.superusername: self.telnet.su_root( self.remote_host.remote_user.superusername, decrypt(self.remote_host.remote_user.superpassword), 1, ) for i in self.scope['headers']: if i[0].decode('utf-8') == 'user-agent': self.user_agent = i[1].decode('utf-8') break for i in self.scope['headers']: if i[0].decode('utf-8') == 'x-real-ip': self.client = i[1].decode('utf-8') break if i[0].decode('utf-8') == 'x-forwarded-for': self.client = i[1].decode('utf-8').split(',')[0] break self.client = self.scope['client'][0] data = { 'name': self.channel_name, 'group': self.group, 'user': self.session.get('username'), 'host': host, 'username': user, 'protocol': self.remote_host.protocol, 'port': port, 'type': 5, # 5 webtelnet 'address': self.client, 'useragent': self.user_agent, } TerminalSession.objects.create(**data)
def connect(self): self.accept('guacamole') async_to_sync(self.channel_layer.group_add)(self.group, self.channel_name) # 加入组 self.session = self.scope.get('session', None) if not self.session.get('islogin', None): # 未登录直接断开 websocket 连接 self.close(3001) if 'webguacamole终端' not in self.session[settings.INIT_PERMISSION]['titles']: # 判断权限 self.close(3001) if not self.session['issuperuser']: hosts = RemoteUserBindHost.objects.filter( Q(id=self.hostid), Q(enabled=True), Q(user__username=self.session['username']) | Q(group__user__username=self.session['username']), ).distinct() else: hosts = RemoteUserBindHost.objects.filter( Q(id=self.hostid), Q(enabled=True), ).distinct() if not hosts: self.close(3001) self.remote_host = RemoteUserBindHost.objects.get(id=self.hostid) _type = 7 if self.remote_host.get_protocol_display() == 'vnc': # vnc 登陆不需要账号 _type = 8 self.guacamoleclient = Client(websocker=self) self.guacamoleclient.connect( protocol=self.remote_host.get_protocol_display(), hostname=self.remote_host.ip, port=self.remote_host.port, username=self.remote_host.remote_user.username, password=decrypt(self.remote_host.remote_user.password), width=self.width, height=self.height, dpi=self.dpi, ) for i in self.scope['headers']: if i[0].decode('utf-8') == 'user-agent': self.user_agent = i[1].decode('utf-8') break for i in self.scope['headers']: if i[0].decode('utf-8') == 'x-real-ip': self.client = i[1].decode('utf-8') break if i[0].decode('utf-8') == 'x-forwarded-for': self.client = i[1].decode('utf-8').split(',')[0] break self.client = self.scope['client'][0] data = { 'name': self.channel_name, 'group': self.group, 'user': self.session.get('username'), 'host': self.remote_host.ip, 'username': self.remote_host.remote_user.username, 'protocol': self.remote_host.protocol, 'port': self.remote_host.port, 'type': _type, # 7 webrdp 8 webvnc 'address': self.client, 'useragent': self.user_agent, } TerminalSession.objects.create(**data) t = threading.Thread(target=self.check_timeout) t.daemon = True t.start()
def connect(self): self.accept('guacamole') async_to_sync(self.channel_layer.group_add)(self.group, self.channel_name) # 加入组 self.session = self.scope.get('session', None) if not self.session.get('islogin', None): # 未登录直接断开 websocket 连接 self.close(3001) if 'webguacamole终端' not in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.close(3001) if not self.session['issuperuser']: hosts = RemoteUserBindHost.objects.filter( Q(id=self.hostid), Q(enabled=True), Q(user__username=self.session['username']) | Q(group__user__username=self.session['username']), ).distinct() else: hosts = RemoteUserBindHost.objects.filter( Q(id=self.hostid), Q(enabled=True), ).distinct() if not hosts: self.close(3001) self.remote_host = RemoteUserBindHost.objects.get(id=self.hostid) _type = 7 if self.remote_host.get_protocol_display() == 'vnc': # vnc 登陆不需要账号 _type = 8 # guacamole 连接性能参数设置 # enable_wallpaper 如果设置为true,则开启桌面壁纸渲染。默认为不开启 # enable_theming 如果设置为true,则开启窗口和控件的主题。默认为不开启 # enable_font_smoothing 如果设置为“true”,文本将以平滑的边缘呈现。默认情况下,RDP上的文本粗体呈现,因为这减少了文本使用的颜色数量,从而减少了连接所需的带宽。 # enable_full_window_drag 如果设置为“true”,窗口的内容将随着窗口的移动而显示。默认情况下,RDP服务器将仅在窗口拖动时绘制窗口边框。 # enable_desktop_composition 如果设置为“true”,则允许使用透明窗口和阴影等图形效果。默认情况下,此类效果(如果可用)被禁用。 # enable_menu_animations 如果设置为“true”,菜单开启和关闭动画将被允许。默认情况下禁用菜单动画。 self.guacamoleclient = Client(websocker=self) if 'webguacamole终端文件上传下载' not in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.guacamoleclient.connect( protocol=self.remote_host.get_protocol_display(), hostname=self.remote_host.ip, port=self.remote_host.port, username=self.remote_host.remote_user.username, password=decrypt(self.remote_host.remote_user.password), width=self.width, height=self.height, dpi=self.dpi, enable_font_smoothing="true", ) else: self.guacamoleclient.connect( protocol=self.remote_host.get_protocol_display(), hostname=self.remote_host.ip, port=self.remote_host.port, username=self.remote_host.remote_user.username, password=decrypt(self.remote_host.remote_user.password), width=self.width, height=self.height, dpi=self.dpi, enable_drive="true", drive_name="filesystem", drive_path="/fs/{}".format(self.group), create_drive_path="true", # enable_wallpaper="true", # enable_theming="true", enable_font_smoothing="true", # 字体平滑开启就可以了 # enable_full_window_drag="true", # enable_desktop_composition="true", # enable_menu_animations="true", ) for i in self.scope['headers']: if i[0].decode('utf-8') == 'user-agent': self.user_agent = i[1].decode('utf-8') break for i in self.scope['headers']: if i[0].decode('utf-8') == 'x-real-ip': self.client = i[1].decode('utf-8') break if i[0].decode('utf-8') == 'x-forwarded-for': self.client = i[1].decode('utf-8').split(',')[0] break self.client = self.scope['client'][0] data = { 'name': self.channel_name, 'group': self.group, 'user': self.session.get('username'), 'host': self.remote_host.ip, 'username': self.remote_host.remote_user.username, 'protocol': self.remote_host.protocol, 'port': self.remote_host.port, 'type': _type, # 7 webrdp 8 webvnc 'address': self.client, 'useragent': self.user_agent, 'connect_info': '{0}_{1}_{2}_{3}'.format(self.width, self.height, self.dpi, self.guacamoleclient.guacamoleclient.id) } TerminalSession.objects.create(**data) t = threading.Thread(target=self.check_timeout) t.daemon = True t.start() # 给客户端发送组信息,用于web页面上传文件,需要在 guacamole/js/all.js 中自定义 group 的处理处理方法 self.send('5.group,10.group_name,{0}.{1};'.format( len(self.group), self.group))
def decrypt_passwd(passwd): return decrypt(passwd)
b = '37fbd0f8f39a462e39fef72852061f35' print(_de.decrypt(b)) a = 'WAF@ADmin#Sql$719' print(_de.encrypt(a)) # 使用django配置文件进行设置 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'devops.settings') # 让django初始化 import django django.setup() from util.crypto import encrypt, decrypt passwd = '1213' en = encrypt(passwd) print(en) print(decrypt(en)) x = 'gAAAAABduSzufr3De6SKUdjF44QSU8khLWO1V2n7et1if5pYjUsJ6hxn30sYlXEfiP-JWt5ADjtrx6vI_tE7ZNCwniBX0xWSjQ==' print(decrypt(x)) x = 'gAAAAABduSzujDu0XLd0sy1FvNgd2Ttf9id_YKTG4P2XySMxRM9CFk6qOiAKEnMY1PMByervIGUoDVcK1HuxYIOHYOWU7T115w==' print(decrypt(x)) hosts = { 'k8s1': '192.168.223.111', 'k8s2': '192.168.223.111', 'k8s3': '192.168.223.111', 'k8s4': '192.168.223.111', 'k8s5': '192.168.223.111', 'k8s6': '192.168.223.111', 'k8s7': '192.168.223.111',