转自:http://blog.jianingy.com/2009/10/
主机认证的设置上并不复杂,考虑全面就能很容易搞定。我们还是先来简单描述下环境。这里我们假设主机admin是管理节点,我们的目标是admin上的所有用户都能通过主机认证从admin节点上登陆其他机器而不需要输入密码。首先,来看看需要修改的文件有那些以及他们各自的作用。
• admin上的/etc/ssh/ssh_known_hosts: 系统级别的主机公钥文件,需要将你想登陆主机的公钥全部放在这个文件里。
• 其他机器上的 /etc/ssh/sshd_config :ssh服务进程的配置文件,稍后我们要在这个文件里开启服务进程对主机认证的支持。
• admin上的 /etc/ssh/ssh_config: 系统级别的ssh客户端配置文件,我们需要在里面打开客户端对主机认证的支持。
• 其他机器上的 /etc/hosts.equiv : 允许通过主机认证登陆本机的主机名称(域名或者IP)以及用户名称。(有点拗口,但是就是这个逻辑)
我们先来配置admin上的/etc/ssh/ssh_known_hosts。该文件应该包含admin希望登陆的所有机器的rsa或者dsa公钥。为了获取这个公钥我们可以使用openssh提供的工具“ssh-keyscan”:http://www.linuxmanpages.com/man1/ssh-keyscan.1.php。下面的例子演示了如何获得几个机器的rsa公钥。
ssh-keyscan -t rsa ls101 ls102 ls103 #获取几个机器的公钥,并输出在屏幕上
sort <(ssh-keyscan-t rsa ls101 ls102 ls103)<(cat /etc/ssh/ssh_known_hosts)| uniq #获取几个机器的公钥并和原有的公钥列表做简单排重
接下来我们要在其他机器上开启ssh服务进程对主机认证的支持。编辑文件/etc/ssh/sshd_config,进行下面的设置:
HostbasedAuthentication yes #开启主机认证
IgnoreRhosts no # 允许用户自己设置 ~/.shosts 和 ~/.rhosts。该设置对主机认证中root用户的登陆有关键作用。
修改好ssh服务进程的配置文件后,我们需要重新启动一下ssh服务以应用最新的设置。
在各个ssh服务器准备完毕后,我们来配置admin上面ssh客户端参数。编辑文件/etc/ssh/ssh_config,进行下面的设置:
Host *
HostbasedAuthentication yes # 开启主机认证
EnableSSHKeysign yes # 开启SSH签名支持
由于主机认证会用到一个叫“ssh-keysign”:http://www.linuxmanpages.com/man8/ssh-keysign.8.php的程序来进行认证,因此在ssh_config中开启对SSHKeysign的支持是必要的。
最后,我们将admin的域名加入到每个机器的 /etc/hosts.equiv 文件中。现在,在admin上除root用户外的所有用户都可以通过主机认证登陆其他机器了。为了让root用户也有这样的便利,我们还需要在其他机器的/root中加入文件.shosts。其内容和/etc/hosts.equiv相同。至此,我们已经成功完成了ssh主机认证的全部配置。
请看下面这段脚本片断
while read FN; do
test -e"$FN" || rm -iv "$FN"
done < <(find . $level -type l)
它用来查找一个目录下是否存在损坏的符号链接,然后对符号链接执行“rm -iv“命令。其中一个严重的问题是:为了获取find输出的结果,标准输入被重定向成为了find命令的输出。从而导致循环内部的rm -iv命令不能读取确认删除的信息。其原因是当程序执行到rm -iv的时候,标准输入已经不是原先的通过键盘的输入了,而是find命令的输出。为了解决这个问题,我们可以事先将原始的标准输入保存下来,专门提供给rm -iv来使用。请看下面的脚本片断:
exec 3<&0 # copies STDIN, it prevents'read' stealing STDIN from '$command'
while read FN; do
test -e"$FN" || rm -iv "$FN" <&3
done < <(find . $level -type l)
首先我们把标准输入即&0复制给一个新的描述符-3号描述符。然后在循环内部,我们使用<&3来重定向rm -iv的标准输入到3号描述符-也就是最初的标准输入。从而解决了重定向导致的键盘输入丢失问题。