Shell脚本如何配置SSH密钥登录

wen 实用脚本 2

如何配置SSH密钥登录:Shell脚本自动化实战指南

目录导读

  1. SSH密钥认证原理与优势
  2. 基础配置步骤详解
  3. Shell脚本自动化配置方案
  4. 批量配置与安全加固策略
  5. 常见问题与解答(FAQ)
  6. 企业级最佳实践建议

SSH密钥认证原理与优势

在深入Shell脚本配置之前,必须理解SSH密钥认证的核心机制,与传统密码认证不同,密钥对由私钥(位于客户端,需严格保密)和公钥(部署到服务器)组成,认证时,服务器使用公钥加密挑战数据,客户端用私钥解密,整个过程无需传输密码。

Shell脚本如何配置SSH密钥登录

主要优势:

  • 防御暴力破解:密钥长度通常2048位以上,穷举难度极高
  • 自动化友好:脚本无需处理密码交互,支持免密登录
  • 集中权限管理:通过公钥分发即可控制访问权限
  • 审计追踪:结合~/.ssh/authorized_keys日志,可追踪具体用户行为

基础配置步骤详解

1 生成密钥对

ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa_server

参数说明:

  • -t rsa:指定算法(支持rsa/ed25519)
  • -b 4096:位长度(推荐4096)
  • -C:注释标记
  • -f:指定文件名,避免覆盖默认密钥

2 上传公钥到服务器

传统方式使用ssh-copy-id

ssh-copy-id -i ~/.ssh/id_rsa_server.pub user@server_ip

该命令自动将公钥追加到服务器的~/.ssh/authorized_keys文件,并设置正确权限(600)。

3 服务端配置优化

编辑/etc/ssh/sshd_config

PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
PermitRootLogin prohibit-password

配置后重启服务:sudo systemctl restart sshd


Shell脚本自动化配置方案

1 一键生成并部署密钥(交互式脚本)

#!/bin/bash
# 脚本名称: configure_ssh_key.sh
# 功能: 自动生成密钥对并部署到远程服务器
set -e
# 颜色输出定义
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
# 检查依赖
command -v ssh-keygen >/dev/null 2>&1 || { echo "$RED Error: ssh-keygen not found $NC"; exit 1; }
# 输入参数
read -p "输入远程服务器IP: " SERVER_IP
read -p "输入用户名: " USERNAME
read -p "密钥文件名(默认id_rsa_custom): " KEY_NAME
KEY_NAME=${KEY_NAME:-id_rsa_custom}
# 生成密钥(非交互模式)
echo -e "${GREEN}正在生成密钥对...${NC}"
ssh-keygen -t rsa -b 4096 -f "$HOME/.ssh/$KEY_NAME" -N "" -C "auto-key-$(date +%Y%m%d)" <<< y
# 部署公钥
echo -e "${GREEN}正在部署公钥到 $SERVER_IP ...${NC}"
ssh-copy-id -i "$HOME/.ssh/${KEY_NAME}.pub" "$USERNAME@$SERVER_IP" 2>&1 || {
    echo -e "${RED}部署失败,请检查网络或密码${NC}"
    exit 1
}
# 创建SSH配置文件简化登录
cat >> "$HOME/.ssh/config" << EOF
Host $SERVER_IP
    HostName $SERVER_IP
    User $USERNAME
    IdentityFile ~/.ssh/$KEY_NAME
    IdentitiesOnly yes
EOF
echo -e "${GREEN}部署完成!测试连接:ssh $USERNAME@$SERVER_IP${NC}"

2 非交互式批量配置脚本(生产环境)

#!/bin/bash
# 用途:通过密码自动批量部署密钥
PASSWORDS_FILE="servers.txt"
# servers.txt格式:ip user password
# 10.0.0.1 root MyP@ss123
# 10.0.0.2 admin Secure_456
while IFS= read -r line; do
    IP=$(echo $line | awk '{print $1}')
    USER=$(echo $line | awk '{print $2}')
    PASS=$(echo $line | awk '{print $3}')
    # 使用expect处理交互式密码输入
    expect <<-EOF
        spawn ssh-copy-id -i ~/.ssh/deploy_key.pub $USER@$IP
        expect {
            "password:" { send "$PASS\r"; exp_continue }
            "yes/no" { send "yes\r"; exp_continue }
            eof
        }
    EOF
    # 禁用密码登录
    ssh "$USER@$IP" "sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config && sudo systemctl restart sshd"
done < "$PASSWORDS_FILE"

重要提示:生产环境建议使用Ansible等工具代替expect,密码明文存储存在安全风险。


