Exemple #1
0
def host_executor(host, pkey, command):
    try:
        cli = SSH(host.hostname, host.port, host.username, pkey=pkey)
        exit_code, out = cli.exec_command(command)
        return exit_code == 0, out.decode()
    except Exception as e:
        return False, f'异常信息:{e}'
Exemple #2
0
def check_user_password(request):
    """
    判断远程登陆用户名和密码是否准确
    """
    if request.method == "POST":
        try:
            data = dict()
            post_data = json.loads(str(request.body, encoding='utf-8'))
            info = {
                "hostname": post_data["hostname"],
                "username": post_data["username"],
                "password": post_data["password"],
                "port": post_data["port"]
            }
            ssh = SSH(**info)
            ssh.get_client()

            data["status"] = "success"
            data['result'] = info
        except paramiko.ssh_exception.NoValidConnectionsError:
            data["status"] = "fail"
            data["result"] = u"端口未开放或路由不可达,请重试或关闭!"
        except paramiko.ssh_exception.AuthenticationException:
            data["status"] = "fail"
            data["result"] = u"用户名或密码不准确,请重试或关闭!"
        except socket.error as err:
            data["status"] = "fail"
            data["result"] = u"连接超时,请重试或关闭!"
        return json_response(data)
Exemple #3
0
def host_executor(q, host, pkey, command):
    exit_code, out, now = -1, None, time.time()
    try:
        cli = SSH(host.hostname, host.port, host.username, pkey=pkey)
        exit_code, out = cli.exec_command(command)
    finally:
        q.put((host.id, exit_code, round(time.time() - now, 3), out.decode() if out else None))
Exemple #4
0
def host_executor(host, pkey, command):
    try:
        cli = SSH(host.hostname, host.port, host.username, pkey=pkey)
        exit_code, out = cli.exec_command(command)
        if exit_code == 0:
            return True, out or '检测状态正常'
        else:
            return False, out or f'退出状态码:{exit_code}'
    except Exception as e:
        return False, f'异常信息:{e}'
Exemple #5
0
def valid_ssh(hostname,
              port,
              username,
              password=None,
              pkey=None,
              with_expect=True):
    try:
        private_key = AppSetting.get('private_key')
        public_key = AppSetting.get('public_key')
    except KeyError:
        private_key, public_key = SSH.generate_key()
        AppSetting.set('private_key', private_key, 'ssh private key')
        AppSetting.set('public_key', public_key, 'ssh public key')
    if password:
        _cli = SSH(hostname, port, username, password=str(password))
        _cli.add_public_key(public_key)
    if pkey:
        private_key = pkey
    try:
        cli = SSH(hostname, port, username, private_key)
        cli.ping()
    except BadAuthenticationType:
        if with_expect:
            raise TypeError('该主机不支持密钥认证,请参考官方文档,错误代码:E01')
        return False
    except AuthenticationException:
        if password and with_expect:
            raise ValueError('密钥认证失败,请参考官方文档,错误代码:E02')
        return False
    return True
Exemple #6
0
class Job:
    def __init__(self,
                 hostname,
                 port,
                 username,
                 pkey,
                 command,
                 token=None,
                 **kwargs):
        self.ssh_cli = SSH(hostname, port, username, pkey)
        self.key = f'{hostname}:{port}'
        self.command = command
        self.token = token
        self.rds_cli = None

    def _send(self, message, with_expire=False):
        if self.rds_cli is None:
            self.rds_cli = get_redis_connection()
        self.rds_cli.lpush(self.token, json.dumps(message))
        if with_expire:
            self.rds_cli.expire(self.token, 300)

    def send(self, data):
        message = {'key': self.key, 'type': 'info', 'data': data}
        self._send(message)

    def send_system(self, data):
        message = {'key': self.key, 'type': 'system', 'data': data}
        self._send(message)

    def send_error(self, data):
        message = {'key': self.key, 'type': 'error', 'data': data}
        self._send(message)

    def send_status(self, code):
        message = {'key': self.key, 'status': code}
        self._send(message, True)

    def run(self):
        if not self.token:
            return self.ssh_cli.exec_command(self.command)
        self.send_system('### Executing')
        code = -1
        try:
            for code, out in self.ssh_cli.exec_command_with_stream(
                    self.command):
                self.send(out)
        except socket.timeout:
            code = 130
            self.send_error('### Time out')
        except Exception as e:
            code = 131
            self.send_error(f'{e}')
        finally:
            self.send_status(code)
