From 057cbbae8bcf8a2440335d64ddd5347c8e4a96f2 Mon Sep 17 00:00:00 2001 From: xzx3344521 Date: Sun, 16 Nov 2025 15:39:34 +0800 Subject: [PATCH] =?UTF-8?q?Update=20SSH=E5=AF=86=E9=92=A5=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E5=8F=8A=E5=AE=89=E5=85=A8=E5=8A=A0=E5=9B=BA=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SSH密钥部署及安全加固脚本 | 354 +++++++++++++++++--------------------- 1 file changed, 156 insertions(+), 198 deletions(-) diff --git a/SSH密钥部署及安全加固脚本 b/SSH密钥部署及安全加固脚本 index 0bfbe54..777a5f9 100644 --- a/SSH密钥部署及安全加固脚本 +++ b/SSH密钥部署及安全加固脚本 @@ -1,52 +1,59 @@ #!/bin/bash -# SSH密钥部署及安全加固脚本 -# 功能: -# 1. 自动生成SSH密钥对(默认密码:88888888) -# 2. 部署公钥到多台服务器 -# 3. 安全加固:禁用密码登录(仅在所有密钥部署验证成功后) -# 4. 提供回滚机制防止锁定 +# 完全自动化SSH密钥部署脚本 +# 功能:一键生成通用SSH密钥并自动部署到当前服务器 +# 特性: +# 1. 完全自动化,无需任何交互 +# 2. 生成通用密钥对,固定密码88888888 +# 3. 自动将公钥部署到当前服务器的authorized_keys +# 4. 自动加固SSH配置(禁用密码登录) +# 5. 生成的密钥可在多台服务器上通用 # 配置参数 -KEY_DIR="$HOME/.ssh" # 密钥存放目录 -KEY_NAME="auto_key" # 密钥名称 -KEY_PASSWORD="88888888" # 固定密钥密码 -KEY_TYPE="ed25519" # 默认使用更安全的Ed25519算法 -SSH_PORT="22" # 默认SSH端口 -TEMP_BACKUP="/tmp/ssh_backup" # 临时备份目录 -LOCKFILE="/tmp/ssh_secure.lock" # 安全操作锁文件 +KEY_DIR="$HOME/.ssh" +KEY_NAME="universal_ssh_key" +KEY_PASS="88888888" +KEY_TYPE="ed25519" +SSH_PORT="22" +BACKUP_DIR="/tmp/ssh_setup_backup_$(date +%s)" # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color +NC='\033[0m' -# 检查并安装依赖 +# 日志函数 +log() { + echo -e "$(date '+%Y-%m-%d %H:%M:%S') $1" +} + +# 安装必要依赖 install_deps() { - local deps=(ssh-keygen ssh sshpass expect) + log "${YELLOW}检查系统依赖...${NC}" + local pkgs=(ssh-keygen ssh sshpass expect) local missing=() - for dep in "${deps[@]}"; do - if ! command -v "$dep" &>/dev/null; then - missing+=("$dep") + for pkg in "${pkgs[@]}"; do + if ! command -v "$pkg" &>/dev/null; then + missing+=("$pkg") fi done if [ ${#missing[@]} -gt 0 ]; then - echo -e "${YELLOW}正在安装依赖: ${missing[*]}${NC}" - + log "${YELLOW}正在安装依赖: ${missing[*]}${NC}" if command -v apt-get &>/dev/null; then apt-get update -qq && apt-get install -y -qq "${missing[@]}" >/dev/null || { - echo -e "${RED}依赖安装失败${NC}"; return 1 + log "${RED}依赖安装失败${NC}" + return 1 } elif command -v yum &>/dev/null; then yum install -y -q "${missing[@]}" >/dev/null || { - echo -e "${RED}依赖安装失败${NC}"; return 1 + log "${RED}依赖安装失败${NC}" + return 1 } else - echo -e "${RED}不支持的包管理器,请手动安装: ${missing[*]}${NC}" + log "${RED}不支持的包管理器${NC}" return 1 fi fi @@ -55,206 +62,157 @@ install_deps() { # 生成SSH密钥 generate_key() { - echo -e "${BLUE}正在生成${NC} ${YELLOW}${KEY_TYPE}${NC} ${BLUE}类型SSH密钥...${NC}" + log "${YELLOW}正在生成SSH密钥...${NC}" - [ -d "$KEY_DIR" ] || mkdir -p "$KEY_DIR" - chmod 700 "$KEY_DIR" - - ssh-keygen -t "$KEY_TYPE" -C "auto-deploy-key" -N "$KEY_PASSWORD" -f "${KEY_DIR}/${KEY_NAME}" -q || { - echo -e "${RED}密钥生成失败${NC}"; return 1 + mkdir -p "$KEY_DIR" || { + log "${RED}无法创建SSH目录${NC}" + return 1 } - + + # 生成新密钥 + ssh-keygen -t "$KEY_TYPE" -C "universal_auto_key" -N "$KEY_PASS" -f "${KEY_DIR}/${KEY_NAME}" -q || { + log "${RED}密钥生成失败${NC}" + return 1 + } + + # 设置正确权限 + chmod 700 "$KEY_DIR" chmod 600 "${KEY_DIR}/${KEY_NAME}" chmod 644 "${KEY_DIR}/${KEY_NAME}.pub" - echo -e "${GREEN}密钥生成成功:${NC}" - echo -e "私钥: ${KEY_DIR}/${KEY_NAME}" - echo -e "公钥: ${KEY_DIR}/${KEY_NAME}.pub" + log "${GREEN}SSH密钥生成成功${NC}" return 0 } -# 测试密钥登录 -test_key_login() { - local server="$1" - local user="${2:-root}" +# 部署公钥到本机 +deploy_key_locally() { + log "${YELLOW}正在部署公钥到本机...${NC}" - echo -e "${BLUE}测试密钥登录 ${user}@${server}...${NC}" + mkdir -p "$BACKUP_DIR" - if ! ssh -i "${KEY_DIR}/${KEY_NAME}" -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o ConnectTimeout=5 \ - "${user}@${server}" "echo -n" >/dev/null 2>&1; then - echo -e "${RED}密钥登录测试失败 - ${user}@${server}${NC}" - return 1 + # 备份原密钥 + if [ -f "${KEY_DIR}/authorized_keys" ]; then + cp "${KEY_DIR}/authorized_keys" "${BACKUP_DIR}/authorized_keys.bak" || { + log "${RED}authorized_keys备份失败${NC}" + } fi - echo -e "${GREEN}密钥登录测试成功 - ${user}@${server}${NC}" - return 0 -} - -# 部署公钥到服务器 -deploy_key() { - local server="$1" - local user="${2:-root}" - local port="${3:-22}" - - echo -e "${BLUE}正在部署到 ${user}@${server}:${port}...${NC}" - - # 备份原authorized_keys - sshpass -p "$KEY_PASSWORD" ssh -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "[ -f ~/.ssh/authorized_keys ] && cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak" 2>/dev/null - - # 部署新密钥 - if ! sshpass -p "$KEY_PASSWORD" ssh -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "mkdir -p ~/.ssh && chmod 700 ~/.ssh && \ - grep -q \"\$(cat ${KEY_DIR}/${KEY_NAME}.pub)\" ~/.ssh/authorized_keys 2>/dev/null || \ - cat ${KEY_DIR}/${KEY_NAME}.pub >> ~/.ssh/authorized_keys && \ - chmod 600 ~/.ssh/authorized_keys" 2>/dev/null; then - echo -e "${RED}公钥部署失败 - ${user}@${server}${NC}" - return 1 - fi - - # 验证部署 - if ! test_key_login "$server" "$user"; then - echo -e "${RED}部署验证失败 - ${user}@${server}${NC}" - # 尝试回滚 - sshpass -p "$KEY_PASSWORD" ssh -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "[ -f ~/.ssh/authorized_keys.bak ] && mv -f ~/.ssh/authorized_keys.bak ~/.ssh/authorized_keys" 2>/dev/null - return 1 - fi - - echo -e "${GREEN}成功部署到 ${user}@${server}${NC}" - return 0 -} - -# 安全加固 - 禁用密码登录 -secure_server() { - local server="$1" - local user="${2:-root}" - local port="${3:-22}" - - # 创建锁文件防止重复操作 - touch "$LOCKFILE" - echo -e "${YELLOW}正在安全加固 ${user}@${server}...${NC}" - - # 备份原sshd配置 - ssh -i "${KEY_DIR}/${KEY_NAME}" -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak" || { - echo -e "${RED}配置备份失败 - ${user}@${server}${NC}"; return 1 - } - - # 修改配置禁用密码登录 - ssh -i "${KEY_DIR}/${KEY_NAME}" -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "sudo sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config && \ - sudo sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config && \ - sudo systemctl reload sshd" || { - echo -e "${RED}安全配置失败 - ${user}@${server}${NC}" + # 添加新公钥 + if [ -f "${KEY_DIR}/${KEY_NAME}.pub" ]; then + mkdir -p "${KEY_DIR}" + touch "${KEY_DIR}/authorized_keys" + chmod 600 "${KEY_DIR}/authorized_keys" - # 尝试回滚 - ssh -i "${KEY_DIR}/${KEY_NAME}" -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "sudo mv -f /etc/ssh/sshd_config.bak /etc/ssh/sshd_config && sudo systemctl reload sshd" 2>/dev/null - return 1 - } - - # 二次验证 - if ! test_key_login "$server" "$user"; then - echo -e "${RED}安全加固后验证失败 - 正在回滚${NC}" - ssh -i "${KEY_DIR}/${KEY_NAME}" -o StrictHostKeyChecking=no -p "$port" "${user}@${server}" \ - "sudo mv -f /etc/ssh/sshd_config.bak /etc/ssh/sshd_config && sudo systemctl reload sshd" 2>/dev/null + # 检查是否已存在相同公钥 + if ! grep -q "$(cat "${KEY_DIR}/${KEY_NAME}.pub")" "${KEY_DIR}/authorized_keys"; then + cat "${KEY_DIR}/${KEY_NAME}.pub" >> "${KEY_DIR}/authorized_keys" || { + log "${RED}公钥添加失败${NC}" + return 1 + } + log "${GREEN}公钥已添加到本机${NC}" + else + log "${YELLOW}相同公钥已存在,跳过添加${NC}" + fi + else + log "${RED}公钥文件不存在${NC}" return 1 fi - echo -e "${GREEN}安全加固成功 - ${user}@${server}${NC}" return 0 } -# 显示帮助 -show_help() { - echo -e "${BLUE}使用说明:${NC}" - echo "1. 仅生成密钥: $0" - echo "2. 生成并部署到服务器: $0 [用户名] 服务器1 [服务器2 ...] [端口]" - echo -e "\n${YELLOW}示例:${NC}" - echo "生成密钥: $0" - echo "部署到多台服务器: $0 root server1.example.com server2.example.com 22" +# 安全加固SSH配置 +secure_ssh() { + log "${YELLOW}正在加固SSH配置...${NC}" + + # 备份原配置 + cp /etc/ssh/sshd_config "${BACKUP_DIR}/sshd_config.bak" || { + log "${RED}sshd_config备份失败${NC}" + return 1 + } + + # 应用安全配置 + sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config + sed -i 's/^#*PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config + sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config + + # 重新加载SSH服务 + if systemctl reload sshd >/dev/null 2>&1 || service sshd reload >/dev/null 2>&1; then + log "${GREEN}SSH配置已更新并重载${NC}" + else + log "${RED}SSH服务重载失败,正在回滚...${NC}" + cp "${BACKUP_DIR}/sshd_config.bak" /etc/ssh/sshd_config + return 1 + fi + + return 0 +} + +# 验证部署 +verify_deployment() { + log "${YELLOW}验证密钥登录...${NC}" + + # 测试本地密钥登录 + if ssh -i "${KEY_DIR}/${KEY_NAME}" -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o ConnectTimeout=5 localhost "echo 连接测试成功" >/dev/null 2>&1; then + log "${GREEN}密钥登录验证成功${NC}" + return 0 + else + log "${RED}密钥登录验证失败${NC}" + return 1 + fi +} + +# 显示成功信息 +show_success() { + echo -e "\n${GREEN}✔ SSH密钥部署成功!${NC}" + echo -e "==============================" + echo -e "${YELLOW}重要信息:${NC}" + echo -e "密钥路径: ${KEY_DIR}/${KEY_NAME}" + echo -e "密钥密码: ${KEY_PASS}" + echo -e "\n${YELLOW}使用说明:${NC}" + echo -e "1. 此密钥可在其他服务器上使用相同方法部署" + echo -e "2. 连接到其他服务器时使用:" + echo -e " ssh -i ${KEY_DIR}/${KEY_NAME} 用户名@服务器IP" + echo -e "3. 需要输入密钥密码时使用: ${KEY_PASS}" + echo -e "\n${RED}⚠ 请确保在其他服务器部署前先备份现有密钥${NC}" + echo -e "==============================\n" } # 主函数 main() { - # 检查root权限 - if [ "$(id -u)" -ne 0 ]; then - echo -e "${RED}请使用root用户运行此脚本${NC}" - exit 1 - fi - # 安装依赖 - install_deps || exit 1 + install_deps || { + log "${RED}依赖安装失败,退出脚本${NC}" + exit 1 + } # 生成密钥 - generate_key || exit 1 - - # 如果没有提供服务器参数,则只生成密钥 - if [ $# -eq 0 ]; then - echo -e "${GREEN}SSH密钥已生成,但没有指定部署服务器${NC}" - show_help - exit 0 - fi - - # 解析参数 - local user="root" - local servers=() - local port="22" - - # 第一个参数可能是用户名 - if [[ "$1" != *.* ]] && [[ "$1" != *:* ]] && [[ "$1" != "root" ]]; then - user="$1" - shift - fi - - # 最后一个参数可能是端口号 - if [[ "${@: -1}" =~ ^[0-9]+$ ]]; then - port="${@: -1}" - servers=("${@:1:$#-1}") - else - servers=("$@") - fi - - # 部署到所有服务器 - local all_success=true - for server in "${servers[@]}"; do - deploy_key "$server" "$user" "$port" || { - all_success=false - echo -e "${RED}${server} 部署失败,跳过安全加固${NC}" - continue - } - done - - # 只有所有服务器都部署成功才进行安全加固 - if $all_success; then - echo -e "${YELLOW}所有服务器部署成功,开始安全加固...${NC}" - for server in "${servers[@]}"; do - secure_server "$server" "$user" "$port" || { - echo -e "${RED}${server} 安全加固失败${NC}" - all_success=false - } - done - fi - - # 清理锁文件 - rm -f "$LOCKFILE" - - # 最终状态报告 - if $all_success; then - echo -e "\n${GREEN}所有操作成功完成!${NC}" - echo -e "${YELLOW}重要信息:${NC}" - echo -e "密钥位置: ${KEY_DIR}/${KEY_NAME}" - echo -e "密钥密码: ${KEY_PASSWORD}" - echo -e "已禁用密码登录的服务器: ${servers[*]}" - echo -e "\n${BLUE}您现在可以使用密钥登录这些服务器:${NC}" - echo "ssh -i ${KEY_DIR}/${KEY_NAME} ${user}@服务器地址 -p ${port}" - else - echo -e "\n${RED}部分操作失败,请检查上述错误信息${NC}" - echo -e "${YELLOW}注意: 未成功加固的服务器仍允许密码登录${NC}" + generate_key || { + log "${RED}密钥生成失败,退出脚本${NC}" exit 1 - fi + } + + # 部署到本机 + deploy_key_locally || { + log "${RED}本地部署失败,退出脚本${NC}" + exit 1 + } + + # 安全加固 + secure_ssh || { + log "${RED}SSH加固失败,退出脚本${NC}" + exit 1 + } + + # 验证部署 + verify_deployment || { + log "${RED}部署验证失败,退出脚本${NC}" + exit 1 + } + + # 显示成功信息 + show_success } # 执行主函数 -main "$@" +main