一、生成密钥
ssh-keygen -t ed25519 -C "me@example.com"
ed25519是现在的首选:密钥短、速度快、安全性好。老系统不支持时用rsa -b 4096。- 一路回车即可,passphrase 建议设置:即使私钥文件泄露,没有口令也用不了。
- 生成两个文件:
id_ed25519(私钥,绝不能外传)、id_ed25519.pub(公钥,可以随便给)。
二、把公钥放到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
它做的事就是往服务器的 ~/.ssh/authorized_keys 追加一行。手动操作也可以:
cat id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
权限是硬要求,SSH 会检查:
| 路径 | 权限 |
|---|---|
~(家目录) | 不能对组和其他人可写(755 或 700) |
~/.ssh | 700 |
~/.ssh/authorized_keys | 600 |
| 私钥文件 | 600 |
任何一项过宽,sshd 会直接忽略这个密钥,然后回落到密码登录——看起来像「配置没生效」。
三、~/.ssh/config 让登录变短
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
Host db
HostName 10.0.0.5
User root
ProxyJump prod
之后 ssh prod 就够了,ssh db 会自动经 prod 跳转。ProxyJump 比老式的 ProxyCommand nc 更简洁可靠。
四、端口转发
# 本地端口 → 远程服务(访问本地 8080 等于访问服务器的 3306)
ssh -L 8080:127.0.0.1:3306 prod
# 远程端口 → 本地服务(把本地 3000 暴露到服务器的 9000)
ssh -R 9000:127.0.0.1:3000 prod
# 动态代理(SOCKS5)
ssh -D 1080 prod
调试数据库、访问内网面板、临时穿透,都用得上,不必额外装工具。
五、还是提示输密码?按顺序查
- 权限:
ls -ld ~ ~/.ssh ~/.ssh/authorized_keys,家目录是否 755 以内。 - 服务端配置:
/etc/ssh/sshd_config里PubkeyAuthentication yes、AuthorizedKeysFile .ssh/authorized_keys,改完要systemctl reload sshd。 - SELinux:
restorecon -R -v ~/.ssh,标签不对也会拒绝。 - 用的是不是同一个用户:公钥加到了
root的目录,却用deploy登录。 - 客户端有没有指定对的私钥:
ssh -v看Offering public key那几行,能看到实际尝试了哪个文件。 - authorized_keys 格式:一行一个公钥,中间不能有换行;从网页复制常带换行导致整行失效。
ssh -vvv user@host 是排查的终极手段,输出里搜 Authentication 能看到每一步失败原因。
六、安全加固
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
关掉密码登录前,务必先确认密钥能登录、并留一个已连接的会话,否则容易把自己锁在外面。改完配置先 sshd -t 检查语法,再 reload。
另外建议:改默认端口只能挡扫描器、不算安全措施;真正有效的是禁密码 + 禁 root + fail2ban。
七、常用小技巧
ssh user@host "df -h"直接执行命令,不进交互 shell。scp -r dir user@host:/path传目录;大文件用rsync -avz --progress。ssh -o StrictHostKeyChecking=no首次连接免确认(脚本里用,交互场景别用)。- 私钥丢了就重新生成并把旧公钥从
authorized_keys删掉。
小结
ed25519 + 600 私钥 + 700 目录 + 600 authorized_keys 是基础;config 别名和 ProxyJump 能省大量输入;免密失败先查权限,再 ssh -vvv 看实际尝试的密钥。