赞
踩
公钥(Public Key)与私钥(Private Key)是通过加密算法得到的一个密钥对(即一个公钥和一个私钥,也就是非对称加密方式)。公钥可对会话进行加密、验证数字签名,只有使用对应的私钥才能解密会话数据,从而保证数据传输的安全性。公钥是密钥对外公开的部分,私钥则是非公开的部分,由用户自行保管。用公钥加密的数据必须用对应的私钥才能解密;如果用私钥进行加密也必须使用对应的公钥才能解密,否则将无法成功解密。
比较有趣的例子是鲍勃的钥匙,附上转载的链接 图解公钥与私钥的使用
首先需要下载 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 官方教程
通过ssh远程连接服务器并执行想要命令,类似于Xshell、ansible批量管理机器,ansible底层用的就是paramiko模块。
paramiko 模块官方文档:https://www.paramiko.org/
该模块属于第三方模块,需要下载使用
pip3 install paramiko
连接服务器执行命令的两种方式:
用户名和密码连接服务器执行命令
公钥私钥连接服务器执行命令
# 用户名和密码的方式 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()
上传或下载文件的两种方式:
用户名和密码连接服务器上传下载文件
公钥私钥连接服务器上传下载文件
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()
注意点:
get
⽅法和put
方法⼀次只能传输⼀个⽂件,不能传输⽬录。get
⽅法还是put
方法,若⽬标⽂件存在会直接覆盖。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')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。