目录
学习来源:
一、SSH
SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。
SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。
通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、PoP、甚至为PPP提供一个安全的"通道
从客户端来看,
1、SSH提供两种级别的安全验证:
- 第一种级别(基于口令的安全验证)
只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击
- 第二种级别(基于密匙的安全验证)
需要依靠密匙(激活码),也就是你必须为自己创建一对密匙,并把公用密匙放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在该服务器上你的主目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致,服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器。
但是整个登录的过程可能需要10秒
2、SSH 主要由三部分组成:
- 传输层协议 [SSH-TRANS]
提供了服务器认证,保密性及完整性。此外它有时还提供压缩功能。SSH-TRANS 通常运行在TCP/IP连接上,也可能用于其它可靠数据流上。
- 用户认证协议 [SSH-USERAUTH]
用于向服务器提供客户端用户鉴别功能。它运行在传输层协议 SSH-TRANS 上面。当SSH-USERAUTH 开始后,它从低层协议那里接收会话标识符(从第一次密钥交换中的交换哈希H )
- 连接协议 [SSH-CONNECT]
将多个加密隧道分成逻辑通道。它运行在用户认证协议上。它提供了交互式登录话路、远程命令执行、转发 TCP/IP 连接和转发 X11 连接。
3、结构
SSH是由客户端和服务端的软件组成的
有两个不兼容的版本分别是:1.x和2.x。 用SSH 2.x的客户程序是不能连接到SSH 1.x的服务程序上去的。OpenSSH 2.x同时支持SSH 1.x和2.x。SSH 1.x和SSH 2.x在连接协议上有一些差异。
他们的工作机制大致是本地的客户端发送一个连接请求到远程的服务端,服务端检查申请的包和IP地址再发送密钥给SSH的客户端,本地再将密钥发回给服务端,自此连接建立。
二、SFTP
sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。
可以为传输文件提供一种安全的网络的加密方法。
sftp 与 ftp 有着几乎一样的语法和功能。
SFTP 为 SSH的其中一部分,是一种传输档案至 Blogger 伺服器的安全方式。其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件信息传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接和答复操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。
在Linux中的用法
- 连接远程服务器:sftp username@ip 回车之后输入服务器密码即可连接成功。
- 将文件上传到服务器上:put [本地文件的地址] [服务器上文件存储的位置]
- 将服务器上的文件下载到本地:get [服务器上文件存储的位置] [本地要存储的位置]
三、使用Python的paramiko模块远程登录服务器
ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography)。
paramiko包含两个核心组件:SSHClient和SFTPClient
- SSHClient的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用于执行远程命令。
- SFTPClient的作用类似与Linux的sftp命令,是对SFTP客户端的封装,用以实现远程文件操作,如文件上传、下载、修改文件权限等操作。
- Channel:是一种类Socket,一种安全的SSH传输通道
- Transport:是一种加密的会话,使用时会同步创建了一个加密的Tunnels(通道),这个Tunnels叫做Channel
- Session:是client与Server保持连接的对象,用connect()/start_client()/start_server()开始会话
1、SSHClient方式登录以及常用方法
connect():实现远程服务器的连接与认证
参数:
hostname 连接的目标主机(必须的参数)
port=SSH_PORT 指定端口
username=None 验证的用户名
password=None 验证的用户密码
pkey=None 私钥方式用于身份验证
key_filename=None 一个文件名或文件列表,指定私钥文件
timeout=None 可选的tcp连接超时时间
allow_agent=True, 是否允许连接到ssh代理,默认为True 允许
look_for_keys=True 是否在~/.ssh中搜索私钥文件,默认为True 允许
compress=False, 是否打开压缩
set_missing_host_key_policy():设置远程服务器没有在know_hosts文件中记录时的应对策略
目前支持三种策略:
AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
exec_command():在远程服务器执行Linux命令的方法
返回三个变量:stdin是标准输入,stdout是正确输出,stderr是错误输出(stdout和stderr只会输出一个)
open_sftp():在当前ssh会话的基础上创建一个sftp会话。
该方法会返回一个SFTPClient对象(基于当前连接的sftp对象),然后可以进行文件的操作
2、transport 方式登录
登录上服务器执行多个操作,比如执行命令、上传/下载文件,但是基于SSHClient是传统的连接服务器、执行命令、关闭的一个操作,无法做到多操作
简单示例:
#SSHClient 封装 Transport
import paramiko
# 实例化一个transport对象
transport = paramiko.Transport(('服务器IP', 22))
# 建立连接
transport.connect(username='你的账户', password='你的密码')
# 将sshclient的对象的transport指定为以上的transport
ssh = paramiko.SSHClient()
ssh._transport = transport
# 执行命令,和传统方法一样
stdin, stdout, stderr = ssh.exec_command('df')
print (stdout.read().decode())
# 关闭连接
transport.close()
3、SFTPClient方式登录以及常用方法
SFTPCLient作为一个sftp的客户端对象,根据ssh传输协议的sftp会话,实现远程文件操作,如上传、下载、权限、状态
from_transport(cls,t):创建一个已经连通的SFTP客户端通道
put(localpath, remotepath, callback=None, confirm=True) :将本地文件上传到服务器
参数:
- localpath:本地文件的路径
- remotepath:上传到服务器的文件的路径
- confirm:是否调用stat()方法检查文件状态,返回ls -l的结果
get
(remotepath, localpath, callback=None) 从服务器下载文件到本地
mkdir() 在服务器上创建目录
remove() 在服务器上删除目录
rename() 在服务器上重命名目录
stat() 查看服务器文件状态
listdir() 列出服务器目录下的文件
四、代码实现(无密钥方式
)
登录远程服务器实现Linux操作
'''
file:01_ssh.py
'''
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在known_hosts文件上的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname="服务器IP", port=22, username="账号", password="密码")
# 执行命令
stdin, stdout, stderr = ssh.exec_command('cd zhuzhu && ls')
# 获取结果
result = stdout.read().decode()
# 获取错误提示(stdout、stderr只会输出其中一个)
err = stderr.read()
# 关闭连接
ssh.close()
print("-------------------------------")
print(stdin)
print("-------------------------------")
print(result)
print("-------------------------------")
print(err)
print("-------------------------------")
#输出
-------------------------------
<paramiko.ChannelFile from <paramiko.Channel 0 (closed) -> <paramiko.Transport at 0xf09c7f48 (unconnected)>>>
-------------------------------
frp
test
-------------------------------
b''
-------------------------------
传输文件至服务器、从服务器下载文件
'''
file:02_sftp.py
'''
import paramiko
# 连接虚拟机centos上的ip及端口
transport = paramiko.Transport(("服务器IP", 22))
transport.connect(username="账号", password="密码")
# 将实例化的Transport作为参数传入SFTPClient中
sftp = paramiko.SFTPClient.from_transport(transport)
# 将“calculator.py”上传到filelist文件夹中
sftp.put('C:/Users/86183/Desktop/test_dir/test.txt', 'zhuzhu/test/test.txt')
# 将centos中的aaa.txt文件下载到桌面
sftp.get('zhuzhu/test/test.txt', r'C:/Users/86183/Desktop/test.txt')
transport.close()