Exemple #7
0
def host_executor(q, host, pkey, command):
    exit_code, out, now = -1, None, time.time()
    try:
        cli = SSH(host.hostname, host.port, host.username, pkey=pkey)
        exit_code, out = cli.exec_command(command)
        out = out.decode() if out else None
    except AuthenticationException:
        out = 'ssh authentication fail'
    except socket.error as e:
        out = f'network error {e}'
    finally:
        q.put((host.id, exit_code, round(time.time() - now, 3), out))
Exemple #8
0
 def __init__(self,
              hostname,
              port,
              username,
              pkey,
              command,
              token=None,
              **kwargs):
     self.ssh_cli = SSH(hostname, port, username, pkey)
     self.key = f'{hostname}:{port}'
     self.command = command
     self.token = token
     self.rds_cli = None
Exemple #9
0
def valid_ssh(hostname, port, username, password, with_expect=True):
    try:
        private_key = AppSetting.get('private_key')  #定义私钥公钥
        public_key = AppSetting.get('public_key')
    except KeyError:  #错误检查
        private_key, public_key = SSH.generate_key()
        AppSetting.set('private_key', private_key, 'ssh private key')
        AppSetting.set('public_key', public_key, 'ssh public key')
    cli = SSH(hostname, port, username, private_key)
    if password:
        _cli = SSH(hostname, port, username, password=str(password))
        code, out = _cli.exec_command('mkdir -p -m 700 ~/.ssh && \
                echo %r >> ~/.ssh/authorized_keys && \
                chmod 600 ~/.ssh/authorized_keys' % public_key)
        if code != 0:
            raise Exception(f'add public key error: {out!r}')
    try:
        cli.ping()
    except BadAuthenticationType:
        if with_expect:
            raise TypeError('该主机不支持密钥认证,请参考官方文档,错误代码:E01')
        return False
    except AuthenticationException:
        if password and with_expect:
            raise ValueError('密钥认证失败,请参考官方文档,错误代码:E02')
        return False
    return True
Exemple #10
0
 def _init(self):
     self.send(bytes_data=b'Connecting ...\r\n')
     host = self.ssh_info_dict.get("ip")
     if not host:
         self.send(text_data='Unknown host\r\n')
         self.close()
     try:
         self.ssh = SSH(hostname=host,
                        username=self.ssh_info_dict["username"],
                        password=self.ssh_info_dict["password"],
                        port=self.ssh_info_dict["port"]).get_client()
     except Exception as e:
         self.send(bytes_data=f'Exception: {e}\r\n'.encode())
         self.close()
     self.chan = self.ssh.invoke_shell(term='xterm')
     self.chan.transport.set_keepalive(30)
     Thread(target=self.loop_read).start()
Exemple #11
0
 def get_ssh_key(cls):
     public_key = cls.get_default('public_key')
     private_key = cls.get_default('private_key')
     if not private_key or not public_key:
         private_key, public_key = SSH.generate_key()
         cls.set('private_key', private_key)
         cls.set('public_key', public_key)
     return private_key, public_key
Exemple #12
0
    def post(self, request):
        form, error = JsonParser(
            Argument('id', type=int, required=False),
            Argument('group_ids', type=list, filter=lambda x: len(x), help='请选择主机分组'),
            Argument('name', help='请输主机名称'),
            Argument('username', handler=str.strip, help='请输入登录用户名'),
            Argument('hostname', handler=str.strip, help='请输入主机名或IP'),
            Argument('port', type=int, help='请输入SSH端口'),
            Argument('pkey', required=False),
            Argument('desc', required=False),
            Argument('password', required=False),
        ).parse(request.body)
        if error is None:
            password = form.pop('password')
            private_key, public_key = AppSetting.get_ssh_key()
            try:
                if form.pkey:
                    private_key = form.pkey
                elif password:
                    with SSH(form.hostname, form.port, form.username, password=password) as ssh:
                        ssh.add_public_key(public_key)

                with SSH(form.hostname, form.port, form.username, private_key) as ssh:
                    ssh.ping()
            except BadAuthenticationType:
                return json_response(error='该主机不支持密钥认证,请参考官方文档,错误代码:E01')
            except AuthenticationException:
                if password:
                    return json_response(error='密钥认证失败,请参考官方文档,错误代码:E02')
                return json_response('auth fail')

            group_ids = form.pop('group_ids')
            other = Host.objects.filter(name=form.name).first()
            if other and (not form.id or other.id != form.id):
                return json_response(error=f'已存在的主机名称【{form.name}】')
            if form.id:
                Host.objects.filter(pk=form.id).update(is_verified=True, **form)
                host = Host.objects.get(pk=form.id)
            else:
                host = Host.objects.create(created_by=request.user, is_verified=True, **form)
                _sync_host_extend(host, ssh=ssh)
            host.groups.set(group_ids)
            response = host.to_view()
            response['group_ids'] = group_ids
            return json_response(response)
        return json_response(error=error)
Exemple #13
0
 def __init__(self,
              key,
              name,
              hostname,
              port,
              username,
              pkey,
              command,
              interpreter,
              token=None):
     self.ssh = SSH(hostname, port, username, pkey)
     self.key = key
     self.command = self._handle_command(command, interpreter)
     self.token = token
     self.rds_cli = None
     self.env = dict(SPUG_HOST_ID=str(self.key),
                     SPUG_HOST_NAME=name,
                     SPUG_HOST_HOSTNAME=hostname,
                     SPUG_SSH_PORT=str(port),
                     SPUG_SSH_USERNAME=username,
                     SPUG_INTERPRETER=interpreter)
Exemple #14
0
def _get_ssh(kwargs, pkey=None, private_key=None, public_key=None, password=None):
    try:
        ssh = SSH(pkey=pkey or private_key, **kwargs)
        ssh.get_client()
        return ssh
    except AuthenticationException as e:
        if password:
            with SSH(password=str(password), **kwargs) as ssh:
                ssh.add_public_key(public_key)
            return _get_ssh(kwargs, private_key)
        raise e
Exemple #15
0
def valid_ssh(hostname, port, username, password):
    try:
        private_key = AppSetting.get('private_key')
        public_key = AppSetting.get('public_key')
    except KeyError:
        private_key, public_key = SSH.generate_key()
        AppSetting.set('private_key', private_key, 'ssh private key')
        AppSetting.set('public_key', public_key, 'ssh public key')
    if password:
        cli = SSH(hostname, port, username, password=str(password))
        code, out = cli.exec_command('mkdir -p -m 700 ~/.ssh && \
                echo %r >> ~/.ssh/authorized_keys && \
                chmod 600 ~/.ssh/authorized_keys' % public_key)
        if code != 0:
            raise Exception(f'add public key error: {out!r}')
    else:
        cli = SSH(hostname, port, username, private_key)

    try:
        cli.ping()
    except AuthenticationException:
        return False
    return True
