当前位置:   article > 正文

Linux paramiko模块以及公钥私钥_paramiko rsakey

paramiko rsakey

1. 公钥与私钥

公钥(Public Key)与私钥(Private Key)是通过加密算法得到的一个密钥对(即一个公钥和一个私钥,也就是非对称加密方式)。公钥可对会话进行加密、验证数字签名,只有使用对应的私钥才能解密会话数据,从而保证数据传输的安全性。公钥是密钥对外公开的部分,私钥则是非公开的部分,由用户自行保管。用公钥加密的数据必须用对应的私钥才能解密;如果用私钥进行加密也必须使用对应的公钥才能解密,否则将无法成功解密。

比较有趣的例子是鲍勃的钥匙,附上转载的链接 图解公钥与私钥的使用

2. git 配置公钥与私钥

首先需要下载 git ,官方网站地址:Git - Downloads

  • 安装完之后进入git终端,输入命令 ssh-keygen -t rsa 并按三次回车,会在默认系统用户目录下 .ssh 文件夹里面生成一个私钥 id_rsa 和一个 公钥 id_rsa.pub
    在这里插入图片描述
    ssh-keygen 会确认密钥的存储位置(默认是 .ssh/id_rsa),然后它会要求你输入两次密钥口令。 如果你不想在使用密钥时输入口令,将其留空即可。 然而,如果你使用了密码,那么请确保添加了 -o 选项,它会以比默认格式更能抗暴力破解的格式保存私钥。 你也可以用 ssh-agent 工具来避免每次都要输入密码。

  • 查看公钥,使用的命令是 cat ~/.ssh/id_rsa.pub,公钥类似于

	$ cat ~/.ssh/id_rsa.pub
	ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
	GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
	Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
	t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
	mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
	NrRFi9wrf+M7Q== schacon@mylaptop.local
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 拷贝公钥到远程服务器上,输入命令 ssh-copy-id -i 公钥文件路径 usename@hostname ,然后会生成已知的主机公钥清单 know_hosts
    在这里插入图片描述

  • git 终端进入虚拟机环境 ssh 用户名@服务器IP

git 详细中文教程: git 官方教程

3. paramiko 模块

通过ssh远程连接服务器并执行想要命令,类似于Xshell、ansible批量管理机器,ansible底层用的就是paramiko模块。

paramiko 模块官方文档:https://www.paramiko.org/
该模块属于第三方模块,需要下载使用

pip3 install paramiko
  • 1

(3.1) 连接服务器

连接服务器执行命令的两种方式:

用户名和密码连接服务器执行命令
公钥私钥连接服务器执行命令
  • 1
  • 2
  • 用户名密码方式
# 用户名和密码的方式
import paramiko

# 创建ssh对象
ssh = paramiko.SSHClient()

# 允许链接不在know_hosts文件中主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 链接服务器
ssh.connect(hostname='10.0.0.100', port=22, username='root', password='111')

# 执行命令
stdin, stdout, stderr = ssh.exec_command('ip a')
# stdin, stdout, stderr = ssh.exec_command('ls')
"""
stdin       输入的内容
stdout      输出的内容
stderr      错误的内容
"""

# 获取结果
res = stdout.read()  # 基于网络传输 该结果是一个bytes类型
print(res.decode('utf-8'))

# 断开链接
ssh.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 公钥私钥方式
# 公钥和私钥(需要先将公钥保存到服务器上)
import paramiko
 
# 读取本地私钥
private_key = paramiko.RSAKey.from_private_key_file('私钥路径')
 
# 创建SSH对象
ssh = paramiko.SSHClient()

# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接服务器
ssh.connect(hostname='服务器IP', port=22, username='用户', pkey=private_key)
 
# 执行命令
stdin, stdout, stderr = ssh.exec_command('ls /')

# 获取命令结果
result = stdout.read()
print(result.decode('utf-8'))

# 关闭连接
ssh.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

(3.2) 上传与下载文件

上传或下载文件的两种方式:

用户名和密码连接服务器上传下载文件
公钥私钥连接服务器上传下载文件
  • 1
  • 2
  • 3
  • 4
  • 用户名密码方式
import paramiko
 
# 用户名和密码
transport = paramiko.Transport(('服务器IP', 22))
transport.connect(username='用户', password='密码')
 
sftp = paramiko.SFTPClient.from_transport(transport)
 
# 上传文件 如:将py文件相对路径下的a.txt文件上传到服务器的data文件夹下并重命名为tmp.txt
sftp.put("a.txt", '/data/tmp.txt')  # 注意上传文件到远程某个文件下 文件必须存在
 
# 下载文件
sftp.get('/data/tmp.txt', 'b.txt')  # 将远程文件下载到本地并重新命名

transport.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 公钥私钥方式
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('私钥路径')
transport = paramiko.Transport(('服务器IP', 22))
transport.connect(username='用户', pkey=private_key)

sftp = paramiko.SFTPClient.from_transport(transport)
# 将当前py文件相对路径下的location.py 上传至服务器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
 
# 将remove_path 下载到本地 local_path
sftp.get('remove_path', 'local_path')

transport.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注意点:

  1. get⽅法和put方法⼀次只能传输⼀个⽂件,不能传输⽬录。
  2. 上传和下载的路径参数都必须具体到⽂件名,不能是⽬录,⽂件名也不能⽤通配符
  3. 不管是get⽅法还是put方法,若⽬标⽂件存在会直接覆盖。

(3.3) 方法整合

import paramiko


class SSHProxy(object):
    def __init__(self, hostname, port, username, password):
        self.hostname = hostname
        self.port = port
        self.username = username
        self.password = password
        self.transport = None

    def open(self):  # 给对象赋值一个上传下载文件对象连接
        self.transport = paramiko.Transport((self.hostname, self.port))
        self.transport.connect(username=self.username, password=self.password)

    def command(self, cmd):  # 正常执行命令的连接  至此对象内容就既有执行命令的连接又有上传下载链接
        ssh = paramiko.SSHClient()
        ssh._transport = self.transport

        stdin, stdout, stderr = ssh.exec_command(cmd)
        result = stdout.read()
        return result

    def upload(self, local_path, remote_path):
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        sftp.put(local_path, remote_path)
        sftp.close()

    def close(self):
        self.transport.close()

    def __enter__(self):
        print('with开始')
        self.open()
        return self  # 该方法返回什么 with ... as 后面就拿到什么

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with结束')
        self.close()


if __name__ == '__main__':
	# 不用with上下文管理语句需要加上 open()和close()方法
    # obj = SSHProxy(hostname='10.0.0.200',port=22,username='root',password='123')
    # obj.open()
    # print(obj.command('ip a'))
    # print(obj.command('ls /'))
    # print(obj.command('ls -l'))
    # obj.upload(r'hhh.txt','/data/heihei.txt')
    # obj.close()

	# 由于在类中定义了 __enter__ 和 __exit__方法分别在with开始和结束分别执行 open()和close()
    with SSHProxy(hostname='10.0.0.200', port=22, username='root', password='123') as obj:
        print(obj.command('ip a'))
        obj.upload(r'a.txt', '/data/b.txt')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/603451
推荐阅读
相关标签
  

闽ICP备14008679号