python使用paramiko实现ssh

代码

myssh.py

import utils
import paramiko
class SSHConnection(object):
    def __init__(self, host, port=22, proxy_name="proxy"):
        self._host = host
        self._port = int(port)
        self._tunnel_server, self._host, self._port, self._username, self._passwords \
            = utils.get_common_ssh_tunnel(proxy_name, self._host, self._port)
        self._password = None
        self._transport = None
        self._sftp = None
        self._client = None
        self._connect()  # 建立连接

    def _connect(self):
        if self._tunnel_server:
            self._tunnel_server.start()

        passwords = self._passwords.split("\n")
        success = False
        transport = None
        for password in passwords:
            try:
                transport = paramiko.Transport((self._host, self._port))
                transport.connect(username=self._username, password=password)
                self._password = password
                success = True
            except Exception as e:
                if transport:
                    transport.close()
                if "Authentication failed." in e:
                    continue
        if success:
            self._transport = transport
        else:
            raise paramiko.AuthenticationException

    # 下载
    def download(self, remotepath, localpath):
        try:
            if self._sftp is None:
                self._sftp = paramiko.SFTPClient.from_transport(self._transport)
            self._sftp.get(remotepath, localpath)
        except Exception as e:
            raise e

    # 上传
    def put(self, localpath, remotepath):
        try:
            if self._sftp is None:
                self._sftp = paramiko.SFTPClient.from_transport(self._transport)
            self._sftp.put(localpath, remotepath)
        except Exception as e:
            raise e

    # 执行命令
    def exec_command(self, command):
        try:
            if self._client is None:
                self._client = paramiko.SSHClient()
                self._client._transport = self._transport
            stdin, stdout, stderr = self._client.exec_command(command)
            data = stdout.read()
            if len(data) > 0:
                print data.strip()  # 打印正确结果
                return data
            err = stderr.read()
            if len(err) > 0:
                print err.strip()  # 输出错误结果
                return err
        except Exception as e:
            raise e

    def close(self):
        if self._transport:
            self._transport.close()
        if self._client:
            self._client.close()
        if self._tunnel_server:
            self._tunnel_server.close()

utils.py

def get_common_ssh_tunnel(proxy_server, remote_host, remote_port):
    session = models.get_db_session()
    remote_server = None
    try:
        remote_server = session.query(models.Server).filter(models.Server.host == remote_host).one()
    except Exception as e:
        if "No row was found for one()" in e.message:
            remote_server = session.query(models.Server).filter(models.Server.name == "common").one()
            remote_server.host = remote_host
            remote_server.port = remote_port
    if not remote_server.need_jump:
        return None, remote_server.host, remote_server.port, remote_server
    local_port = utils.get_open_port()
    proxy = session.query(models.Server).filter(models.Server.name == proxy_server).one()
    session.close()
    return SSHTunnelForwarder(
        (proxy.host, int(proxy.port)),
        ssh_username=proxy.username,
        ssh_password=proxy.password,
        remote_bind_address=(remote_host, int(remote_port)),
        local_bind_address=("0.0.0.0", int(local_port))
    ), "127.0.0.1", local_port, remote_server.username, remote_server.password

参考

https://blog.csdn.net/u012322855/article/details/77839929

    原文作者:多余的午宴
    原文地址: https://www.jianshu.com/p/908b4f818a2d
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