python编程 入门后学习笔记三——paramiko模块
本节内容
1.paramiko模块的安装
2.利用paramiko模块进行文件传输
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* Python的paramiko模块,基于SSH用于连接远程服务器并执行相关操作。 *
* paramiko遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。 *
* paramiko支持Linux,Solaris, BSD,MacOS X, Windows等平台通过SSH从一个平台连接到另外一个平台。 *
* 利用该模块,可以方便的进行ssh连接和sftp协议进行sftp文件传输。 *
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1.安装
1)Linux
系统:Ubuntu16.04
python版本:python2.7
安装命令:pip install paramiko
但是,我现在想在python3.5中使用paramiko模块
python版本:python3.5
安装命令:sudo apt install python3-pip
pip3 install paramiko
注:执行 pip3 install paramiko 安装命令时,提示需要先安装python3-pip,所以需要先 sudo apt install python3-pip,再执行 pip3 install paramiko。
试试
>>> import paramiko >>>
安装成功。
2)windows
系统:win7
python版本:python3.4
按照经验,需要先安装好pycrypto,再安装paramiko。
暂时没有尝试成功。
第一步,下载 pycrypto-2.6.1.win32-py3.4 .exe,点击exe进行安装,直接默认Next到安装完成;
第二步,下载 paramiko-1.15.2.tar.gz(从https://pypi.python.org/pypi/paramiko 找到合适版本,这里我尝试过paramiko-2.2.1.tar.gz一直报错(error: Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat).));
解压完成以后,打开dos命令控制台进行操作;
切换到paramiko解压的目录下进行安装,执行安装命令python setup.py install;

看到红框的字,真是太兴奋了,(前后摸索了大半上午)终于在Windows上顺利安装好了paramiko模块!!!
2.利用paramiko模块进行文件传输
1)Linux系统间的数据传输
在使用paramiko模块前,我们来先来理解下多台Linux间是如何进行数据互传的?
需求:Linux机器1 向 Linux机器2 传输一个文件 ”test.exe“
Linux机器1:地址 10.0.0.11 端口号 22
Linux机器2:地址 10.0.0.12 端口号 22
操作:
在Linux机器1上,执行命令
[root@Sev ~]# ssh root@10.0.0.12 -p22 root@10.0.0.12's password: Last login: Friday Aug 18 13:31:27 from 10.0.0.11 [root@Vicky ~]#
这时我们已经可以用命令操作 Linux机器2 了
现在退出 Linux机器2,回到 Linux机器1
[root@Vicky ~]# exit
[root@Sev ~]#
从 Linux机器1 向 Linux机器2 发送文件”test.exe“
[root@Sev ~]# scp -rp -P22 test.exe root@10.0.0.12:/tmp/ root@10.0.0.12's password: test.exe [root@Sev ~]#
这样就把test.exe文件发送到 Linux机器2的/tmp目录下了
####################################################################################
那么用Python是如何来模拟scp的呢?
2)Windows宿主机与Linux的文件传输
先来试试 宿主机 连接 Ubuntu虚拟机(ip:192.168.150.128,port:22)
宿主机:win7 bit64
虚拟机: WMware8
Linux:Ubuntu 16.04
#-*- coding:utf-8 -*- import paramiko #创建SSH对象 ssh=paramiko.SSHClient() #允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) print("连接服务器...") ssh.connect(hostname='192.168.150.128',port=22,username='root',password='root') print("执行命令...") stdin,stdout,stderr=ssh.exec_command('df') print("获取命令结果...") result=stdout.read() print(result.decode()) print("关闭连接") ssh.close()
这里记录下,不懂系统的小白入的坑:
♥ 报错:paramiko.ssh_exception.AuthenticationException: Authentication failed.
但是 在linux和windows互ping可以通过
solution:
经排查有如下原因:
1、Ubuntu没有安装 ssh2的服务,在终端中执行如下指令:sudo apt-get install openssh-server
2、防火墙的限制: 请确保windows下防火墙是关闭的;
LINUX(ubuntu)下防火墙的关闭,执行如下指令: sudo ufw disable(一定要有root权限)
3、编辑配置文件,允许以 root 用户通过 ssh 密码登录:
sudo vim /etc/ssh/sshd_config
找到:PermitRootLogin prohibit-password 注释禁用掉
添加:PermitRootLogin yes
sudo service ssh restart
OK,终于可以正常登录!!!
上面代码还有个地方需要改进,不知道你看到了吗?
为了能抓取到 stderr 的信息,对上述代码进行了略微改进:
#-*- coding:utf-8 -*- import paramiko #创建SSH对象 ssh=paramiko.SSHClient() #允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) print("连接服务器...") ssh.connect(hostname='192.168.150.128',port=22,username='root',password='root') print("执行命令...") stdin,stdout,stderr=ssh.exec_command('top') res,err=stdout.read(),stderr.read() print("获取命令结果...") result=res if res else err print(result.decode()) print("关闭连接") ssh.close()
上面已经能传输命令了,现在试试文件的传输(上传、下载)吧!
#-*- coding:utf-8 -*- #Author:'Yang' import paramiko trans=paramiko.Transport(('192.168.150.128',22)) trans.connect(username='root',password='root') sftp=paramiko.SFTPClient.from_transport(trans) #将本地文件paramiko_demo_v1.1.py上传至服务器 /tmp目录下 sftp.put('paramiko_demo_v1.1.py','/tmp/paramiko_demo_v1.1.py') print('paramiko_demo_v1.1.py','已上传') #将服务器 /tmp目录下的文件paramiko_demo_v1.1.py下载到本地,并命名为fromlinux.txt sftp.get('/tmp/paramiko_demo_v1.1.py','fromlinux.txt') print('fromlinux.txt','已下载')
就这么简单几句就OK。
.
.
.
但是上面代码在实际应用中存在一个很大的隐患,不知道你认识到了没?
密码!!!就这么以明文的形式暴露了。
那怎么办?有没有能让我们不用输入密码,又很安全的办法呢?
这就是接下来要讲解的key ——“公钥(public key)-私钥(private key)”
Linux机器1(拿着私钥)-------->Linux机器1(待连接机器,拿着公钥)
Linux机器1上生成key的命令
[root@Sev ~]# ssh-keygen
连续三次回车键,默认存储是
private key saved in /root/.ssh/id_rsa
public key saved in root/.ssh/id_rsa.pub
生成的public key要放到Linux机器2(待连接机器)的什么位置呢?
复制粘贴放置在Linux机器2(待连接机器)
[root@Vicky ~]# vim /root/.ssh/authorized_keys
注意你想连接哪个用户就放在哪个用户下面,这里我们使用的是root用户。
但是复制粘贴容易导致格式不一致引起的错误,还有一个更好的办法是用命令
[root@Sev ~]# ssh-copy-id -p22 root@10.0.0.12
这样就直接把Linux1的公钥拷贝给了Linux2,为了确认,可以在Linux2下 check in .ssh/authorized_keys
现在试试在Linux1上直接连接Linux2吧!
[root@Sev ~]# ssh root@10.0.0.12 -p22
果然不用再输入密码了!
注意:要连接哪台机器就将public key 给哪台机器,千万不要把private key给别人了!
讲了这么多,在python上是怎么模拟的呢?
####################################################################################
例如,现在宿主机想连接Linux1(192.168.150.128:22)
第一步,在Linux1上,用命令
[root@Sev ~]# ssh-keygen
生成public key 和private key(默认情况,分别存储在当前用户的.ssh/id_rsa和.ssh/id_rsa.pub);
第二步,在Linux1上,用命令
[root@Sev ~]# ssh-copy-id -p22 root@192.168.150.128
将public key复制到.ssh/authorized_keys,为了检查是否成功,可以用more .ssh/authorized_keys命令进行查看;
第三步,想办法将Linux1上生成的private key移到宿主机(win7)上
笨方法(1):创建新文件id_rsa.txt,直接将private key复制粘贴保存
笨方法(2):利用上面 paramiko_sftp.py 文件的代码,稍作修改,也就是用户名密码的方式,将id_rsa文件,直接下载下来保存
第四步,运行 paramiko_ssh_rsa.py 验证key方法是否成功。
#-*- coding:utf-8 -*- #Author:'Yang' import paramiko #创建SSH对象 ssh=paramiko.SSHClient() #允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) print("连接服务器...") #指定private key文件 private_key=paramiko.RSAKey.from_private_key_file('id_rsa.txt') ssh.connect(hostname='192.168.150.128',port=22,username='root',pkey=private_key) print("执行命令...") stdin,stdout,stderr=ssh.exec_command('df') res,err=stdout.read(),stderr.read() print("获取命令结果...") result=res if res else err print(result.decode()) print("关闭连接") ssh.close()
以上纯粹出于演示key的应用,实际操作时,要连接哪台机器就将public key 给哪台机器,千万不要把private key给别人了!
浙公网安备 33010602011771号