「Python 网络自动化」Paramiko 使用证书免密连接 H3C 网络设备

917 阅读4分钟

在一般的网络运维场景中,由于网络设备的黑盒特殊性,我们都是使用账号密码来进行登录设备进行运维。 其实网络设备也是支持像 Linux 系统一样,配置证书进行免密验证登录。

以下为配置方法,使用的是华三官方 HCL 模拟器,仅供参考~

设备侧配置

  1. 设备配置用户

    #
    local-user admin class manage
     password simple admin
     service-type ftp
     service-type ssh
     authorization-attribute user-role network-admin
    #
    
  2. 配置登录 vty 登录权限

    #
    line vty 0 63
     authentication-mode scheme
    #
    
  3. 开启 ssh 服务

    ssh erver enable
    
  4. 开启 ftp 服务,用来向网络设备传输密钥,当然其他方式也是可以的,目的达到即可。

    ftp server enable
    

密钥传输及配置

  1. 在 windows 上生成 ssh key

    PS C:\Users\xdai> ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (C:\Users\xdai/.ssh/id_rsa):
    C:\Users\xdai/.ssh/id_rsa already exists.
    Overwrite (y/n)? y
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in C:\Users\xdai/.ssh/id_rsa.
    Your public key has been saved in C:\Users\xdai/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:Dfia7aLwhuSowN7iSsXlqkB0/ZJw2mMoMVi9Y4ez06E xdai@xdai
    The key's randomart image is:
    +---[RSA 2048]----+
    |  ..             |
    |..  o  .         |
    |.+ o *. .        |
    |. = # =. o       |
    | o * # oS .      |
    |o + E ++         |
    |o*.o .o .        |
    |*.=o. ..         |
    |*+.oo. ..        |
    +----[SHA256]-----+
    PS C:\Users\xdai>
    
  2. 在 windows 上将公钥通过 ftp 上传到设备

    C:\Users\xdai\.ssh>ftp 192.168.56.20
    连接到 192.168.56.20220 FTP service ready.
    502 Command not implemented.
    用户(192.168.56.20:(none)): admin
    331 Password required for admin.
    密码:
    230 User logged in.
    ftp> put id_rsa.pub
    200 PORT command successful
    150 Connecting to port 11865
    226 File successfully transferred
    ftp: 发送 392 字节,用时 0.00392.00千字节/秒。
    ftp> quit
    221-Goodbye. You uploaded 1 and downloaded 0 kbytes.
    221 Logout.
    

可以在 R1 上看到已经接收到了公钥

<R1>%Dec 26 15:05:41:190 2020 R1 FTP/6/AUTH: User N/A@192.168.56.102 for connection.
%Dec 26 15:05:44:437 2020 R1 FTP/6/AUTH: User admin@192.168.56.102 login.
%Dec 26 15:05:53:983 2020 R1 FTP/5/OPER: User admin@192.168.56.102 uploaded flash:/id_rsa.pub.
%Dec 26 15:06:17:204 2020 R1 FTP/6/LOGOUT: User admin@192.168.56.102 logout.
<R1>dir
Directory of flash:
   0 drw-           - Dec 26 2020 14:56:17   diagfile
   1 -rw-         735 Dec 26 2020 14:57:27   hostkey
   2 -rw-         391 Dec 26 2020 15:05:53   id_rsa.pub

在 R1 上导入远端主机公钥

public-key peer netdevops import sshkey flash:/id_rsa.pub

查看已经导入的公钥

[R1] display public-key peer

=============================================
Key name: netdevops
Key type: RSA
Key modulus: 2048
Key code:
......

配置远端主机公钥的方式有两种:

  • 从公钥文件中导入:用户事先将远端主机的公钥文件保存到本地设备(例如,通过FTP或TFTP,以二进制方式将远端主机的公钥文件保存到本地设备),本地设备从该公钥文件中导入远端主机的公钥。导入公钥时,系统会自动将远端主机的公钥文件转换为PKCS(Public Key Cryptography Standards,公共密钥加密标准)编码形式。

  • 手工配置:用户事先在远端主机上查看其公钥信息,并记录远端主机公钥的内容。在本地设备上采用手工输入的方式将远端主机的公钥配置到本地。手工输入远端主机公钥时,可以逐个字符输入,也可以一次拷贝粘贴多个字符。

因为当前版本设备不支持直接输入 rsa 公钥,所以采用导入文件的方式。

R1 上为 ssh 用户配置公钥验证方式,指定公钥

ssh user admin service-type all authentication-type any assign publickey netdevops

authentication-type 可选项有 any、password、password-publickey、publickey

设备配置已经完成。

代码实现

在 windows 中编代码,代码中没有配置网络设备的登录密码,也能成功执行命令。

import paramiko


ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
ssh.connect(
    hostname='192.168.56.20',
    username='admin',
)
stdin, stdout,  stderr = ssh.exec_command('dis ip int brief')
interface = stdout.read().decode(encoding='utf-8')
print(interface)
ssh.close()

可以看到输出:

PS C:\python\netdevops> & "C:/Program Files (x86)/Python38-32/python.exe" c:/python/netdevops/1.py

******************************************************************************
* Copyright (c) 2004-2017 New H3C Technologies Co., Ltd. All rights reserved.*
* Without the owner's prior written consent,                                 *
* no decompiling or reverse-engineering shall be allowed.                    *
******************************************************************************

<R1>dis ip int brief
*down: administratively down
(s): spoofing  (l): loopback
Interface                Physical Protocol IP Address      Description
GE0/0                    up       up       192.168.56.20   --
GE0/1                    down     down     --              --
GE0/2                    down     down     --              --
GE5/0                    down     down     --              --
GE5/1                    down     down     --              --
GE6/0                    down     down     --              --
GE6/1                    down     down     --              --
Ser1/0                   down     down     --              --
Ser2/0                   down     down     --              --
Ser3/0                   down     down     --              --
Ser4/0                   down     down     --              --

PS C:\python\netdevops>

设备上查看 console log

<R1>
<R1>%Dec 26 16:50:50:033 2020 R1 SHELL/5/SHELL_LOGIN: Console logged in from con0.
%Dec 26 16:50:54:285 2020 R1 SSHS/6/SSHS_LOG: Accepted publickey for admin from 192.168.56.102 port 1313.

%Dec 26 16:50:56:061 2020 R1 SSHS/6/SSHS_LOG: User admin logged out from 192.168.56.102 port 1313.
%Dec 26 16:50:56:061 2020 R1 SSHS/6/SSHS_DISCONNECT: SSH user admin (IP: 192.168.56.102) disconnected from the server.

<R1>