sshpass非交互登录
sshpass+ssh可以实现完全非交互式密码访问远程主机,可直接跳过第一次访问时的yes/no,现如今炙手可热的ansible安装时也会一并安装上sshpass噢
格式:sshpass -p 密码 ssh -o StrictHostKeyChecking=no 用户@主机
如:sshpass -p password ssh -o StrictHostKeyChecking=no foo@192.168.1.1
expect非交互登录
#!/usr/bin/expect
set timeout 5;
set user foo
set password foo123
set host 10.10.4.12
spawn ssh $user@$host
expect {
"Connection refused" exit
"Name or service not known" exit
"continue connecting" {send "yes\r";exp_continue}
"password:" {send "$password\r";exp_continue}
}
expect eof
interact
SSH服务端加速
提示1:Ubuntu发行版默认不允许root ssh远程登录,注释掉/etc/ssh/sshd_config 中的如下一行即可开启root远程登录
提示2:禁用ssh DNS反解,加快访问速度,修改或添加如下行即可
UseDNS no
GSSAPIAuthentication no
SSH客户端
ControlPersist
版本新一点的openssh,如centos7默认自带的版本。
在ssh客户端配置文件/etc/ssh/ssh_config中加入如下内容,可以在~/.ssh/目录下生成访问缓存文件,第一次访问会生成临时的socket隧道,之后再次连接时无需输入再次输入密码
Host *
SendEnv LANG LC_*
ControlMaster auto
ControlPath ~/.ssh/%h-%p-%r
ControlPersist yes
jlive@MacBook-Pro:~ $pstree |grep ssh
| | \--= 00751 jlive ssh root@192.168.130.254
| \--- 00876 jlive grep ssh
|--= 00752 jlive /usr/bin/ssh-agent -l
|--= 00755 jlive ssh: /Users/jlive/.ssh/192.168.130.254-22-root [mux]
|--= 00816 jlive ssh: /Users/jlive/.ssh/10.157.20.8-22-wasadmin [mux]
jlive@MacBook-Pro:~ $ls .ssh/
10.157.20.8-22-wasadmin id_rsa known_hosts
192.168.130.254-22-root id_rsa.pub
忽略主机指纹检查(第一次访问远程主机时不用输yes确认)
一.本地用户密码验证
ssh正常登录某主机会提示输入密码,如没有指定以谁的身份登录则以当前用户的身份来验证
root@jun-live:~#ssh 192.168.2.104
The authenticity of host '192.168.2.104 (192.168.2.104)' can't be established.
RSA key fingerprint is 81:9a:a5:90:4d:4b:2d:b1:df:45:39:33:1a:7f:af:d5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.2.104' (RSA) to the list of known hosts.
root@192.168.2.104's password:
Last login: Tue Sep 9 10:04:14 2014
二.公私钥验证
A.通过ssh-keygen在本机生成公私钥对
root@vhost4:~#ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
c8:07:b6:d5:f4:26:91:7e:1b:97:86:5d:8a:b2:39:e2 root@vhost4
The key's randomart image is:
+---[RSA 2048]----+
| .BE++|
| . +..o |
| . .... o |
| . . .. oo +|
| o o S ... ..+|
| * = =. .o |
| . = =.B o |
| . ..*.* o |
| ..o*=+. |
+----[SHA256]-----+
加密算法默认采用的是rsa加密,dsa可选。
ssh-keygen生成公钥和私钥时会“问”,公私钥存放的位置及名称,如果不指定则默认放在~/.ssh这个目录,并且默认叫id_rsa(私钥), id_rsa.pub(公钥),known_hosts里存放的则是所有远程主机的信息,每个主机一条标识,当远程主机名一样但IP等信息发生变化时会提示信息不匹配,这里只需要把known_hosts里对应的那条记录删掉,再重新建立连接一次,这里该主机的信息会再次自动添加known_hosts文件。可以通过你喜欢的编辑器来打开~/.ssh/known_hosts这个文件删除对应的行,我这里直接用sed流编辑器
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
c7:b3:03:2f:7c:ab:9e:75:fe:c9:a3:45:63:1b:55:3f.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:66
RSA host key for 192.168.2.251 has changed and you have requested strict checking.
Host key verification failed.
lost connection
sed -i '/192.168.2.251/d' ~/.ssh/know_hosts
在提示公私钥的存放位置后还会问,是否给公私钥设置密码,直接回车则不设置密码,如果设置了密码则每次去连接远程主机时都会提示输入公私钥的密码。
问题:
1.没有设置密码的公私钥,配对成功后访问远程主机更方便但不安全,随便copy到另外一台主机就可以无密码直接ssh到已经经过该公私钥配对验证成功的主机
2.设置密码后的公私钥更安全,即便被窃取,但在使用时会提示输入密码,破解也是需要时间的,但每次访问某台主机都需要输入本地公私钥对的密码,不太方便,麻烦。
3.远程主机非常多,并且需要非交互地远程执行一些脚本或命令,这时如果登录一台就输入一次公私钥对的密码,那也很麻烦,怎么办---代理。
root@vhost4:~#pwd
/root
root@vhost4:~#ls .ssh/
id_rsa id_rsa.pub known_hosts
root@vhost4:~#cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtDgmYibO4iuwRj0mAhHvWxvAF1uxCPEtif3yDiISJJncvHGB99V17F/AodzIFv9SOV9F4qekcjmnjNu95VJ7bdAQUnKUJIEABGo4LjhPZB3BJd2RxAdCXvP/IiDIlNjT7RzOd5n9peVmbaMX2wpslvNxdHV3FbHnIa3RrbwfiQ6EitvtOthlOGQgkOgYAEnVbX8RyKAj5ATSW4yrHO1vIyPOe/9/ng0nlwgEoLQnmcetbjJGbcgcdAfY31dE3GTnFVKwbpYWLKnDSGRNj1fPUe2ytBEI4cGMp7uYezROt8m0yd95d4+m6O+6BhO2FYtjaYN1+PlVA8pNiQEyp+Rb0Q== root@vhost4
B.将本机的公钥copy到远程主机的~/.ssh/authorized_keys中
root@vhost4:~#ssh-copy-id -i .ssh/id_rsa.pub 192.168.2.250
root@192.168.2.250's password:
/root/.bashrc: line 48: bind: warning: line editing not enabled
/root/.bashrc: line 54: bind: warning: line editing not enabled
/root/.bashrc: line 59: bind: warning: line editing not enabled
Now try logging into the machine, with "ssh '192.168.2.250'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
默认情况下都是放在远程主机的~/.ssh/authorized_keys这个文件中,除远程主机的/etc/ssh/sshd_config配置文件有重新定义,下面是截取的一段,大概在49行的样子,不同版本可能有些微差异。
47 #RSAAuthentication yes
48 #PubkeyAuthentication yes
49 #AuthorizedKeysFile .ssh/authorized_keys
50 #AuthorizedKeysCommand none
51 #AuthorizedKeysCommandRunAs nobody
ssh-copy-id #自动将本地公钥添加到远程主机~/.ssh/authorized_keys的脚本,一般在安装了openssh后就会有
ssh-copy-id - install your public key in a remote machine’s authorized_keys
SYNOPSIS
ssh-copy-id [-i [identity_file]] [user@]machine
DESCRIPTION
ssh-copy-id is a script that uses ssh to log into a remote machine
(presumably using a login password, so password authentication should
be enabled, unless you’ve done some clever use of multiple identities)
It also changes the permissions of the remote user’s home, ~/.ssh, and
~/.ssh/authorized_keys to remove group writability (which would other-
wise prevent you from logging in, if the remote sshd has StrictModes
set in its configuration). If the -i option is given then the identity
file (defaults to ~/.ssh/id_rsa.pub) is used, regardless of whether
there are any keys in your ssh-agent.
ssh-copy-id能很方便地将本地公钥添加到远程主机对应的认证文件中,当然如果没有这个工具要怎么办呢,通常我们搜索到的文章讲述的时手动copy到远程主机,再把公钥追加到认证文件authorized_keys中。
scp -p ~/.ssh/id_rsa.pub 192.168.2.250:/tmp #把本地的公钥copy到远程的某个目录
ssh 192.168.2.250 #登录到远程主机
cat /tmp/id_rsa.pub >>~/.ssh/authorized_keys #把公钥追加到authorized_keys,这所以要追加是因为远程主机的认证文件authorized_keys中可能已经有了其它客户端的公钥了,如果直接覆盖则其它主机又得重新验证。
rm -rf /tmp/id_rsa.pub #删掉公钥,以确保安全。
C.ssh-agent公私钥代理认证
1.未启用代理,当登录远程主机时会提示输入key的密码,这个密码就时用ssh-keygen生成公私钥对时设置的密码。每次登录都会要求输入密码验证,
root@vhost4:ssh#ssh 192.168.2.250
Enter passphrase for key '/root/.ssh/id_rsa':
2.启用代理
There are two main ways to get an agent set up: The first is that the agent starts a new subcommand
into which some environment variables are exported, eg ssh-agent xterm &. The second is that the
agent prints the needed shell commands (either sh(1) or csh(1) syntax can be generated) which can be
evaluated in the calling shell, eg eval ‘ssh-agent -s‘ for Bourne-type shells such as sh(1) or ksh(1)
and eval ‘ssh-agent -c‘ for csh(1) and derivatives.
从上面的man帮助中我们可以知道,有2种方式来设置代理,
a. 代理subcommand 如,ssh-agent xterm &,通过ssh-agent代理开启了一个xterm后台会话,只要在这个xterm终端中输入ssh-add然后再提示并正确输入公私钥对密码后,通过这个xterm发出的ssh连接都不需要再输入任何密码(前提是针对已经通过该公私钥验证过的远程主机)。
b.直接代理shell进程,如,eval 'ssh-agent -s' 代理sh,ksh; eval 'ssh-agent -c'代理csh,tcsh;
注意:这两种方式都只是代理某个进程及由该进程衍生的子进程,举例来说,代理xterm,那么其它的终端去连远程主机照样需要输入本地公私钥的密码,代理的sh,也只局限于该sh进程,也就时在eval 'ssh-agent -s'这条命令回车后在该终端发起的远程连接,如果Ctrl+D回到上层sh,则代理失效。
下面的进程树可以说明这个问题,
root@vhost4:~#ps aux|grep ssh-agent
root 2138 0.0 0.1 103252 808 pts/0 R+ 11:32 0:00 grep --color=auto ssh-agent
root@vhost4:~#pstree|grep pstree -A3 -B3
|-6*[mingetty]
|-rsyslogd---3*[{rsyslogd}]
|-sshd---sshd---bash-+-grep
| `-pstree
`-udevd---2*[udevd]
直接代理bash
root@vhost4:~#ssh-agent bash
root@vhost4:~#ps aux|grep ssh-agent
root 2142 0.0 0.1 57700 744 ? Ss 11:33 0:00 ssh-agent bash
root 2153 0.0 0.1 103252 812 pts/0 S+ 11:33 0:00 grep --color=auto ssh-agent
验证代理凭据
root@vhost4:~#ssh-add
Enter passphrase for /root/.ssh/id_rsa:
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
启用代理后,代理ssh-agent是上一bash衍生出的子bash的子进程
root@vhost4:~#pstree|grep pstree -A3 -B3
|-6*[mingetty]
|-rsyslogd---3*[{rsyslogd}]
|-sshd---sshd---