Exemple #16
0
class SSHConsumer(WebsocketConsumer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        kwargs = self.scope['url_route']['kwargs']
        ssh_infos = kwargs['id']
        ssh_infos = aes_decode(conf_data['AES_KEY'], ssh_infos)
        ssh_infos = ssh_infos.split("&")
        self.ssh_info_dict = dict()

        for i in ssh_infos:
            i = i.split("=")
            self.ssh_info_dict[i[0]] = i[1]

        self.chan = None
        self.ssh = None

    def loop_read(self):
        while True:
            data = self.chan.recv(32 * 1024)
            if not data:
                self.close(3333)
                break
            self.send(bytes_data=data)

    def receive(self, text_data=None, bytes_data=None):
        data = text_data or bytes_data
        if data:
            data = json.loads(data)
            print("receive:", data)
            resize = data.get('resize')
            if resize and len(resize) == 2:
                self.chan.resize_pty(*resize)
            else:
                print("send:", data['data'])
                self.chan.send(data['data'])

    def disconnect(self, code):
        self.chan.close()
        self.ssh.close()

    def connect(self):
        self.accept()
        self._init()

    def _init(self):
        self.send(bytes_data=b'Connecting ...\r\n')
        host = self.ssh_info_dict.get("ip")
        if not host:
            self.send(text_data='Unknown host\r\n')
            self.close()
        try:
            self.ssh = SSH(hostname=host,
                           username=self.ssh_info_dict["username"],
                           password=self.ssh_info_dict["password"],
                           port=self.ssh_info_dict["port"]).get_client()
        except Exception as e:
            self.send(bytes_data=f'Exception: {e}\r\n'.encode())
            self.close()
        self.chan = self.ssh.invoke_shell(term='xterm')
        self.chan.transport.set_keepalive(30)
        Thread(target=self.loop_read).start()
Exemple #17
0
class Job:
    def __init__(self,
                 key,
                 name,
                 hostname,
                 port,
                 username,
                 pkey,
                 command,
                 interpreter,
                 token=None):
        self.ssh = SSH(hostname, port, username, pkey)
        self.key = key
        self.command = self._handle_command(command, interpreter)
        self.token = token
        self.rds_cli = None
        self.env = dict(SPUG_HOST_ID=str(self.key),
                        SPUG_HOST_NAME=name,
                        SPUG_HOST_HOSTNAME=hostname,
                        SPUG_SSH_PORT=str(port),
                        SPUG_SSH_USERNAME=username,
                        SPUG_INTERPRETER=interpreter)

    def _send(self, message, with_expire=False):
        if self.rds_cli is None:
            self.rds_cli = get_redis_connection()
        self.rds_cli.lpush(self.token, json.dumps(message))
        if with_expire:
            self.rds_cli.expire(self.token, 300)

    def _handle_command(self, command, interpreter):
        if interpreter == 'python':
            attach = 'INTERPRETER=python\ncommand -v python3 &> /dev/null && INTERPRETER=python3'
            return f'{attach}\n$INTERPRETER << EOF\n# -*- coding: UTF-8 -*-\n{command}\nEOF'
        return command

    def send(self, data):
        message = {'key': self.key, 'data': data}
        self._send(message)

    def send_status(self, code):
        message = {'key': self.key, 'status': code}
        self._send(message, True)

    def run(self):
        if not self.token:
            with self.ssh:
                return self.ssh.exec_command(self.command, self.env)
        self.send('\r\n\x1b[36m### Executing ...\x1b[0m\r\n')
        code = -1
        try:
            with self.ssh:
                for code, out in self.ssh.exec_command_with_stream(
                        self.command, self.env):
                    self.send(out)
        except socket.timeout:
            code = 130
            self.send('\r\n\x1b[31m### Time out\x1b[0m')
        except Exception as e:
            code = 131
            self.send(f'\r\n\x1b[31m### Exception {e}\x1b[0m')
            raise e
        finally:
            self.send_status(code)
Exemple #18
0
 def get_ssh(self, pkey=None, default_env=None):
     pkey = pkey or self.private_key
     return SSH(self.hostname, self.port, self.username, pkey, default_env=default_env)
Exemple #19
0
 def get_ssh(self, pkey=None):
     pkey = pkey or AppSetting.get('private_key')
     return SSH(self.hostname, self.port, self.username, pkey)