Linux paramiko模块以及公钥私钥

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
  • 拷贝公钥到远程服务器上,输入命令 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

(3.1) 连接服务器

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

用户名和密码连接服务器执行命令
公钥私钥连接服务器执行命令
  • 用户名密码方式
# 用户名和密码的方式
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()

  • 公钥私钥方式
# 公钥和私钥(需要先将公钥保存到服务器上)
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()

(3.2) 上传与下载文件

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

用户名和密码连接服务器上传下载文件
公钥私钥连接服务器上传下载文件
  • 用户名密码方式
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()

  • 公钥私钥方式
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. 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')

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值