在做系統運維的時候,可能以免密碼通過ssh方式登錄到遠程主機,這時就首先需要將本機的公鑰復制到遠程主機,用ssh-copy-id命令可以輕松做到。
如果沒有生成密鑰對,要先生成密鑰,再將公鑰復制到遠程主機,usernaem是遠程主機的用戶名,host是遠程主機的ip地址或域名
#生成密鑰
ssh-keygen -t rsa
#復制公鑰到遠程主機 ssh-copy-id username@host
對於單台遠程主機,直接使用命令就可以了,但如果有很多台主機,需要一台台操作,就費時費力了。那么有什么好辦法,能夠一次性將公鑰復制到所有主機呢?要解決這個問題,要自動處理在執行ssh-copy-id命令時兩處需要手工介入的過程。
一是在看到類似如下提示時,要輸入”yse“進行確認。
The authenticity of host '10.10.5.133 (10.10.5.133)' can't be established. RSA key fingerprint is SHA256:anhO4ihOzEsun0zDRNAu8Wew9Bxntr7Di6qpJVAnXFQ. Are you sure you want to continue connecting (yes/no)?
二是需要輸入遠程主機的密碼
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ubuntu/.ssh/id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys Warning: Permanently added '10.10.5.133' (RSA) to the list of known hosts. root@10.10.5.133's password:
解決第一個問題,可以修改配置文件或運行ssh-copy-id命令加ssh的相關參數。
# -o StrictHostKeyChecking=no,連接新主機時,不進行公鑰確認
ssh-copy-id -o StrictHostKeyChecking=no root@10.10.5.133
或者在當前用戶目錄的.ssh/config文件,添加如下配置項,如果.ssh目錄沒有config文件,可自行創建。
StrictHostKeyChecking=no
接着來解決第二個問題,安裝sshpass命令,在ubuntu中可以用apt-get命令直接安裝,在Centos下,請google搜索安裝方式,在這里就不作說明了。
apt-get install sshpass
通過安裝好的sshpass命令,運行下面命令就能無需手工介入將ssh公鑰復制到遠程主機。
sshpass -p 'YOUR_PASSWORD' ssh-copy-id -o StrictHostKeyChecking=no root@10.10.5.133
如果使用修改配置文件的方式,可用下面的命令。
sshpass -p 'YOUR_PASSWORD' ssh-copy-id root@10.10.5.133
在解決了上面的兩個問題之后,接下來的事情就簡單了, 可以將遠程主機的域名或IP地址記錄在一個文件中,比如記錄在remote-hosts文件中,運行下面的腳本就能批量的將公鑰復制到遠程主機中。
for host in $(cat remote-hosts) do sshpass -p 'YOUR_PASSWORD' ssh-copy-id -o StrictHostKeyChecking=no root@${host} done
注:上面的腳本是遠程主機的密碼都是相同,在命令行將密碼硬編碼寫死,如果每台主機的密碼不一樣,可以將密碼記錄在remote-hosts文件中,通過cut命令分割,可以分別獲得主機的IP地址或域名和對應的密碼,當然如果ssh的端口號不是默認的22,也可以一並記錄。如下列格式:
10.10.10.10:2222:YOURPASSWORD
可將上面的腳本稍做修改:
因為ssh-copy-id使用非默認端口時,需要加雙引號,沒有找到地的辦法,取了個巧,先將整個命令放至一個臨時文件。再執行該臨時文件,執行之后,再刪除。
for host in $(cat remote-hosts) do ip=$(echo ${host} | cut -f1 -d ":") port=$(echo ${host} | cut -f2 -d ":") password=$(echo ${host} | cut -f3 -d ":") arg=$(echo -p ${port} -o StrickHostKeyChecking=no root@${ip}) echo sshpass -p ${password} ssh-copy-id '"'${arg}'"' >> tmp.sh done sh tmm.sh rm -f tmp.sh