由于工作中会用到很多服务器,服务器间跳转要不断的输入密码,所以就搞个小脚本来解决这个痛点,也希望能帮到需要的同学。
工具特点
1: 实现服务器间两两互信
2: 支持离线,即使服务器不能连接外网也可行
3: root和非root用户,已验证可行
4: centos7/8 redhat7/8 麒麟V10 统信UOS1020e,已验证可行
5: 配置好服务器信息后,全自动化运行
工具免费下载,可任意复制使用,如果有bug或需要兼容的操作系统,可评论区交流
下载地址
https://download.csdn.net/download/u014773648/89642404
使用说明
脚本代码
#!/bin/bash
# 功能:实现服务器间互信,达到免秘钥登录
# 1: root和非root用户,已验证可行
# 2: centos7/8 redhat7/8 麒麟V10 统信UOS1020e,已验证可行
# author 鲁家湾
# 跳转到本脚本的当前目录
cd $(dirname $0)
declare -A all_ip_pwd_dict
# 获取变量
if [ -f ./trust.cfg ];then
source ./trust.cfg
else
echo "获取trust.cfg配置文件失败,请检查!"
exit -1
fi
# 若未安装expect,则安装
command -v expect >/dev/null
if [ $? -ne 0 ];then
if [ -d ./lib/ ];then
cd ./lib/; rpm -Uvh --force --nodeps ./*.rpm
else
echo "未发现lib目录,请检查!"
exit -1
fi
fi
command -v expect >/dev/null
if [ $? -ne 0 ];then
echo "安装expect出错,请检查!"
exit -1
fi
# 获取当前服务器的ip,若当前服务器有多个ip,只匹配trust.cfg中的ip
cur_ip=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
cur_array=(${cur_ip//\r\n/ })
cur_real_ip=""
for tmp_ip in ${cur_array[@]}
do
if [[ `echo "${!all_ip_pwd_dict[@]}" | grep -Ewq "$tmp_ip" && echo '1'` == '1' ]] ; then
cur_real_ip=$tmp_ip
fi
done
if [[ X$cur_real_ip == X"" ]];then
echo "当前服务器的ip未配置到trust.cfg的all_ip_pwd_dict中,请检查!"
exit -1
fi
# 生成公钥
if [ ! -f ~/.ssh/id_rsa.pub ];then
ssh-keygen -f ~/.ssh/id_rsa -t rsa -N ''
fi
# 保存本机的秘钥
cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
# 配置在第一次登陆时,避免出现yes/no的确认提示
if [ -f ~/.ssh/config ];then
is_avoidance_yes=`grep "^StrictHostKeyChecking no" ~/.ssh/config|wc -l`
else
is_avoidance_yes=0
fi
if [ $is_avoidance_yes -le 0 ];then
echo "StrictHostKeyChecking no" >>~/.ssh/config
fi
# 确保config文件的用户组和其他用户没有可写的权限,否则ssh时会报'Bad owner or permissions'错误
chmod 644 ~/.ssh/config
# 本机与每个服务器建立互信,便于免密登录
for tmp_ip in ${!all_ip_pwd_dict[@]}
do
if [[ $cur_real_ip != $tmp_ip ]];then
expect -c "
spawn ssh-copy-id -p $ssh_port $tmp_ip
expect {
\"yes/no\" {send \"yes\r\"; exp_continue}
\"password\" {send \"${all_ip_pwd_dict[$tmp_ip]}\r\"; exp_continue}
}
spawn ssh -p $ssh_port $tmp_ip \"cd ~/.ssh;ssh-keygen -t rsa\"
expect {
\".ssh/id_rsa\" {send \"id_rsa\r\"; exp_continue}
\"y/n\" {send \"y\r\"; exp_continue}
\"passphrase\" {send \"\r\"; exp_continue}
\"passphrase\" {send \"\r\";}
}
"
# 检查互信是否成功
ssh -p $ssh_port $tmp_ip -o PreferredAuthentications=publickey -o StrictHostKeyChecking=no "date" >/dev/null 2>&1
if [ $? -ne 0 ];then
cur_user=`whoami`
echo -e "\n======================================================"
echo "服务器间互信失败!"
echo "处理1: 检查trust.cfg中${tmp_ip}的密码是否正确"
echo "处理2: 检查所有服务器是否存在用户$cur_user"
echo "处理3: 检查本机能否远程登录上所有服务器,如ssh $cur_user@$tmp_ip"
echo "处理4: 删除所有服务器~/.ssh/目录下的文件(rm ~/.ssh/* -rf)"
echo "以上4条处理好后再执行互信脚本"
echo -e "========================================================\n"
exit -1
fi
# 收集公钥
ssh -p $ssh_port $tmp_ip "cat ~/.ssh/id_rsa.pub" >> ~/.ssh/authorized_keys;
chmod 600 ~/.ssh/authorized_keys
fi
done
# 给每个服务器复制认证文件,以达到两两互信
for desc_ip in ${!all_ip_pwd_dict[@]}
do
if [[ $cur_real_ip != $desc_ip ]];then
scp -P $ssh_port -o ConnectTimeout=10 ~/.ssh/authorized_keys $desc_ip:~/.ssh/authorized_keys
scp -P $ssh_port -o ConnectTimeout=10 ~/.ssh/config $desc_ip:~/.ssh/config
fi
done