本文已迁移到我的新博客地址:blog.favorstack.io,欢迎访问~
注:本文假设你已经有一定的linux基本操作常识,所以一些细节不再赘述,仅作为思路参考记下。
本文方法在Linux发行版Ubuntu12.04LTS /12.10 Server下均已验证,其他发行版原理相同。
工作中,如果常常跟linux打交道,肯定经常需要用到ssh远程登录到服务器,毕竟跑机房是不现实的。
ssh每次登录都要求输入密码进行交互,因为它认为直接加密码不安全,但是有时候确实需要执行自动进行的定时任务,如设置的远程登录服务器的一些备份任务,或登录后执行某些脚本,此时就需要避免人工再输入密码确认,但是ssh命令中没有指定密码的参数:
~$ ssh --help
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-ccipher_spec]
[-D[bind_address:]port] [-e escape_char] [-F configfile]
[-I pkcs11][-i identity_file]
[-L [bind_address:]port:host:hostport]
[-llogin_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R[bind_address:]port:host:hostport] [-S ctl_path]
[-Whost:port] [-w local_tun[:remote_tun]]
[user@]hostname [command]
这时该怎么办呢?
因为自己在做服务器代码仓库(采用ssh协议访问的)的备份时就遇到了该问题,写完脚本发现无论如何都要求人工干预(要求输入密码),所以赶紧百度google,下面是我从网上找到的并结合自己的实践整理的一些方法,贴出来与大家共享:
方法一:sshpass +ssh组合
sshpass是sourceforge下面的一个项目,是专门为ssh的免认证登录设计的,没有的的话需要先安装,具体安装命令依各发行版linux有所不同(基于redhat系列的一般是yum;debian的一般是apt-get或aptitude),也可直接去SF官网下载,详细参数如下:
~$ sshpass
Usage: sshpass [-f|-d|-p|-e] [-hV] command parameters
-f filename Take password to use from file
-d number Use number as file descriptor for gettingpassword
-p password Provide password as argument (securityunwise)
-e Password is passed as env-var"SSHPASS"
With no parameters- password will be taken from stdin
-h Show help (this screen)
-V Print version information
At most one of -f, -d, -p or -e should be used
从上面可以看出,它可以直接用“-p”参数指定密码,还可以用“-f”选项来指定存放密码的文件,也可以通过标准输入读入密码,还可以用”-e”选项从环境变量”SSHPASS”来读入密码;sshpass后还要跟上标准的ssh命令语法,如现在可以这样写:
sshpass –p[PASSWD]ssh[USER]@host
这样一条命令就可以了
不过SF官网说,这并不安全,因为它直接存储了明文密码,一般还是要通过秘钥认证的方式,对安全要求不高的可以考虑这种方法。
方法二:expect脚本
expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。
没有的需要先安装,方法同上。
将以下代码保存为.exp后缀的文件如sshlogin.exp,执行
#!/usr/bin/expect
spawn ssh -o StrictHostKeyChecking=no -l username host
expect "*password:"
send "password\r"
interact
注意,执行需要1(x)权限,默认没有,需执行chmod +x sshlogin.exp 或chmod 755sshlogin.exp
然后再执行脚本(./ sshlogin.exp)。
该方法同样以明文方式保存了密码,也是不够安全的。
方法三:密钥文件免认证
首先用ssh-keygen生成密钥:
ssh-keygen –t rsa (根据提示默认回车三次即可);
完成之后,应该在$HOME/.ssh/目录下,新生成两个文件:id_rsa.pub和id_rsa。前者是你的公钥,后者是你的私钥,现在你需要将你的公钥拷贝到服务器上,有三种方法
(1)使用scp:
:~/.ssh$scp id_rsa.pub user@host:/home/user/.ssh/authorized_keys
(2)直接使用ssh-copy-iduser@host
根据提示输入服务器端密码即可,
(3)用$ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys'< ~/.ssh/id_rsa.pub
这条命令由多个语句组成,简介如下:
1)"$ ssh user@host",表示登录远程主机;
2)单引号中的mkdir.ssh && cat >> .ssh/authorized_keys,表示登录后在远程shell上执行的命令;
3)"$ mkdir-p .ssh"的作用是,如果用户主目录中的.ssh目录不存在,就创建一个;
4)'cat >>.ssh/authorized_keys' < ~/.ssh/id_rsa.pub的作用是,将本地的公钥文件~/.ssh/id_rsa.pub,追加到远程文件authorized_keys的末尾。
现在直接使用
ssh user@host或scp命令应该就可以直接登录到服务器了。
远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。
方法三由于不需要把密码明文直接写到文件里面,所以比较安全。但是需要注意的是,该方法需要你保护好私钥文件($HOME/.ssh/id_rsa)不被别人获取到,否则别人拿到你的私钥就可以登录认证过你的机器了,一般该目录默认是自己可读写(700),如果不是,需要修改权限。
最后通过这几个方法再结合具体的应用更改命令就可以实现自动任务了。
本文方法基于linux到linux,对于windows到linux,可以使用putty等工具来实现同样的功能,具体方法参见putty官方文档,或百度google。
参考:
http://ahei.info/ssh-copy-id.htm
http://www.blogjava.net/SpringSun/articles/267387.html
http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html