Использование Paramiko SSH и SFTP

Python

[TOC]

1 Обзор

Я не хотел писать Paramiko, так как думал, что предыдущая статья о модуле Netmiko больше подходит для пользователей сети.Позже я обнаружил, что paramiko включает в себя функцию SFTP, поэтому необходимо рассказать об этом.Ведь нам нужно для загрузки конфигурации и частой загрузки на устройство.Используется версия/версия обновления, и SFTP более безопасен, чем FTP и TFTP.

Таким образом, у вас нет помощи других инструментов для загрузки, загрузки через универсальный «Python», чтобы заключить сделку.

И SSH, и SFTP используют один и тот же номер порта — 22. Если вы придаете большее значение безопасности передачи данных, SFTP является первым выбором вместо FTP и TFTP.

Описание экспериментальной среды:

  • Маршрутизатор Cisco для входа по SSH;
  • Коммутатор Huawei для загрузки/выгрузки по SFTP;
  • PyCharm Pro

2. Основное использование Paramiko

2.1 Введение в ключевые параметры SSHClient

функция подключения():

использовать:Используется для подключения к удаленному хосту, где «имя хоста» является обязательным параметром.

常用参数
hostname    //远端主机,填写IP和域名都可以
port=SSH_PORT    //缺省为22端口
username=None    //用于登陆远端主机使用的用户名
password=None    //用于登陆远端主机使用的密码
pkey=None    //使用私钥用于身份认证,也叫'免密'登陆
key_filename=None    //使用私钥文件名
timeout=None    //tcp连接超时时间
allow_agent=True    //缺省允许连接到ssh代理
look_for_keys=True    //缺省在~/.ssh中搜索私钥文件,默认为True 允许
compress=False    //缺省没有开启压缩

loadsystemФункция host_keys():

использовать:Чтобы загрузить ключ хоста, сохраните ключ в файле known_hosts.

filename=None    //缺省会加载"~/.ssh/known_hosts"文件

setmissinghostkeyФункция политики ():

использовать:Используется для проверки того, есть ли на удаленном хосте запись в локальных «ключах хоста» и какую стратегию использовать.

#目前支持的三种策略: 
1.AutoAddPolicy        //自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
2.WarningPolicy        //用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
3.RejectPolicy        //自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项

функция exec_command():

использовать:Используется для выполнения команд на удаленном хосте и возврата информации о вводе, выводе и ошибках.

command    //执行的命令
stdin, stdout, stderr    //分别表示输入、输出、错误

2.2 Общие примеры SSHCLENT

2.2.1 Путем ввода имени пользователя и пароля:

import paramiko

def ssh_client():
    # 创建一个实例化
    ssh = paramiko.SSHClient()
    # 加载系统HostKeys密钥
    ssh.load_system_host_keys()
    # 自动添加策略,保存远端主机的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    #连接远端主机
    ssh.connect('192.168.0.101',port=22, username='admin', password='Admin@123')
    #执行命令
    stdin, stdout,stderr = ssh.exec_command('show ip int br')
    print(stdout.read().decode('utf-8'))
    #关闭连接
    ssh.close()

if __name__ == '__main__':
    ssh_client()

Результат выполнения кода следующий:

2.2.2 Вход по логину и паролю (транспортный режим)

def ssh_client():
    # 创建一个实例化
    ssh = paramiko.SSHClient()
    #transport封装
    t = paramiko.Transport('192.168.0.101', 22)
    t.connect(username='admin', password='Admin@123')
    ssh._transport = t

    # 加载系统HostKeys密钥
    ssh.load_system_host_keys()
    # 自动添加策略,保存远端主机的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    #执行命令
    stdin, stdout,stderr = ssh.exec_command('show ip int br')
    print(stdout.read().decode('utf-8'))
    #关闭连接
    ssh.close()

if __name__ == '__main__':
    ssh_client()

Результат выполнения кода следующий:

Результат такой же, как и выше, и выход такой же.

2.2.3 Вход по имени пользователя и ключу

Cisco Router Configuration Configuration:

username admin privilege 15 password Admin@123
ip domain name cisco.com
crypto key generate rsa modulus 1024
ip ssh version 2
ip ssh pubkey-chain
  username admin
   key-hash ssh-rsa 560DE41351E40FF6C237F9BBFF4238AC singvis@DESKTOP-IQ964AEendend
line vty 0 4
 exec-timeout 5 0
 logging synchronous
 login local
 transport input ssh
 privilege level 15

Код Python:

import paramiko

def ssh_client():
    #私钥的绝对路径
    private = paramiko.RSAKey.from_private_key_file(r'C:\Users\singvis\Documents\Identity')

    # 创建一个实例化
    ssh = paramiko.SSHClient()
    # 加载系统HostKeys密钥
    ssh.load_system_host_keys()
    # 自动添加策略,保存远端主机的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    #连接远端主机,此处不需要密码,为私钥文件
    ssh.connect('192.168.0.101',port=22, username='admin', pkey=private)
    #执行命令
    stdin, stdout,stderr = ssh.exec_command('show ip int br')
    print(stdout.read().decode('utf-8'))
    ssh.close()

if __name__ == '__main__':
    ssh_client()

Используйте SecurityCRT для входа в 192.168.0.101 по ключу, без ввода пароля, вход напрямую:

Описание: Путь генерации ключа: инструменты->создать открытый ключ (на этот раз через SecurityCRT)

