219 lines
6.0 KiB
Bash
219 lines
6.0 KiB
Bash
#!/bin/bash
|
||
|
||
# 完全自动化SSH密钥部署脚本
|
||
# 功能:一键生成通用SSH密钥并自动部署到当前服务器
|
||
# 特性:
|
||
# 1. 完全自动化,无需任何交互
|
||
# 2. 生成通用密钥对,固定密码88888888
|
||
# 3. 自动将公钥部署到当前服务器的authorized_keys
|
||
# 4. 自动加固SSH配置(禁用密码登录)
|
||
# 5. 生成的密钥可在多台服务器上通用
|
||
|
||
# 配置参数
|
||
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'
|
||
NC='\033[0m'
|
||
|
||
# 日志函数
|
||
log() {
|
||
echo -e "$(date '+%Y-%m-%d %H:%M:%S') $1"
|
||
}
|
||
|
||
# 安装必要依赖
|
||
install_deps() {
|
||
log "${YELLOW}检查系统依赖...${NC}"
|
||
local pkgs=(ssh-keygen ssh sshpass expect)
|
||
local missing=()
|
||
|
||
for pkg in "${pkgs[@]}"; do
|
||
if ! command -v "$pkg" &>/dev/null; then
|
||
missing+=("$pkg")
|
||
fi
|
||
done
|
||
|
||
if [ ${#missing[@]} -gt 0 ]; then
|
||
log "${YELLOW}正在安装依赖: ${missing[*]}${NC}"
|
||
if command -v apt-get &>/dev/null; then
|
||
apt-get update -qq && apt-get install -y -qq "${missing[@]}" >/dev/null || {
|
||
log "${RED}依赖安装失败${NC}"
|
||
return 1
|
||
}
|
||
elif command -v yum &>/dev/null; then
|
||
yum install -y -q "${missing[@]}" >/dev/null || {
|
||
log "${RED}依赖安装失败${NC}"
|
||
return 1
|
||
}
|
||
else
|
||
log "${RED}不支持的包管理器${NC}"
|
||
return 1
|
||
fi
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
# 生成SSH密钥
|
||
generate_key() {
|
||
log "${YELLOW}正在生成SSH密钥...${NC}"
|
||
|
||
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"
|
||
|
||
log "${GREEN}SSH密钥生成成功${NC}"
|
||
return 0
|
||
}
|
||
|
||
# 部署公钥到本机
|
||
deploy_key_locally() {
|
||
log "${YELLOW}正在部署公钥到本机...${NC}"
|
||
|
||
mkdir -p "$BACKUP_DIR"
|
||
|
||
# 备份原密钥
|
||
if [ -f "${KEY_DIR}/authorized_keys" ]; then
|
||
cp "${KEY_DIR}/authorized_keys" "${BACKUP_DIR}/authorized_keys.bak" || {
|
||
log "${RED}authorized_keys备份失败${NC}"
|
||
}
|
||
fi
|
||
|
||
# 添加新公钥
|
||
if [ -f "${KEY_DIR}/${KEY_NAME}.pub" ]; then
|
||
mkdir -p "${KEY_DIR}"
|
||
touch "${KEY_DIR}/authorized_keys"
|
||
chmod 600 "${KEY_DIR}/authorized_keys"
|
||
|
||
# 检查是否已存在相同公钥
|
||
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
|
||
|
||
return 0
|
||
}
|
||
|
||
# 安全加固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() {
|
||
# 安装依赖
|
||
install_deps || {
|
||
log "${RED}依赖安装失败,退出脚本${NC}"
|
||
exit 1
|
||
}
|
||
|
||
# 生成密钥
|
||
generate_key || {
|
||
log "${RED}密钥生成失败,退出脚本${NC}"
|
||
exit 1
|
||
}
|
||
|
||
# 部署到本机
|
||
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
|