自动分发SSH秘钥

背景介绍

企业A新入职了一位资深网络管理专家,经过一周的了解,发现公司现在的网络情况非常糟糕,所有的同事都可以从线下办公网访问线上生产服务器进行操作,有稳定性风险。现在网络组要进行网络权限隔离,使线下不能直接访问线上,影响运维的日常生产问题排查。于是,组长和网络管理人员对此事进行沟通,最终结论是网络组给运维组开放一个访问入口,让运维组申请2台服务器作为中控机并申请办公网访问权限,以后访问生产的机器都要先登录任意一台中控机,然后在SSH到目标主机上。

解决方案

现在线上有500台服务器,如果每次排查问题都从中控机上手动输入密码非常影响效率。现在需要开发批量分发秘钥的脚本,实现SSH免密登录。

基础环境

两台服务器,一台模拟中控机,一台模拟生产机器,操作系统Linux,发行版本不限制。

假设中控机IP地址是10.0.1.67,生产机器是10.0.1.66

环境准备好后,先生成ssh秘钥

# -q: 安静模式
# -t: 指定秘钥算法
# -b: 秘钥长度
# -C: 注释
# -f: 生成的秘钥对文件名
ssh-keygen -q -t rsa -b 4096 -C 'zhushiyang@ops.com' -f /root/.ssh/id_rsa -P ''

然后准备ipfile.list文件,每行一个IP地址

# 这里要更新地址,10.0.1.68是不存在的地址
cat >ipfile.list << EOF
10.0.1.68
10.0.1.66
EOF

脚本内容

文件名:ssh_distribution.sh

#!/bin/bash
#######################################
# 脚本名称:  ssh_distribution.sh 
# 脚本版本:  v1.0
# 功能描述:  ssh秘钥批量自动分发
# 参数说明:  sh ssh_distribution.sh
# 核心逻辑:  从文件中读取IP地址,先检测
#            连通性,然后进行秘钥分发 
# 依赖工具:  sshpass|ssh-copy-id|ssh-keygen
# 脚本作者:  shiyang.zhu
# 联系邮箱:  zhushiyang@ops.com
# 创建时间:  2023-03-13
#######################################

#######################################
# 全局变量:
#   SCRIPT_DIR         脚本所在目录
#   SCRIPT_NAME        脚本名称
#   LOG_DIR            日志目录
#   LOG_FILE           日志文件
#   IP_FILE            每行一个IP地址
#   CMD_SSHCOPYID      ssh-copy-id命令
#   SSH_PUBLIC_KEY     ssh公钥
#   SSH_PORT           ssh端口
#   SSH_PASS           ssh密码
#######################################
SCRIPT_DIR=$(dirname $(readlink -f "$0"))
SCRIPT_NAME="$0"
LOG_DIR=/var/log/shell/${SCRIPT_NAME}
LOG_FILE=${LOG_DIR}/$(date +%Y-%m-%d).log
IP_FILE="${SCRIPT_DIR}/ipfile.list"
CMD_SSHCOPYID="/usr/bin/ssh-copy-id"
CMD_SSHPASS="/usr/bin/sshpass"
SSH_PUBLIC_KEY="/root/.ssh/id_rsa.pub"
SSH_PORT="22"
SSH_PASS="toor"


[ ! -d ${LOG_DIR} ] && mkdir -p ${LOG_DIR}

# 错误日志函数
function err_log() {
    echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: [ERROR] $@" |tee -a ${LOG_FILE}
}

# 正常日志函数
function log(){
    echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: [INFO] $@" |tee -a ${LOG_FILE}
}


#######################################
# 依赖命令检查函数
# 局部变量:
#   CMDS: 依赖命令列表,使用空格分隔
#######################################
function check_cmd(){
    local CMDS="sshpass"
    for CMD in ${CMDS};do
        local CHECK_RESULT=$(rpm -qa ${CMD}|wc -l)
        if [[ ${CHECK_RESULT} -eq 0 ]];then
            err_log "${CMD}命令不存在,请手动进行安装: yum install -y ${CMD}!"
        fi
    done
}

check_cmd

# 判断${IP_FILE}是否存在
if [ ! -f ${IP_FILE} ];then
    err_log "${IP_FILE}不存在"
    exit 1
fi

# 判断${SSH_PUBLIC_KEY}是否存在
if [ ! -f ${SSH_PUBLIC_KEY} ];then
    err_log "${SSH_PUBLIC_KEY}不存在"
    exit 1
fi

#######################################
# SSH秘钥批量自动分发
# 局部变量:
#   IPADDR:            IP地址
#   CHECK_RESULT_CODE: 探活状态码
#   DIST_RESULT_CODE:  分发结果
#######################################
function sshDistribution(){
    local IPADDR="$1"
    local CHECK_RESULT_CODE=$(ping -c 2 ${IPADDR} >/dev/null;echo $?)
    if [ "${CHECK_RESULT_CODE}" = "0" ];then
        # -i: 公钥文件
        # -p: SSH端口号
        # -o stricthostkeychecking=no: 关闭首次Yes检查
        local DIST_RESULT_CODE=$("${CMD_SSHPASS}" -p "${SSH_PASS}" "${CMD_SSHCOPYID}" -i "${SSH_PUBLIC_KEY}" \
            -p "${SSH_PORT}" -o "stricthostkeychecking=no" root@${IPADDR} >/dev/null 2>&1; echo $?)
        if [ "${DIST_RESULT_CODE}" = "0" ];then
            log "主机${IPADDR}秘钥分发成功"
        else
            err_log "主机${IPADDR}秘钥分发失败"
        fi
    else
        err_log "${IPADDR}无法连通"
        continue
    fi
}

# 遍历IP进行秘钥分发
for i in `cat ${IP_FILE}|xargs`
do
    sshDistribution ${i}
done

预期结果

执行sh ssh_distribution.sh命令

正常情况下,出现如下提示,日志文件存放在/var/log/shell/ssh_distribution.sh/年-月-日.log

然后使用ssh root@10.0.1.66进行登录

当仅不存在ipfile.list文件时,出现如下报错

当仅不存在ssh秘钥文件时,出现如下报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值