2.3 Введение в ключевые параметры SFTPClient

Как клиентский объект sftp, SFTPCLient реализует удаленные файловые операции, такие как загрузка, загрузка, разрешения и статус, в соответствии с сеансом sftp протокола передачи ssh.

from_transport(cls,t)    //创建一个已连通的SFTP客户端通道
put(localpath, remotepath, callback=None, confirm=True)    //将本地文件上传到远端主机
get(remotepath, localpath, callback=None)    //从远端主机下载文件到本地
mkdir()        //创建目录
remove()    //删除目录
rename()    //重命名目录
stat()        //查看文件状态
listdir()    //列出目录下的文件

2.4 Общие примеры SFTPClient

На примере коммутатора Huawei конфигурация коммутатора выглядит следующим образом:

rsa local-key-pair create
#
stelnet server enable
sftp server enable
#
aaa
 local-user admin password simple Admin@123
 local-user admin privilege level 15
 local-user admin service-type terminal ssh
 #
ssh authentication-type default password
ssh user admin authentication-type password
ssh user admin service-type all
ssh user admin sftp-directory flash:/
#
user-interface vty 0 4
 authentication-mode aaa
 protocol inbound ssh

Код Python выглядит следующим образом:

import paramiko

def sftp_put():
    #文件路径
    local_file =r'D:\test\123.txt'
    remote_file ='flash:/123.txt'

    t = paramiko.Transport('192.168.0.200', 22)
    t.connect(username='admin', password='Admin@123')

    sftp = paramiko.SFTPClient.from_transport(t)
    sftp.put(local_file,remote_file)
    t.close()

def sftp_get():
    local_path = r'D:\test\vrpcfg.zip'
    remote_path = 'flash:/vrpcfg.zip'

    t = paramiko.Transport('192.168.0.200', 22)
    t.connect(username='admin', password='Admin@123')
    #
    sftp = paramiko.SFTPClient.from_transport(t)
    sftp.get(remote_path, local_path)
    t.close()

if __name__ == '__main__':
    sftp_put()
    sftp_get()

Результат выполнения кода следующий:

3. Полный код

#!/usr/bin/env python
#coding:utf-8
#欢迎关注微信公众号:点滴技术
#这里有靠谱的、有价值的、共成长的,专属于网络攻城狮

import paramiko, time
from paramiko.ssh_exception import NoValidConnectionsError,AuthenticationException

def ssh_client(host, user, pwd, cmds, verbose=True):
    # 私钥文件的存放路径
    # private = paramiko.RSAKey.from_private_key_file(r'C:\Users\singvis\Documents\Identity')
    # 创建一个实例化
    ssh = paramiko.SSHClient()
    # 加载系统SSH密钥
    ssh.load_system_host_keys()
    # 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不在本地knows_hosts文件中记录的主机将无法连接,默认拒接
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 连接设备
    try:
        ssh.connect(hostname=host,
                    username=user,
                    timeout=5,
                    compress=True,
                    password=pwd
                    #pkey=private,    #可以采用密钥连接
                    )

        print("正在连接主机{}.....".format(host))
    except NoValidConnectionsError:
        print('连接出现了问题')
    except AuthenticationException:
        print('用户名或密码错误')
    except Exception as e:
        print('其他错误问题{}'.format(e))
    finally:
        #激活交互式shell
        chan = ssh.invoke_shell()
        time.sleep(1)

        for cmd in cmds:
            chan.send(cmd.encode())
            #一定要有回车'Enter'这个动作
            chan.send(b'\n')
            time.sleep(2)
            r = chan.recv(40960).decode()
            if verbose:
                print(r)
        chan.close()
        ssh.close()

def sftp_get(ip, user, pwd, local_file,remote_file, port=22):
    try:
        t = paramiko.Transport(ip, port)
        t.connect(username=user, password=pwd)
        sftp = paramiko.SFTPClient.from_transport(t)
        sftp.get(remote_file, local_file)
        t.close()

    except Exception as e:
        print(e)


def sftp_put(ip, user, pwd, local_file, remote_file, port=22):
    try:
        t = paramiko.Transport(ip, port)
        t.connect(username=user, password=pwd)
        sftp = paramiko.SFTPClient.from_transport(t)
        sftp.put(local_file, remote_file)
        t.close()

    except Exception as e:
        print(e)


if __name__ == '__main__':
    '''
    不要运行的,请注释掉,前面加'#'符号
    '''
    ip = '192.168.0.101'
    user= 'admin'
    pwd= 'Admin@123'
    # local_file = r'D:\test\123.txt'
    # remote_file = 'flash:/vrpcfg.zip'
    # sftp_get(ip='192.168.0.200', user=user, pwd=pwd, remote_file=remote_file, local_file=r'D:\test\vrpcfg.zip')
    # sftp_put(ip='192.168.0.200', user=user, pwd=pwd, local_file=local_file, remote_file='flash:/123.txt')

    cmds = ['terminal length 0', 'show version', 'show ip int br','show ip route']
    # cmds = ['disp ip int br','disp device','disp clock']
    ssh_client(ip, user, pwd, cmds)

Справочная информация:

Конфигурация SSH маршрутизатора и коммутатора Cisco

Если вам нравятся мои статьи, обратите внимание на мой официальный аккаунт: капельная технология, сканируйте код, чтобы следовать, и время от времени делитесь

点滴技术