批量配置与安全加固策略

1 基于主机的访问控制

authorized_keys文件中,可通过from=限制来源IP:

echo 'from="192.168.1.0/24,10.0.0.5" ssh-rsa AAAA... comment' >> ~/.ssh/authorized_keys

2 多因素认证叠加

密钥认证可配合sshguardfail2ban使用:

sudo apt install fail2ban -y
sudo systemctl enable fail2ban

3 密钥轮换自动化脚本

#!/bin/bash
# 每90天自动轮换密钥
if [ $(date +%s) -gt $(cat ~/.ssh/last_rotation 2>/dev/null || echo 0) ]; then
    ssh-keygen -t ed25519 -f ~/.ssh/rotated_key -N "" -C "rotation-$(date +%Y%m%d)"
    scp ~/.ssh/rotated_key.pub user@server_ip:~/.ssh/authorized_keys_new
    ssh user@server_ip "cat ~/.ssh/authorized_keys_new > ~/.ssh/authorized_keys && rm ~/.ssh/authorized_keys_new"
    date +%s > ~/.ssh/last_rotation
fi

常见问题与解答(FAQ)

Q1:部署密钥后仍然需要输入密码? A:检查以下问题:

  • 客户端:确认ssh -v user@ip输出中使用了正确密钥
  • 服务端:检查~/.ssh/authorized_keys权限(应为600),父目录~/.ssh权限(应为700)
  • SELinux/AppArmor:查看ausearch -m AVCjournalctl -u sshd

Q2:如何同时配置多台服务器的免密登录? A:使用ssh-agent加载私钥,或通过~/.ssh/config为不同服务器指定不同密钥:

Host server1
   HostName 10.0.0.1
   IdentityFile ~/.ssh/key1
Host server2
   HostName 10.0.0.2
   IdentityFile ~/.ssh/key2

Q3:Ed25519算法比RSA更好吗? A:Ed25519提供更高安全级别和更快的签名速度(约5x),且密钥更短,推荐首选ed25519,但需确保服务端支持(OpenSSH 6.5+),旧系统可保留RSA兼容。

Q4:密钥泄露后如何紧急处理? A:立即执行:

  1. authorized_keys移除对应公钥
  2. 更新防火墙临时限制来源IP
  3. 使用ssh-keygen -R hostname清除客户端known_hosts
  4. 检查/var/log/secure/var/log/auth.log确认未发生入侵

Q5:脚本执行时报"Permission denied (publickey)"? A:常见原因:

  • 公钥未正确追加(需逐行写入,避免多余空格)
  • 服务器SSH配置中PubkeyAuthentication未启用
  • 使用-i参数未指定正确的私钥路径
  • 文件权限错误:chmod 600 ~/.ssh/authorized_keys

企业级最佳实践建议

1 堡垒机集成方案

通过跳板机统一管理密钥分发:

# 在跳板机配置sshd_config
ForceCommand /usr/local/bin/key_audit.sh
# 该脚本记录所有SSH Session的Start/End时间及执行命令

2 使用证书认证替代原始密钥

部署OpenSSH证书中心:

# CA签发用户证书
ssh-keygen -s ca_key -I "user_id" -n "user1,user2" -V "+52w" user_key.pub
# 服务端信任证书
echo "TrustedUserCAKeys /etc/ssh/ca.pub" >> /etc/ssh/sshd_config

证书认证可精确控制有效期、允许命令等。

3 监控与审计脚本

#!/bin/bash
# 检查所有用户的authorized_keys异常条目
for user in $(awk -F: '$7 ~ /bash|sh/ {print $1}' /etc/passwd); do
    if [ -f "/home/$user/.ssh/authorized_keys" ]; then
        echo "=== $user ==="
        cat /home/$user/.ssh/authorized_keys | grep -vE "^(#|$)"
    fi
done > /var/log/ssh_key_audit_$(date +%Y%m%d).log

4 部署检查清单

  • [ ] 所有服务器禁用PasswordAuthentication
  • [ ] 密钥至少2048位RSA或256位ED25519
  • [ ] 私钥存储于HSM或加密卷
  • [ ] 每90天自动轮换一次密钥
  • [ ] 堡垒机记录所有SSH会话
  • [ ] fail2ban配置5次失败后封禁1小时

通过以上Shell脚本方案,您能快速实现SSH密钥认证的自动化部署,从单机配置到企业级批量管理,关键在于坚持最小权限原则定期审计,建议将本文脚本纳入CI/CD管道,结合基础设施即代码工具(Terraform/Ansible)实现完全自动化的安全运维。

抱歉,评论功能暂时关闭!