我們的服務器都是通過key認證的,使用CRT登錄服務器,雖然登錄各個服務器用CRT(它有OPENSSH代理轉發的功能)已經很方便了,不需要輸入密碼。但是,當我們在控制服務器上通過ssh客戶端執行腳本的時候,打個比方,在center上有個腳本,腳本中需要ssh到host1執行腳本1,而腳本1中又需要ssh到host2獲取數據,很顯然,當在center執行這個腳本的時候,腳本中ssh到host1執行腳本1是成功的(因爲CRT啓用了轉發,所以從center ssh到host1認證是通過的),但是host1上的腳本1 ssh到host2肯定是失敗的。因爲在center上沒有啓用代理轉發,所以從host1到hosts2的認證是失敗的。那怎麼辦呢?
那就是使用SSH代理轉發就OK了,在center控制服務器上,啓動代理程序,添加私鑰,搞定!
[root@centos6-1 ~]# eval `ssh-agent`
Agent pid 26771
[root@centos6-1 ~]# ssh-add
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
[root@centos6-1 ~]#
eval `ssh-agent`
#這麼要加個eval?因爲執行ssh-agent會生成兩個變量,一個sock文件的變量,一個pid的變量,而這兩個東西在使用ssh-add添加私鑰的時候需要用到,所以必須把它添加到環境變量中去,並且它自殺的時候也需要用到(ssh-agent -k),如下所示:
[root@centos6-1 ~]# ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-XesKe26726/agent.26726; export SSH_AUTH_SOCK;
SSH_AGENT_PID=26727; export SSH_AGENT_PID;
echo Agent pid 26727;
然後再添加私鑰
ssh-add
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
默認就是使用的~/.ssh/id_rsa 等私鑰文件!
基本上這裏就搞定了,在終端上肯定是沒問題的了,但是一旦退出終端,這個就失效了,而且,每天登錄的時候都必須執行上述兩個步驟,難免有些繁瑣,而且假設我這個腳本是在計劃任務中執行的呢?也不管用了。
所以我必須把它加到環境變量中去,而且這個腳本必須能夠用到這個環境變量。於是,我寫了個腳本,在登錄的時候自動執行這兩步,vim /etc/profile.d/ssh-agent.sh:
#!/bin/bash
if [ ! -S "/etc/ssh/ssh-agent.sock" ]
then
eval `ssh-agent -a /etc/ssh/ssh-agent.sock` >/dev/null && ssh-add &>/dev/null
echo -e "SSH_AGENT_PID=$SSH_AGENT_PID\nSSH_AUTH_SOCK=$SSH_AUTH_SOCK" > /etc/ssh/ssh-agent.env
else
source /etc/ssh/ssh-agent.env
export SSH_AGENT_PID SSH_AUTH_SOCK
ssh-add &>/dev/null
fi
~
在啓動ssh-agent的時候,我指定了sock路徑,爲什麼?因爲每次啓動程序的時候它都會產生一個新的進程,指定了sock文件了就避免了這種情況了。
然後,凡是在計劃任務中運行的腳本,首先source /etc/profile下,就解決問題了。當然,ssh的時候必須開啓代理轉發啊,比如使用ssh -A 這樣的方式,或者,直接在center服務器上的ssh配置文件中加入:
vim ~/.ssh/config
Host *
ForwardAgent yes
OK,就搞定了!