
为什么使用 SSH 密钥而非密码
SSH 密码认证存在两个关键问题:密码可能被暴力破解,且容易受到钓鱼攻击。SSH 密钥解决了这两个问题:密钥对在数学上无法被暴力破解,且私钥永远不会离开你的机器。

生成 SSH 密钥
# Ed25519(推荐——比 RSA 更小、更快、更安全)
ssh-keygen -t ed25519 -C "your.email@example.com"
# RSA 4096(用于不支持 Ed25519 的系统)
ssh-keygen -t rsa -b 4096 -C "your.email@example.com"
# 提示:
# 输入文件:~/.ssh/id_ed25519(默认)或选择自定义路径
# 输入密码:请务必设置!(保护私钥以防被盗)
# 创建的文件:
# ~/.ssh/id_ed25519 ← 私钥:切勿分享!
# ~/.ssh/id_ed25519.pub ← 公钥:复制到服务器
# 查看你的公钥(复制到服务器)
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your.email@example.com
# 为不同用途创建多个密钥
ssh-keygen -t ed25519 -f ~/.ssh/id_work -C "work@company.com"
ssh-keygen -t ed25519 -f ~/.ssh/id_github -C "github@personal.com"
ssh-keygen -t ed25519 -f ~/.ssh/id_servers -C "servers-2026"
将密钥复制到服务器
# 最简单的方法(将密钥安装到服务器的 ~/.ssh/authorized_keys)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.example.com
# 手动方法(当 ssh-copy-id 不可用时)
cat ~/.ssh/id_ed25519.pub | ssh user@server 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'
# 在服务器上验证:
cat ~/.ssh/authorized_keys
# 应包含你的公钥
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

SSH 配置文件
最被低估的 SSH 功能:
# ~/.ssh/config
# 权限必须为:chmod 600 ~/.ssh/config
Host *
ServerAliveInterval 60 # 每 60 秒发送保活包
ServerAliveCountMax 3 # 连续 3 次保活失败后断开连接
ControlMaster auto # 共享连接(多个会话更快)
ControlPath ~/.ssh/cm_%h_%p_%r
ControlPersist 10m
# 开发服务器
Host dev
HostName 192.168.1.50
User developer
IdentityFile ~/.ssh/id_ed25519
Port 22
# 通过堡垒机访问生产环境
Host prod-bastion
HostName bastion.mycompany.com
User ec2-user
IdentityFile ~/.ssh/id_work
Host prod-*
User ubuntu
IdentityFile ~/.ssh/id_work
ProxyJump prod-bastion # 自动通过堡垒机跳转!
Host prod-web
HostName 10.0.1.10 # 内网 IP
Host prod-api
HostName 10.0.1.20
# GitHub
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_github
# 工作用 GitHub
Host github.work
HostName github.com
User git
IdentityFile ~/.ssh/id_work
# 配置后的使用:
ssh dev # 自动连接到 192.168.1.50
ssh prod-api # 自动通过堡垒机跳转!
# 使用不同身份克隆工作仓库
git clone git@github.work:mycompany/repo.git
ssh-agent:管理受密码保护的密钥
# 启动 agent(通常由操作系统自动启动)
eval "$(ssh-agent -s)"
# 添加密钥(只需输入一次密码)
ssh-add ~/.ssh/id_ed25519
ssh-add ~/.ssh/id_work
# 列出已加载的密钥
ssh-add -l
# 临时添加密钥(4 小时后过期)
ssh-add -t 14400 ~/.ssh/id_ed25519
# 从 agent 中移除所有密钥
ssh-add -D
# macOS:将密码存储在钥匙串中(重启后持久化)
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# ~/.zshrc / ~/.bashrc — 登录时自动添加密钥
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi

SSH 隧道
# 本地端口转发——在本地访问远程服务
# 在 localhost:5432 访问远程 PostgreSQL
ssh -L 5432:localhost:5432 user@server -N
# 使用 SSH 配置:
Host db-tunnel
HostName server.example.com
User user
LocalForward 5432 localhost:5432
LocalForward 6379 localhost:6379 # 同时隧道 Redis
# 使用:
ssh -N db-tunnel # 启动隧道
psql -h localhost -p 5432 -U myuser mydb # 本地连接!
# 远程端口转发——将本地服务暴露到远程
# 通过远程服务器将本地开发服务器暴露到互联网
ssh -R 8080:localhost:3000 user@server -N
# 现在:http://server.example.com:8080 → 你的本地 :3000
# SOCKS5 代理——通过服务器路由浏览器流量
ssh -D 1080 user@server -N
# 配置浏览器使用 SOCKS5 代理:localhost:1080
加固 SSH 服务器安全
# /etc/ssh/sshd_config — 服务器加固
# 禁用密码认证(仅密钥)
PasswordAuthentication no
ChallengeResponseAuthentication no
# 禁用 root 登录
PermitRootLogin no
# 仅使用现代算法
Protocol 2
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# 限制登录尝试次数
MaxAuthTries 3
MaxSessions 5
# 断开空闲会话
ClientAliveInterval 300
ClientAliveCountMax 2
# 日志级别(用于审计)
LogLevel VERBOSE
# 仅允许特定用户
AllowUsers deploy devteam
# 修改后重启 SSH:
sudo systemctl restart sshd
# 在关闭当前会话前,先在另一个终端测试!
SSH 调试
# 详细输出用于调试
ssh -v user@server # 详细
ssh -vv user@server # 更详细
ssh -vvv user@server # 最详细
# 常见问题:
# "Permission denied (publickey)"
ssh -v user@server 2>&1 | grep "Offering|Trying|Authentications"
# 检查:正确的密钥已加载?正确的用户?authorized_keys 权限?
# 检查服务器上的 authorized_keys
cat ~/.ssh/authorized_keys
ls -la ~/.ssh/
# 应为:~/.ssh 权限 700,authorized_keys 权限 600
# 测试特定密钥
ssh -i ~/.ssh/id_ed25519 user@server
# 检查服务器是否接受你的密钥
ssh-keyscan server.example.com >> ~/.ssh/known_hosts
GitHub/GitLab SSH 设置
# 测试连接
ssh -T git@github.com
# Hi username! You've successfully authenticated
# 添加 GitHub 的主机密钥(或在 github.com/docs 上验证指纹)
ssh-keyscan github.com >> ~/.ssh/known_hosts
# 多个 GitHub 账户
# ~/.ssh/config:
Host github.com-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_github_personal
Host github.com-work
HostName github.com
User git
IdentityFile ~/.ssh/id_github_work
# 使用:
git clone git@github.com-personal:username/repo.git
git clone git@github.com-work:company/repo.git
→ 使用 RSA 密钥对生成器 为 SSH 和其他加密目的生成 RSA 密钥对。