ssh和scp是使用远程Linux服务器常用的命令,为了安全起见,他们都没有提供直接指定密码的方法,只能通过手动输入的方式来输入密码。有时需要在脚本当中使用ssh或scp访问远程服务器,就会带来一定的困扰。此时,使用ssh key是一种安全有效的方法,但有时可能没有权限配置ssh key,或者只是临时使用,没有必要配置ssh key,就可以用sshpass命令为其指定密码。
sshpass有下述四种指定密码的方式,其中具体的ssh/scp命令被忽略
1. 直接指定:password为密码
sshpass -p password ssh/scp ...
2. 通过文件指定:password.txt文件的第一行为密码
sshpass -f password.txt ssh/scp ...
3. 通过环境变量指定
export SSHPASS=password
sshpass -e ssh/scp ...
为了方便,也可以将SSHPASS变量加入到bashrc中,避免每次都要手动export。
4. 通过文件描述符指定
例如,在shell中将密码重定向到文件描述符,然后将文件描述符传递给sshpass读取密码
exec 3< password.txt
sshpass -d 3 ssh/scp ...
exec 3<&-
或者在其它语言(例如C或C++)中创建文件描述符
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<stdio.h>
int main() {
int fd[2]; // 用于传递密码的文件描述符
if(pipe(fd) < 0) return 1;
char *p = (char*)malloc(20);
sprintf(p, "%d", fd[0]);
char *argv[] = {
"sshpass",
"-d",
p,
"ssh",
"user@remote",
NULL
};
pid_t pid;
pid = fork();
if(pid == 0) {
// 子进程使用上述参数执行sshpass
execvp(argv[0], argv);
printf("error\n");
} else {
// 父进程写入密码
write(fd[1], "password\n", 9);
// 等待子进程结束
wait(NULL);
printf("success\n");
free(p);
}
return 0;
}
举例说明:假如需要向192.168.1.100的主机地址上用户名为kedixa,密码为123456的用户主目录传递文件k.txt,则使用sshpass可以写成如下的方式,关于ssh/scp命令的使用此处不多介绍。
sshpass -p 123456 scp k.txt kedixa@192.168.1.100:~/k.txt
在首次连接某个主机的时候,需要进行主机认证,此时使用sshpass可能会出现问题,手动连接一次该主机,再使用sshpass连接即可。通常来说,使用sshpass指定密码的方法很不安全,尤其是使用”sshpass -p password”的方法,会将密码以明文的方式存在bash history中。为了安全起见,首先考虑使用ssh key的方式避免输入密码,其次再考虑以文件或环境变量指定密码的方式使用sshpass指定密码。
本文由kedixa发表于个人博客,
转载请注明作者及出处。
本文链接:https://blog.kedixa.top/2018/sshpass/
搜迪斯奈