一.什么是paramiko
主要是基于ssh连接远程主机服务器做操作。
远程执行命令、上传文件等
二.paramiko的应用
1.远程密码连接
ssh连接远程主机时,第一次需要输入yes/no,解决此问题
The authenticity of host '172.25.0.101 (172.25.0.101)' can't be established.
ECDSA key fingerprint is 9d:37:08:8e:a4:ad:45:b5:eb:69:6f:d2:88:d3:da:8c.
Are you sure you want to continue connecting (yes/no)? yes
import paramiko ##获取模块
client = paramiko.SSHClient() ##创建一个ssh远程连接对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ##对上述情况自动选择yes
client.connect( ##连接的服务器的各项信息
hostname = '172.25.4.105',
username = 'root',
password = 'redhat'
)
标准输入、标准输出、标准错误输出
stdin,stdout,stderr = client.exec_command('ip addr show eth0') ##需要执行的操作命令
print(stdout.read().decode('utf-8')) ##获取执行命令的结果
client.close() ##关闭连接
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:00:04:0a brd ff:ff:ff:ff:ff:ff
inet 172.25.4.105/24 brd 172.25.4.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe00:40a/64 scope link
valid_lft forever preferred_lft forever
2.批量远程密码连接
from paramiko.ssh_exception import NoValidConnectionsError,AuthenticationException
def connect(cmd,hostname,user,password):
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(
hostname=hostname,
username=user,
password=password
)
except NoValidConnectionsError as e:
return '主机%s连接失败' %(hostname)
except AuthenticationException as e:
return '主机%s密码错误' %(hostname)
except Exception as e:
return '未知错误:',e
stdin,stdout,stderr = client.exec_command(cmd) ##执行操作
print(stdout.read().decode('utf-8'))
client.close()
if __name__=='__main__':
with open('hosts.txt') as f:
for line in f:
hostname,username,password = line.strip().split(' ')
res = connect('pwd',hostname,username,password)
print(hostname.center(50,'*'))
print('主机名',res)
/root
*******************172.25.4.105*******************
主机名 None
*******************172.25.4.205*******************
主机名 主机172.25.4.205密码错误
******************172.25.254.111******************
主机名 主机172.25.254.111连接失败
3.基于公钥与私钥的连接
注意:我们当前用户(执行此程序的用户)要免秘连接的一台主机作为服务端,用户拿到的是私钥 要连接的主机要挂载公钥
(1)生成密钥
[kiosk@foundation4 ~]$ ls .ssh
authorized_keys known_hosts
[kiosk@foundation4 ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/kiosk/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kiosk/.ssh/id_rsa.
Your public key has been saved in /home/kiosk/.ssh/id_rsa.pub.
The key fingerprint is:
66:5e:42:63:f2:77:9d:26:fe:eb:ca:8e:5e:15:7e:be kiosk@foundation4.ilt.example.com
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| . + . |
| = . o o |
| S o o * .|
| + + o + o |
| . o .|
| + . .|
| .o.+o+E |
+-----------------+
[kiosk@foundation4 ~]$ ls .ssh
authorized_keys id_rsa id_rsa.pub known_hosts
(2)将公钥发送给服务端主机即需要连接的主机
[kiosk@foundation4 ~]$ ssh-copy-id -i /home/kiosk/.ssh/id_rsa.pub root@172.25.4.105
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.25.4.105's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.25.4.105'"
and check to make sure that only the key(s) you wanted were added.
(3)利用paramiko进行免密连接
import paramiko
client = paramiko.SSHClient()
private_key = paramiko.RSAKey.from_private_key_file('/home/kiosk/.ssh/id_rsa') ##创建私钥对象
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(
hostname = '172.25.4.105',
username = 'root',
pkey = private_key
)
stdin,stdout,stderr = client.exec_command('ip addr show eth0')
print(stdout.read().decode('utf-8'))
client.close()
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:00:04:0a brd ff:ff:ff:ff:ff:ff
inet 172.25.4.105/24 brd 172.25.4.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe00:40a/64 scope link
valid_lft forever preferred_lft forever
4.paramiko基于用户和密码的上传和下载文件
import paramiko
from paramiko import AuthenticationException,SSHException
def put(hostname,password,source_name,target_name):
try:
tarnsport = paramiko.Transport(hostname,22) ##建立与远程主机的通道
tarnsport.connect(username = 'root',password=password) ##验证用户及密码是否正确
sftp = paramiko.SFTPClient.from_transport(tarnsport) ##根据创建并验证成功通道
except AuthenticationException as e:
return '主机%s密码错误' %(hostname)
except Exception as e:
return '未知错误:' ,e
else:
sftp.put(source_name,target_name) ##上传文件
# sftp.get('/mnt/name') ##下载文件
finally:
tarnsport.close() ##关闭两台主机间建立的通道
put('172.25.4.105','redhat','/etc/passwd','/mnt/luck')
结果测试
[root@server ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:00:04:0a brd ff:ff:ff:ff:ff:ff
inet 172.25.4.105/24 brd 172.25.4.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe00:40a/64 scope link
valid_lft forever preferred_lft forever
[root@server ~]# cd /mnt
[root@server mnt]# ls
Calculator.sh luck time.sh
[root@server mnt]# cat luck
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown