Rocky Linux 远程连接 SSH 密钥对配置:手把手教你生成公钥私钥并设置免密登录安全攻略
引言:为什么需要配置 SSH 密钥对?
在 Rocky Linux 系统管理中,远程连接是最常见的操作之一。传统的密码认证方式虽然简单,但存在明显的安全隐患:密码容易被暴力破解、容易被键盘记录器捕获、每次登录都需要手动输入。而 SSH 密钥对认证则提供了更安全、更便捷的解决方案。
SSH 密钥对使用非对称加密技术,公钥用于验证身份,私钥用于证明身份。这种机制不仅安全性更高,还能实现真正的免密登录,极大提升运维效率。本文将详细介绍如何在 Rocky Linux 上生成 SSH 密钥对,并配置安全的免密登录环境。
第一部分:理解 SSH 密钥对的工作原理
1.1 非对称加密基础
SSH 密钥对基于非对称加密算法(通常是 RSA、ECDSA 或 Ed25519)。它包含两个部分:
- 私钥(Private Key):保存在客户端,必须严格保密,相当于你的身份证明
- 公钥(Public Key):可以公开,存放在服务器端,用于验证私钥持有者的身份
1.2 认证流程
- 客户端发起连接请求,携带公钥信息
- 服务器检查
authorized_keys文件,找到匹配的公钥 - 服务器生成一个随机数,用公钥加密后发送给客户端
- 客户端用私钥解密,将结果发回服务器
- 服务器验证解密结果,匹配则认证通过
第二部分:生成 SSH 密钥对
2.1 检查现有密钥
在生成新密钥前,先检查是否已有密钥:
# 查看现有 SSH 密钥 ls -la ~/.ssh/ # 常见的密钥文件 # id_rsa (私钥) # id_rsa.pub (公钥) # known_hosts (已知主机) # authorized_keys (授权的公钥) 2.2 生成 RSA 密钥对(推荐用于兼容性)
RSA 是最广泛支持的算法,适合需要兼容旧系统的场景:
# 生成 4096 位 RSA 密钥对 ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # 交互式过程详解: # 1. 提示输入保存路径:直接回车使用默认 ~/.ssh/id_rsa # 2. 输入密码(passphrase):可以留空(不推荐)或设置强密码 # 3. 确认密码:再次输入 参数说明:
-t rsa:指定密钥类型为 RSA-b 4096:指定密钥长度为 4096 位(安全推荐)-C "comment":添加注释,通常使用邮箱或标识符
2.3 生成 Ed25519 密钥对(推荐用于新系统)
Ed25519 是更现代、更安全的算法,性能更好:
# 生成 Ed25519 密钥对 ssh-keygen -t ed25519 -C "your_email@example.com" # 交互式过程与 RSA 相同 2.4 生成 ECDSA 密钥对
ECDSA 是另一种选择,但在某些场景下可能不如 Ed25519:
# 生成 ECDSA 密钥对 ssh-keygen -t ecdsa -b 521 -C "your_email@example.com" 2.5 批量生成(非交互式)
对于自动化脚本,可以使用非交互方式:
# 使用空密码生成密钥(不推荐用于生产) ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "" # 使用特定密码生成 ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "YourStrongPassphrase" 2.6 密钥文件权限设置
生成密钥后,必须设置正确的权限,否则 SSH 会拒绝使用:
# 设置私钥权限为 600(只有所有者可读写) chmod 600 ~/.ssh/id_rsa # 设置公钥权限为 644(所有者可读写,其他人只读) chmod 644 ~/.ssh/id_rsa.pub # 设置 .ssh 目录权限为 700 chmod 700 ~/.ssh 重要提示:权限设置错误会导致 SSH 认证失败,务必仔细检查。
第三部分:将公钥部署到 Rocky Linux 服务器
3.1 手动复制公钥(基础方法)
方法一:使用 ssh-copy-id(推荐)
# 语法:ssh-copy-id [选项] user@hostname ssh-copy-id -i ~/.ssh/id_ed25519.pub root@192.168.1.100 # 如果 SSH 端口不是 22 ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 root@192.168.1.100 ssh-copy-id 会自动完成以下操作:
- 连接远程服务器(需要输入密码)
- 创建
~/.ssh目录(如果不存在) - 将公钥追加到
~/.ssh/authorized_keys - 设置正确的权限
方法二:手动复制
如果 ssh-copy-id 不可用,可以手动操作:
# 1. 在客户端显示公钥内容 cat ~/.ssh/id_ed25519.pub # 2. 在服务器端执行(将上面的输出粘贴) mkdir -p ~/.ssh chmod 700 ~/.ssh echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys 3.2 使用 Ansible 批量部署(高级方法)
对于多台服务器,可以使用 Ansible 自动部署:
# playbook: deploy-ssh-keys.yml --- - name: Deploy SSH public keys to servers hosts: all become: yes tasks: - name: Ensure .ssh directory exists file: path: /root/.ssh state: directory mode: '0700' owner: root group: root - name: Add SSH public key authorized_key: user: root state: present key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}" 执行命令:
ansible-playbook -i inventory.ini deploy-ssh-keys.yml 3.3 使用脚本批量部署
#!/bin/bash # deploy_keys.sh SERVERS=("192.168.1.101" "192.168.1.102" "192.168.1.103") USER="root" PUBKEY="$HOME/.ssh/id_ed25519.pub" for server in "${SERVERS[@]}"; do echo "Deploying key to $server..." ssh-copy-id -i "$PUBKEY" "$USER@$server" if [ $? -eq 0 ]; then echo "✓ Success: $server" else echo "✗ Failed: $server" fi done 第四部分:测试免密登录
4.1 基本测试
# 测试连接 ssh root@192.168.1.100 # 如果配置正确,应该直接登录,无需密码 # 如果仍然要求密码,说明配置有问题 4.2 详细调试模式
如果登录失败,使用 verbose 模式诊断:
# -v:详细输出(可多次使用增加详细程度) ssh -v root@192.168.1.100 # 更详细 ssh -vvv root@192.168.1.100 调试输出会显示:
- 使用的密钥文件
- 是否找到公钥
- 服务器的响应
- 具体的错误信息
4.3 检查服务器端配置
在服务器上检查:
# 查看 authorized_keys 文件 cat ~/.ssh/authorized_keys # 检查文件权限 ls -la ~/.ssh/ # 查看 SSH 服务状态 systemctl status sshd # 查看认证日志 tail -f /var/log/secure # 或 tail -f /var/log/auth.log 第五部分:安全加固配置
5.1 禁用密码认证(关键安全步骤)
警告:在禁用密码认证前,确保密钥登录已正常工作!
编辑 SSH 服务器配置:
# 编辑配置文件 sudo vi /etc/ssh/sshd_config 修改以下参数:
# 禁用密码认证 PasswordAuthentication no # 禁用空密码 PermitEmptyPasswords no # 强制使用密钥认证 PubkeyAuthentication yes # 可选:限制可使用的用户 AllowUsers root admin # 可选:限制可使用的公钥 AuthorizedKeysFile .ssh/authorized_keys 重启 SSH 服务:
# 重启 SSH 服务 sudo systemctl restart sshd # 检查状态 sudo systemctl status sshd # 验证配置 sudo sshd -t 5.2 修改默认 SSH 端口
# 编辑配置文件 sudo vi /etc/ssh/sshd_config # 修改端口(例如改为 2222) Port 2222 # 重启服务 sudo systemctl restart sshd # 防火墙放行新端口 sudo firewall-cmd --permanent --add-port=2222/tcp sudo firewall-cmd --reload # 测试新端口连接 ssh -p 2222 root@192.168.1.100 5.3 配置 SSH 客户端配置
在客户端创建 ~/.ssh/config 文件,简化连接:
# 编辑配置文件 vi ~/.ssh/config 添加内容:
# Rocky Linux 服务器配置 Host rocky-server HostName 192.168.1.100 User root Port 22 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes # 多服务器配置示例 Host web-server HostName 192.168.1.101 User admin Port 2222 IdentityFile ~/.ssh/id_ed25519 Host db-server HostName 192.168.1.102 User postgres Port 5432 IdentityFile ~/.ssh/id_rsa 设置权限:
chmod 600 ~/.ssh/config 现在可以使用简化命令:
ssh rocky-server scp file.txt rocky-server:/tmp/ 5.4 使用 SSH 代理(ssh-agent)
对于设置了密码的私钥,可以使用 ssh-agent 避免重复输入:
# 启动 ssh-agent eval "$(ssh-agent -s)" # 添加私钥到代理 ssh-add ~/.ssh/id_ed25519 # 查看已添加的密钥 ssh-add -l # 删除特定密钥 ssh-add -d ~/.ssh/id_ed25519 # 删除所有密钥 ssh-add -D 持久化配置:在 ~/.bashrc 或 ~/.zshrc 中添加:
# 自动启动 ssh-agent if [ -z "$SSH_AUTH_SOCK" ]; then eval "$(ssh-agent -s)" > /dev/null ssh-add ~/.ssh/id_ed25519 2>/dev/null fi 5.5 限制用户和命令
在服务器端的 authorized_keys 文件中,可以添加限制:
# 限制只能执行特定命令 command="/usr/local/bin/backup.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com # 限制只能从特定 IP 连接 from="192.168.1.100",command="/usr/local/bin/backup.sh" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com # 限制端口转发 no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com 第六部分:高级配置与最佳实践
6.1 使用不同的密钥对管理不同服务器
# 生成多个密钥对 ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work -C "work@company.com" ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C "personal@gmail.com" # 在 ~/.ssh/config 中指定 Host work-server HostName 10.0.1.1 User admin IdentityFile ~/.ssh/id_ed25519_work Host personal-server HostName 192.168.1.100 User root IdentityFile ~/.ssh/id_ed25519_personal 6.2 密钥轮换策略
定期更换密钥是良好的安全实践:
# 1. 生成新密钥 ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -C "new-key-2024" # 2. 部署新公钥到服务器 ssh-copy-id -i ~/.ssh/id_ed25519_new.pub root@192.168.1.100 # 3. 测试新密钥 ssh -i ~/.ssh/id_ed25519_new root@192.168.1.100 # 4. 确认无误后,删除旧密钥 rm ~/.ssh/id_ed25519 rm ~/.ssh/id_ed25519.pub # 5. 重命名新密钥为标准名称 mv ~/.ssh/id_ed25519_new ~/.ssh/id_ed25519 mv ~/.ssh/id_ed25519_new.pub ~/.ssh/id_ed25519.pub # 6. 从服务器删除旧公钥 # 编辑 ~/.ssh/authorized_keys,删除旧的公钥行 6.3 使用证书认证(高级)
对于大规模部署,可以使用 SSH CA 签发证书:
# 1. 在 CA 服务器上生成 CA 密钥 ssh-keygen -t ed25519 -f ~/.ssh/ca_ed25519 -C "SSH CA" # 2. 为用户签发证书 ssh-keygen -s ~/.ssh/ca_ed25519 -I user1 -n root -V +52w ~/.ssh/id_ed25519.pub # 3. 在服务器上配置信任 CA # 编辑 /etc/ssh/sshd_config TrustedUserCAKeys /etc/ssh/ca_ed25519.pub # 4. 将 CA 公钥复制到服务器 sudo cp ~/.ssh/ca_ed25519.pub /etc/ssh/ca_ed25519.pub sudo chmod 644 /etc/ssh/ca_ed25519.pub 6.4 监控和审计
设置 SSH 登录监控:
# 在 /etc/ssh/sshd_config 中添加 LogLevel VERBOSE # 查看 SSH 登录日志 sudo journalctl -u sshd -f # 统计登录次数 sudo grep "Accepted" /var/log/secure | wc -l # 查找失败的登录尝试 sudo grep "Failed password" /var/log/secure 第七部分:故障排除
7.1 常见问题及解决方案
问题 1:仍然要求密码
检查清单:
# 1. 检查公钥是否正确部署 cat ~/.ssh/authorized_keys # 2. 检查权限 ls -la ~/.ssh/ # 应该是:drwx------ (700) .ssh # -rw------- (600) authorized_keys # 3. 检查 SELinux 上下文(Rocky Linux 默认启用) ls -Z ~/.ssh/authorized_keys # 应该是:unconfined_u:object_r:ssh_home_t:s0 # 如果不正确,修复: restorecon -R -v ~/.ssh 问题 2:权限被拒绝
# 检查服务器端 SELinux 状态 sestatus # 临时禁用 SELinux 测试(不推荐生产环境) setenforce 0 # 永久禁用(不推荐) # 编辑 /etc/selinux/config,设置 SELINUX=disabled 问题 3:连接超时
# 检查防火墙 sudo firewall-cmd --list-all # 检查 SSH 服务是否监听 sudo ss -tlnp | grep ssh # 测试端口连通性 telnet 192.168.1.100 22 7.2 使用 ssh -vvv 调试
详细分析调试输出:
# 执行调试连接 ssh -vvv root@192.168.1.100 # 关键输出示例: # debug1: Offering public key: /home/user/.ssh/id_ed25519 ED25519 SHA256:... # debug3: send_pubkey_test # debug3: send packet: type 50, length 82 # debug1: Server accepts key: /home/user/.ssh/id_ed25519 ED25519 SHA256:... # debug3: sign_and_send_pubkey: using public key "ED25519 SHA256:..." from agent # debug3: sign_and_send_pubkey: signing using ed25519 SHA256:... # debug3: send packet: type 50, length 68 # debug1: Authentication succeeded (publickey). 第八部分:Rocky Linux 特定配置
8.1 防火墙配置
# 查看防火墙状态 sudo firewall-cmd --state # 允许 SSH 端口(默认 22) sudo firewall-cmd --permanent --add-service=ssh sudo firewall-cmd --reload # 如果修改了端口 sudo firewall-cmd --permanent --add-port=2222/tcp sudo firewall-cmd --reload # 查看规则 sudo firewall-cmd --list-all 8.2 SELinux 配置
# 查看 SELinux 状态 sestatus # 如果遇到 SELinux 相关问题,检查上下文 ls -Z ~/.ssh/authorized_keys # 修复上下文 restorecon -R -v ~/.ssh # 查看 SELinux 日志 sudo ausearch -m avc -ts recent 8.3 使用 firewalld 的 rich rules
# 限制特定 IP 可以访问 SSH sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept' # 限制特定 IP 可以访问自定义端口 sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.1.100" port protocol="tcp" port="2222" accept' sudo firewall-cmd --reload 第九部分:生产环境最佳实践
9.1 密钥管理策略
- 使用强密码保护私钥:即使私钥泄露,也需要密码才能使用
- 定期轮换密钥:建议每 3-6 个月更换一次
- 使用不同的密钥对:生产、测试、开发环境使用不同的密钥
- 备份私钥:加密后备份到安全位置
- 立即吊销:员工离职或密钥泄露时立即从服务器删除
9.2 多因素认证
结合 SSH 密钥和 OTP(一次性密码):
# 安装 Google Authenticator sudo dnf install google-authenticator # 配置 google-authenticator # 编辑 /etc/ssh/sshd_config ChallengeResponseAuthentication yes AuthenticationMethods publickey,keyboard-interactive # 重启 SSH sudo systemctl restart sshd 9.3 审计和监控
# 创建审计脚本 cat > /usr/local/bin/ssh_audit.sh << 'EOF' #!/bin/bash # SSH 登录审计脚本 LOG_FILE="/var/log/ssh_audit.log" DATE=$(date '+%Y-%m-%d %H:%M:%S') # 记录所有 SSH 登录 echo "[$DATE] SSH Login: $PAM_USER from $SSH_CLIENT" >> $LOG_FILE # 发送告警(可选) if [ "$PAM_USER" = "root" ]; then echo "Root login detected from $SSH_CLIENT" | mail -s "SSH Alert" admin@example.com fi EOF chmod +x /usr/local/bin/ssh_audit.sh # 在 /etc/pam.d/sshd 中添加 # session optional pam_exec.so /usr/local/bin/ssh_audit.sh 第十部分:总结与维护
10.1 定期维护检查清单
#!/bin/bash # SSH 安全检查脚本 echo "=== SSH 安全检查 ===" # 1. 检查权限 echo "1. 检查权限..." find ~/.ssh -type f -exec ls -la {} ; | grep -v "600|644|700" # 2. 检查 authorized_keys 数量 echo "2. 检查授权密钥数量..." if [ -f ~/.ssh/authorized_keys ]; then echo "授权密钥数: $(wc -l < ~/.ssh/authorized_keys)" else echo "authorized_keys 文件不存在" fi # 3. 检查 SSH 服务状态 echo "3. 检查 SSH 服务..." systemctl is-active sshd # 4. 检查密码认证是否禁用 echo "4. 检查密码认证配置..." grep "^PasswordAuthentication" /etc/ssh/sshd_config # 5. 检查最近登录 echo "5. 最近登录记录..." last -n 5 echo "=== 检查完成 ===" 10.2 故障恢复
如果 SSH 配置错误导致无法连接:
# 方法 1:通过控制台访问(物理或虚拟机控制台) # 直接登录并修复配置 # 方法 2:使用备用端口 # 如果配置了多个端口,使用其他端口连接 # 方法 3:使用 rescue 模式 # 重启进入 rescue 模式,挂载根分区,修复配置 # 方法 4:使用 cron 任务自动恢复 # 在配置错误前设置 cron 任务,5分钟后恢复默认配置 echo "5 * * * * root /usr/bin/systemctl restart sshd" | sudo tee /etc/cron.d/ssh-recover 结论
SSH 密钥对配置是 Rocky Linux 系统安全管理的基础。通过本文的详细指导,你应该能够:
- ✅ 理解 SSH 密钥对的工作原理
- ✅ 生成安全的 RSA 或 Ed25519 密钥对
- ✅ 正确部署公钥到服务器
- ✅ 配置免密登录并进行测试
- ✅ 实施多项安全加固措施
- ✅ 掌握故障排除方法
- ✅ 遵循生产环境最佳实践
记住,安全是一个持续的过程。定期审查和更新你的 SSH 配置,监控登录日志,并保持对新安全威胁的警惕。通过正确配置 SSH 密钥对,你不仅提高了工作效率,更重要的是大大增强了系统的安全性。
最后提醒:在生产环境中实施任何重大变更前,务必确保有备用的访问方式(如控制台访问),并先在测试环境中验证配置的正确性。
支付宝扫一扫
微信扫一扫