使用SSHpass实现远程服务器免密登陆和文件传输
Password-free Login and File Transferring with Remote Server using SSHpass
Jiawei Xu
Released: 2022-10-07 / Updated: 2022-10-31
日常工作中免不了需要登陆远程服务器,并下载或上传文件。常规的做法是安装XShell,WinSCP,FileZilla等客户端软件,借助图形化界面进行文件操作,也可以用命令行开展工作。以上软件均可看作是对Windows/Linux系统自带的ssh/scp指令的一种封装与图形化表示,在日常工作中,用好ssh/scp指令也是很方便的。使用这两条指令的缺点是:1). 每次都需要输入用户名和主机地址;2). 每次都需要输入密码。对于第一个问题,一般可以通过设置别名(如Linux的alias)来解决,但输入密码仍然无法回避。这里介绍使用SSHpass解决ssh/scp命令密码验证的方法。
1. Linux安装SSHpass
对于有root权限的情况:
yum install -y epel-release
yum repolist
yum install -y sshpass
对于无root权限的情况,从源码进行安装,假定解压后的目录是/home/jwxu/sshpass-1.08:
wget http://sourceforge.net/projects/sshpass/files/sshpass/1.05/sshpass-1.08.tar.gz
tar -xvzf sshpass-1.08.tar.gz
cd /home/jwxu/sshpass-1.08
mkdir bin
./configure --prefix=/home/jwxu/sshpass-1.08/bin
make && make install -j
在.bashrc中添加以下环境变量并source ~/.bashrc:
export PATH=$PATH:/home/jwxu/sshpass-1.08/sshpass
运行SSHpass:
sshpass -p password ssh [-p port] username@host
sshpass -p password scp [-P port] [-r show progress] username@host:~/file.tar ./
2. 命令设置
准备以下脚本,例如命名为xconnect:
#!/usr/bin/python3
import os,sys
name_list=['aaa','bbb','ccc']
host_list=['a@ipa','b@ipb','c@ipc']
passwd_list=['passwordforaaa','passwordforbbb','passwordforccc']
port_list=[portforaaa,portforbbb,portforccc] # Usually default port number is 22
def getpasswd(name):
num=0
host,passwd,port='','',''
for i in range(len(name_list)):
num+=1
if name==name_list[i]:
host=host_list[i]
passwd=passwd_list[i]
port=port_list[i]
if host=='':
return False
else:
return True,host,passwd,port
command,name=sys.argv[1],sys.argv[2]
check,host,passwd,port=False,'','',22
if len(getpasswd(name))==1:
print('Not in host list!')
else:
check,host,passwd,port=getpasswd(name)
if command=='ssh':
ssh_command='sshpass -p "'+passwd+'" ssh -p '+str(port)+' '+host
print(ssh_command+'\n')
os.system(ssh_command)
elif command=='scpdown' or command=='scpup':
localdir=sys.argv[3]
clouddir=sys.argv[4]
if command=='scpdown':
scp_command='sshpass -p "'+passwd+'" scp -P '+str(port)+' -r '+host+':~'+clouddir+' '+localdir
print(scp_command+'\n')
os.system(scp_command)
elif command=='scpup':
scp_command='sshpass -p "'+passwd+'" scp -P '+str(port)+' -r '+localdir+' '+host+':~'+clouddir
print(scp_command+'\n')
os.system(scp_command)
修改line 5~8的账户信息,其中line 5为账户别名,用于登陆时使用。使用方法如下:
# xconnect operation hostname [local file or route] [remote file or route]
# For examples,
# Connect to remote server named 'kalinite':
>> xconnect ssh kalinite
# Download file from remote server to current directory:
>> xconnect scpdown kalinite . /data/output.tar # Note: '/data/output.tar' stands for '~/data/output.tar' so that you don't need to type '~'
# Upload file to remote server:
>> xconnect scpup kalinite ./input.tar /kalinite/workdir/
默认在运行相应指令是输出实际运行的SSHpass命令,可以注释脚本中的两行print使其不输出。
下面是一些实用的例子:
alias upall='for i in ./*.*;do xconnect scpup host $i /dir;done'
alias tarallup='tar -cf up.tar;xconnect scpup host up.tar /dir;rm -f up.tar' # Especially useful for a lot of small files
alias uplogin='tar -cf up.tar;xconnect scpup host up.tar /dir;rm -f up.tar;xconnet ssh host'
需要注意的是,xconnect脚本中已经包含了账户密码等信息,存在一定风险。可行的办法是将xconnect打包编译成二进制可执行文件。首先安装PyInstaller扩展包,然后将xconnect打包,在产生的dist文件夹下有打包完的二进制可执行文件,较源代码安全性有所提高。
>> pip install pyinstaller
# Or mirror package: pip install -i [mirror] pyinstaller
>> pyinstaller -F xconnect
>> cd dist