单向免密
expect
免交互
- 注意修改脚本内的
your_password
为远程主机用户的密码
- 脚本内的 “
master node1 node2
” 需要提前写好/etc/hosts
文件,或者改为ip
即可
#!/usr/bin/env bash ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa -q for host in master node1 node2 do expect -c " spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$host expect { \"*yes/no*\" {send \"yes\r\"; exp_continue} \"*assword*\" {send \"your_password\r\"; exp_continue} \"*assword*\" {send \"your_password\r\";} }" done
或者
#!/usr/bin/env bash ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa -q for host in $(cat ip.txt) do expect -c " spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$host expect { \"*yes/no*\" {send \"yes\r\"; exp_continue} \"*assword*\" {send \"your_password\r\"; exp_continue} \"*assword*\" {send \"your_password\r\";} }" done "这个需要提前准备一个ip.txt文件,里面写好自己需要做免密的ip即可"
sshpass
免交互
- 注意修改脚本内的
your_password
为远程主机用户的密码
- 脚本内的 “
master node1 node2
” 需要提前写好/etc/hosts
文件,或者改为ip
即可 -o StrictHostKeyChecking=no
表示ssh免密码首次登陆避无需输入yes
sshpass
需要提前安装,centos系列
可以直接使用yum
安装,其他发行版,建议使用expect
免交互的方式
#!/usr/bin/env bash for node in master node1 node2 do sshpass -p 'your_password' ssh-copy-id ${node} -o StrictHostKeyChecking=no scp /etc/hosts ${node}:/etc/hosts if [ $? -eq 0 ];then printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m Send ${node} local key to other host succeeded.\e[0m\n" else printf "[\e[0;31mERROR\e[0m]\e[2;35m Send ${node} local key to other host failed!\e[0m\n" fi done
相互免密
- 注意修改脚本内的
your_password
为远程主机用户的密码
- 执行方式:
sh sshcopy.sh ip.txt
ip.txt
非固定名称,可以自行定义
ip.txt
文件内的格式为: "ip地址
用户名
密码
"
- 脚本会删除
~/.ssh
目录,如果有其他秘钥文件存在,请提前备份和保存
,避免保存在~/.ssh
目录下
#!/usr/bin/env bash basepath=$(cd $(dirname $0 ; pwd)) FILENAME=$1 function check_file (){ printf "[\e[0;34mINFO\e[0m]\e[0;35m Checking host ip address account file\e[0m\n" if [ ! -n "${FILENAME}" ]; then printf "[\e[0;31mERROR\e[0m]\e[0;35m No host ip address account file supplied !!!\e[0m\n" printf "[\e[0;34mUsage\e[0m] $0 [\e[0;34mip.txt\e[0m]\n" exit 1 fi IPADDRESS=() USERNAMES=() PASSWORDS=() while read line; do if [ ! -n "${line}" ]; then printf "[\e[0;31mERROR\e[0m]\e[2;35m File is empty!\e[0m\n" break 1 fi ip=$(echo ${line} | cut -d " " -f1) user_name=$(echo ${line} | cut -d " " -f2) pass_word=$(echo ${line} | cut -d " " -f3) if [ "${ip}" == "${user_name}" ]; then printf "[\e[0;31mERROR\e[0m]\e[2;35m File content format error! Format like [ip_address user_name pass_word].\e[0m\n" exit 2 fi if [ ! -n "${ip}" ]; then printf "[\e[0;31mERROR\e[0m]\e[2;35m File content format error! Format like [ip_address user_name pass_word].\e[0m\n" exit 3 fi if [ ! -n "${user_name}" ]; then printf "[\e[0;31mERROR\e[0m]\e[2;35m File content format error! Format like [ip_address user_name pass_word].\e[0m\n" exit 4 fi if [ ! -n "${pass_word}" ]; then printf "[\e[0;31mERROR\e[0m]\e[2;35m File content format error! Format like [ip_address user_name pass_word].\e[0m\n" exit 5 fi IPADDRESS[${#IPADDRESS[*]}]=${ip} USERNAMES[${#USERNAMES[*]}]=${user_name} PASSWORDS[${#PASSWORDS[*]}]=${pass_word} done < ${FILENAME} } function create_key () { [ ! -f ~/.ssh/id_rsa.pub ] && ssh-keygen -t rsa -p '' &>/dev/null printf "[\e[0;34mINFO\e[0m]\e[0;35m Call ssh-keygen to generate key\e[0m\n" for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do ip=${IPADDRESS[$i]} user_name=${USERNAMES[$i]} pass_word=${PASSWORDS[$i]} expect -c " spawn ssh ${user_name}@${ip} \"rm -rf ~/.ssh && ssh-keygen -t rsa -N \'\' -f ~/.ssh/id_rsa -q \> /dev/null 2>&1 \" expect { \"*yes/no*\" {send \"yes\r\"; exp_continue} \"*assword*\" {send \"${pass_word}\r\"; exp_continue} \"*assword*\" {send \"${pass_word}\r\";} }" > /dev/null 2>&1 if [ $? -eq 0 ];then printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m ${ip} call ssh-keygen to generate key succeeded.\e[0m\n" fi done } function create_key_tmp_file () { printf "[\e[0;34mINFO\e[0m]\e[0;35m Copy public key to local\e[0m\n" for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do ip=${IPADDRESS[$i]} user_name=${USERNAMES[$i]} pass_word=${PASSWORDS[$i]} TMP_FILE="${basepath}/.id_rsa.pub.$ip.tmp" expect -c " spawn scp $user_name@$ip:~/.ssh/id_rsa.pub $TMP_FILE expect { \"*yes/no*\" {send \"yes\r\"; exp_continue} \"*assword*\" {send \"$pass_word\r\"; exp_continue} \"*assword*\" {send \"$pass_word\r\";} }" > /dev/null 2>&1 cat $TMP_FILE >> ~/.ssh/authorized_keys rm -f $TMP_FILE if [ $? -eq 0 ];then printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m Copy ${ip} public key to local succeeded.\e[0m\n" fi done } function scp_authorized_keys_file () { printf "[\e[0;34mINFO\e[0m]\e[0;35m Send local key to each host\e[0m\n" for ((i = 0; i < ${#IPADDRESS[@]}; i++)); do ip=${IPADDRESS[$i]} user_name=${USERNAMES[$i]} pass_word=${PASSWORDS[$i]} CMD="scp /root/.ssh/authorized_keys root@$ip:/root/.ssh/authorized_keys" if [ "$user_name" != "root" ]; then CMD="scp /home/$user_name/.ssh/authorized_keys $user_name@$ip:/home/$user_name/.ssh/authorized_keys" fi expect -c " spawn $CMD expect { \"*yes/no*\" {send \"yes\r\"; exp_continue} \"*assword*\" {send \"$pass_word\r\"; exp_continue} \"*assword*\" {send \"$pass_word\r\";} }" > /dev/null 2>&1 if [ $? -eq 0 ];then printf "[\e[0;32mSUCCESS\e[0m]\e[2;35m Send ${ip} local key to each host succeeded.\e[0m\n" fi done } check_file create_key create_key_tmp_file scp_authorized_keys_file printf "[\e[0;34mINFO\e[0m]\e[0;35m Config auto ssh succeeded!\e[0m\n"