配置服务器 SSH 免密登录
# 配置服务器 SSH 免密登录
在日常开发和运维工作中,频繁通过 SSH 连接到远程服务器时,每次都输入密码是一件繁琐的事情。本文将详细介绍如何配置 SSH 免密登录,让你可以一键快速连接到服务器,提升工作效率。
## 一、什么是 SSH 免密登录?
SSH 免密登录(SSH Key Authentication)是一种基于密钥对的认证方式,使用一对密钥——**公钥(Public Key)** 和 **私钥(Private Key)**——来完成身份验证,而无需手动输入密码。
其核心原理:
- **公钥**:可以公开给任何人,放在目标服务器上。
- **私钥**:保留在本地机器上,绝不能泄露给他人。
当发起 SSH 连接时,服务器用公钥加密一个随机挑战值,本地机器用私钥解密后返回结果,服务器验证正确即视为认证通过。
## 二、配置步骤
### 步骤 1:生成 SSH 密钥对
打开终端(macOS / Linux)或 Git Bash(Windows),执行以下命令:
```bash
ssh-keygen -t ed25519 -C "your_email@example.com"
```
> **说明:**
> - `-t ed25519`:指定密钥类型为 Ed25519(推荐,安全性高且密钥较短)。也可以使用 `-t rsa -b 4096`。
> - `-C`:添加注释(通常填邮箱),方便标识密钥的用途。
执行后会提示你选择保存路径和设置密码:
```
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/yourname/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```
- 保存路径通常直接按回车接受默认值(`~/.ssh/id_ed25519`)。
- 如果希望免密且省去输入密钥密码的环节,passphrase 直接留空即可。但生产环境建议设置 passphrase 以提高安全性。
### 步骤 2:将公钥复制到远程服务器
生成密钥对后,你可以通过以下任一方式将公钥(`id_ed25519.pub`)复制到目标服务器。
**方法 A:使用 `ssh-copy-id`(推荐)**
```bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub 用户名@服务器IP
```
输入一次服务器密码后,公钥会自动追加到服务器 `~/.ssh/authorized_keys` 文件中。
**方法 B:手动复制**
```bash
# 本地查看公钥内容
cat ~/.ssh/id_ed25519.pub
# SSH 登录到服务器
ssh 用户名@服务器IP
# 在服务器上执行以下命令:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "你的公钥内容" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
```
### 步骤 3:测试免密登录
配置完成后,尝试直接登录服务器:
```bash
ssh 用户名@服务器IP
```
如果配置正确,你应该可以直接进入服务器,无需输入密码。
## 三、可选配置
### 3.1 配置 SSH 别名(简化命令)
编辑本地 `~/.ssh/config` 文件,添加以下配置:
```
Host myserver
HostName 服务器IP
User 用户名
Port 22
IdentityFile ~/.ssh/id_ed25519
```
之后只需执行 `ssh myserver` 即可快速连接:
```bash
ssh myserver
```
### 3.2 服务器端安全加固
在服务器上编辑 `/etc/ssh/sshd_config`,可以进一步优化安全性:
```bash
# 禁止 root 用户直接登录
PermitRootLogin no
# 禁止密码仅用密码登录(确认免密登录正常后再开启!)
PasswordAuthentication no
# 仅允许密钥认证
PubkeyAuthentication yes
```
修改后重启 SSH 服务:
```bash
# Ubuntu / Debian
sudo systemctl restart ssh
# CentOS / RHEL
sudo systemctl restart sshd
```
> ⚠️ **重要提醒**:在将 `PasswordAuthentication` 设为 `no` 之前,请务必确认你的 SSH 免密登录已经正常工作!否则可能将自己锁在服务器之外。
### 3.3 管理多个密钥
如果你有多个服务器或平台(如 GitHub、GitLab、不同云厂商),可以为它们生成不同的密钥对:
```bash
ssh-keygen -t ed25519 -C "github_account" -f ~/.ssh/id_ed25519_github
ssh-keygen -t ed25519 -c "server_production" -f ~/.ssh/id_ed25519_production
```
然后在 `~/.ssh/config` 中分别为不同 Host 指定对应的密钥:
```
Host github.com
IdentityFile ~/.ssh/id_ed25519_github
Host prod-server
HostName 192.168.1.100
User deploy
IdentityFile ~/.ssh/id_ed25519_production
```
## 四、常见问题排查
### 问题 1:配置后仍需输入密码
检查以下几个常见原因:
```bash
# 1. 确认服务器 authorized_keys 权限正确
ssh 用户名@服务器IP "ls -la ~/.ssh/"
# 正确权限:
# drwx------ (700) for ~/.ssh
# -rw------- (600) for ~/.ssh/authorized_keys
# 2. 确认公钥已正确追加
ssh 用户名@服务器IP "cat ~/.ssh/authorized_keys"
# 3. 查看服务器 SSH 日志(Ubuntu)
sudo tail -f /var/log/auth.log
# 4. 本地使用 verbose 模式排查
ssh -vvv 用户名@服务器IP
```
### 问题 2:Permission denied (publickey)
- 确认 `~/.ssh` 目录权限为 `700`,`authorized_keys` 权限为 `600`。
- 确认公钥没有换行断裂或被截断。
- 确认服务器 `sshd_config` 中 `PubkeyAuthentication yes` 已启用。
### 问题 3:ssh-copy-id 命令不存在
macOS 上如果没有 `ssh-copy-id`,可以先安装:
```bash
brew install ssh-copy-id
```
## 五、安全建议
1. **私钥严格保密**:`~/.ssh/` 目录下的私钥文件绝不上传到 GitHub 或任何公开平台。
2. **使用 passphrase 保护密钥**:虽然设置了 passphrase 后不再算是"完全免密",但安全性大幅提升,可以通过 SSH Agent 来缓存减少输入。
3. **定期轮换密钥**:建议定期更换 SSH 密钥,特别是在怀疑密钥可能泄露时。
4. **生产环境禁用密码认证**:确认免密登录正常后,关闭密码登录以防御暴力破解。
5. **使用 SSH Agent**:在本地可以通过 `ssh-add` 将密钥加入 Agent,会话期间只需输入一次 passphrase。
```bash
# 将密钥添加到 SSH Agent
ssh-add ~/.ssh/id_ed25519
# 查看已添加的密钥
ssh-add -l
```
## 六、总结
| 步骤 | 命令 |
|------|------|
| 生成密钥对 | `ssh-keygen -t ed25519 -C "email"` |
| 复制公钥到服务器 | `ssh-copy-id user@host` |
| 测试连接 | `ssh user@host` |
配置完成后,不仅日常 SSH 登录更加便捷,基于 SSH 的 Git 操作(Git Clone、Push、Pull)、`scp` 文件传输、`rsync` 同步等也都能自动完成认证,大幅提升工作效率。