在某个大型项目的运维过程中,运维工程师小李需要在数十台Linux服务器上执行一项例行的系统更新任务。为了确保任务的高效完成,他需要在所有目标服务器之间实现SSH免密登录,这样可以避免每次登录都手动输入密码,提高工作效率。然而,手动配置每台服务器的免密登录不仅耗时,而且容易出错。
为了解决这个问题,小李决定编写一个Shell脚本,自动批量地在所有目标服务器之间配置SSH免密登录。本文将详细介绍如何通过Shell脚本实现这一目标,帮助运维人员轻松应对类似的批量管理任务。
实现思路
- 首先在本地机器上生成SSH密钥对,如果尚未生成;
- 接着准备一个包含目标服务器IP地址的文件和一个用于登录的远程用户名和密码;
- 然后编写Shell脚本,读取服务器列表并使用sshpass工具和ssh-copy-id命令将本地公钥复制到每个远程服务器的~/.ssh/authorized_keys文件中,以实现免密登录;
- 最后,通过执行该脚本,自动批量配置所有目标服务器的SSH免密登录,以简化和自动化运维操作。
脚本编写
这个Shell脚本用于批量将SSH公钥分发到多个目标主机,以实现免密登录。脚本首先检查必要的依赖和输入,然后遍历目标主机列表,将本地生成的SSH公钥拷贝到每个目标主机上。
(1) 设置公钥文件路径
PUB_KEY_FILE="$HOME/.ssh/id_rsa.pub"
定义本地公钥文件的路径,默认路径为~/.ssh/id_rsa.pub。
(2) 检查sshpass是否安装
# 检查sshpass是否安装
if ! command -v sshpass &> /dev/null; then
echo "sshpass 未安装。请先安装 sshpass,然后再运行此脚本。"
exit 1
fi
使用command -v检查系统中是否安装了sshpass工具。如果未安装,则提示用户安装并退出脚本。
(3) 设置目标主机列表文件 ,并检查文件是否存在
host_list_file="$1"
if [ ! -f "$host_list_file" ]; then
echo "错误: 文件 '$host_list_file' 不存在"
exit 1
fi
将第一个命令行参数(目标主机列表文件)赋值给host_list_file变量。
(4) 读取目标主机列表并分发公钥
while IFS= read -r host; do
echo "正在处理 $host..."
......
done < "$host_list_file"
使用while循环逐行读取目标主机列表文件,每次读取一个主机地址并赋值给host变量。
(5) 生成SSH密钥对
if [ ! -f ~/.ssh/id_rsa ]; then
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
fi
检查本地是否已经存在SSH私钥文件~/.ssh/id_rsa,如果不存在,则生成一个新的SSH密钥对。
(6) 使用sshpass和ssh-copy-id将公钥拷贝到目标主机上
sshpass -p "$password" ssh-copy-id -i ~/.ssh/id_rsa.pub "-p $ssh_port" "$host"
使用sshpass工具提供密码,通过ssh-copy-id命令将本地公钥拷贝到目标主机的~/.ssh/authorized_keys文件中。指定SSH端口和目标主机地址。
脚本使用
这边准备了四台测试机器,如下图:
在跳板机上新建一个文件名为 deploy_ssh_keys.sh,并把脚本的内容复制进去,然后,保存退出。如下图:
然后,为脚本赋予执行的权限,执行如下命令:
chmod +x deploy_ssh_keys.sh
接着,新建一个名为ip.txt的文件,用于存放ip列表的,内容格式如下:
192.168.31.185
192.168.31.232
192.168.31.210
192.168.31.209
运行如下命令,执行脚本文件
./deploy_ssh_keys.sh ip.txt 22 123456
执行成功后,会输出如下信息。
最后,在跳板机上顺便找一台机测试,输入结果如下:
结论
通过上述步骤和Shell脚本,你可以轻松地在多台Linux服务器之间实现SSH免密登录。这种方法适用于需要批量管理和自动化运维的场景,能够极大提高工作效率。希望这篇教程对你有所帮助!