zoukankan      html  css  js  c++  java
  • python下ssh的简单实现

    python下的ssh都需要借助第三方模块paramiko来实现,在使用前需要手动安装。

    一、python实现ssh

    (1) linux下的ssh登录

    root@ubuntu:~# ssh morra@192.168.1.42
    The authenticity of host '192.168.1.42 (192.168.1.42)' can't be established.
    ECDSA key fingerprint is SHA256:/ufx+/OLtdsYy7vsdk4KDu9xJsBp6zHonRAf2jjT0GI.
    Are you sure you want to continue connecting (yes/no)? y
    Please type 'yes' or 'no': yes
    Warning: Permanently added '192.168.1.42' (ECDSA) to the list of known hosts.
    Password:
    Last login: Fri Dec  2 14:15:36 2016
    localhost:~ morra$ 
    

    查看known_hosts文件

    root@ubuntu:~# cat .ssh/known_hosts 
    |1|ohKgSMq+1NLbr37anPqNZKQxh/8=|83NZfZYMUwLGaH32oLhCW/2PsXk= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMTpJEzRyK6Bn96JT9+8IMK57ouWZspbs+oVuc7lD+aAwDB6C9Qgoy8P7cGjRaOA5ImDiBTLSQgHT+cZeGIJbI4=
    

    (2) python实现ssh

    import paramiko
    
    #创建SSH对象
    ssh = paramiko.SSHClient()
    
    #把要连接的机器添加到known_hosts文件中
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    #连接服务器
    ssh.connect(hostname='192.168.1.96', port=22, username='morra', password='123456')
    
    cmd = 'ps'
    #cmd = 'ls -l;ifconfig'       #多个命令用;隔开
    stdin, stdout, stderr = ssh.exec_command(cmd)
    
    result = stdout.read()
    
    if not result:
        result = stderr.read()
    ssh.close()
    
    print(result.decode())
    

    (3) python实现sftp

    import paramiko
    
    transport = paramiko.Transport(('192.168.1.96', 22))
    
    transport.connect(username='morra', password='357447218')
    
    sftp = paramiko.SFTPClient.from_transport(transport)
    
    sftp.put('123.py', '/tmp/test.py')  # 将123.py 上传至服务器 /tmp下并改名为test.py
    
    sftp.get('remove_path', 'local_path')  # 将remove_path 下载到本地 local_path
    
    transport.close()
    

    二、传统的免密登录

    (1) 生成公钥

    使用ssh-keygen生产公钥和私钥

    morra@ubuntu:~$ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/morra/.ssh/id_rsa): 
    Created directory '/home/morra/.ssh'.
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /home/morra/.ssh/id_rsa.
    Your public key has been saved in /home/morra/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:8IVM56bc/2deLZcDXwVs2XDNCuTTbvvlCKmCnUxiHuw morra@ubuntu
    The key's randomart image is:
    +---[RSA 2048]----+
    |        . ....o=o|
    |       o + ...+o+|
    |      . o + oo...|
    |       + =   o. .|
    |     .  S .  .o .|
    |      = .  . oo.+|
    |     + B .  + o+=|
    |      E =  . o **|
    |         ..   o++|
    +----[SHA256]-----+
    
    
    #生成的公钥私钥存放在.ssh目录下,id_rsa.pub就是本机的公钥
    morra@ubuntu:~$ cd .ssh/
    morra@ubuntu:~/.ssh$ ls
    id_rsa  id_rsa.pub
    

    (2) 复制公钥

    最后把本机的id_rsa.pub文件中的内容copy到目标机的.ssh/authorized_keys中就可以了,如果没有authorized_keys,自己创建。但是要注意authorized_keys的权限一般是600

    localhost:.ssh morra$ ls -l authorized_keys 
    -rw-r--r--  1 morra  staff  393 Dec  6 16:33 authorized_keys
    

    或者直接使用一条命令也可以实现公钥的复制,ssh-copy-id后面接入的用户就是要支持免密登录的用户。

    morra@ubuntu:~/.ssh$ ssh-copy-id "morra@192.168.1.42"
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/morra/.ssh/id_rsa.pub"
    The authenticity of host '192.168.1.42 (192.168.1.42)' can't be established.
    ECDSA key fingerprint is SHA256:/ufx+/OLtdsYy7vsdk4KDu9xJsBp6zHonRAf2jjT0GI.
    Are you sure you want to continue connecting (yes/no)? n^H
    Please type 'yes' or 'no': yes
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    Password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'morra@192.168.1.42'"   and check to make sure that only the key(s) you wanted were added.
    
    
    #去目标机器下,检查authorized_keys文件
    localhost:.ssh morra$ cat authorized_keys 
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDB/mkvSx1mo/l/huMiOSqQjTb3KSB+D67qDRe1VgbjeZpwtodpSNueqGMj3mGDtf8tfmfwygKHuMtkVCQuD+1trLZ/yn8dKK9JV2pM4iwmaEvSda/qbQR7lQ37lsmvGnwCloJ49h8MpsF9UsDVXnyo4kauOj+0HYlur1E5Y7dzBuuzBiKAnwS66ZVTtHpIzubfXYanyBEinClpHNr6B7DVWp0J4ubZ8k/AgFMyD8NyJmugoObD3+wry0Dk2LG/WadOaY1luooQN4m55WyfZE2w0Kzi4F7W6v8/GRnpxVKOmNUNk6/c6hr/CDWnthS1abMjI9u/bGru6X2kiyymq3wR morra@ubuntu
    

    (3) 登录测试

    morra@ubuntu:~/.ssh$ ssh 'morra@192.168.1.42'
    Last login: Tue Dec  6 16:28:07 2016 from 192.168.1.69
    localhost:~ morra$ 
    

    登录方式注意区别

    $ ssh morra@192.168.1.42    #用户名密码登录
    $ ssh 'morra@192.168.1.42'  #公钥免密登录
    

    三、用pythonssh免密实现

    (1) 免密ssh

    import paramiko
    
    private_key = paramiko.RSAKey.from_private_key_file('id_rsa96')   #使用目标的私钥来登录
    
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    ssh.connect(hostname='192.168.1.96',port=22,username='morra',pkey=private_key)
    
    cmd = 'ps'
    stdin, stdout, stderr = ssh.exec_command(cmd)
    
    result = stdout.read()
    
    if not result:
        result = stderr.read()
    ssh.close()
    
    print(result.decode())
    

    (2) 免密sftp

    import paramiko
     
    private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
     
    transport = paramiko.Transport(('hostname', 22))
    transport.connect(username='wupeiqi', pkey=private_key )
     
    sftp = paramiko.SFTPClient.from_transport(transport)
    
    sftp.put('/tmp/location.py', '/tmp/test.py')    
    # 将location.py 上传至服务器 /tmp/test.py
    sftp.get('remove_path', 'local_path')        
    # 将remove_path 下载到本地 local_path
     
    transport.close()
    

    四、练手Demo

    import paramiko
    import uuid
    
    class Haproxy(object):
    
        def __init__(self):
            self.host = '192.168.1.96'
            self.port = 22
            self.username = 'morra'
            self.pwd = '123456'
            self.__k = None
    
        def create_file(self):
            file_name = str(uuid.uuid4())
            with open(file_name,'w') as f:
                f.write('sb')
            return file_name
    
        def run(self):
            self.connect()
            self.upload()
            self.rename()
            self.close()
    
        def connect(self):
            transport = paramiko.Transport((self.host,self.port))
            transport.connect(username=self.username,password=self.pwd)
            self.__transport = transport
    
        def close(self):
    
            self.__transport.close()
    
        def upload(self):
            # 连接,上传
            file_name = self.create_file()
    
            sftp = paramiko.SFTPClient.from_transport(self.__transport)
            sftp.put(file_name, '/home/test.py')    # 将location.py 上传至服务器 /tmp/test.pydef rename(self):
    
            ssh = paramiko.SSHClient()
            ssh._transport = self.__transport # 执行命令
            stdin, stdout, stderr = ssh.exec_command('mv /home/test.py /home/test2.py') 
            result = stdout.read()
    
    
    ha = Haproxy()
    ha.run()
    
  • 相关阅读:
    阿里消息队列中间件 RocketMQ 源码分析 —— Message 拉取与消费(上)
    数据库中间件 ShardingJDBC 源码分析 —— SQL 解析(三)之查询SQL
    数据库分库分表中间件 ShardingJDBC 源码分析 —— SQL 解析(六)之删除SQL
    数据库分库分表中间件 ShardingJDBC 源码分析 —— SQL 解析(五)之更新SQL
    消息队列中间件 RocketMQ 源码分析 —— Message 存储
    源码圈 300 胖友的书单整理
    数据库分库分表中间件 ShardingJDBC 源码分析 —— SQL 路由(一)分库分表配置
    数据库分库分表中间件 ShardingJDBC 源码分析 —— SQL 解析(四)之插入SQL
    数据库分库分表中间件 ShardingJDBC 源码分析 —— SQL 路由(二)之分库分表路由
    C#中Math类的用法
  • 原文地址:https://www.cnblogs.com/whatisfantasy/p/6138663.html
Copyright © 2011-2022 走看看