外观
SSH 密钥登录与 config
密码登录是服务器被爆破的第一入口。密钥登录 + 禁用密码,是上线前必做的第一件事。
一、生成密钥
bash
ssh-keygen -t ed25519 -C "ops@laptop" -f ~/.ssh/id_ed25519text
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:8f2c1e9a7b3d5c8e0a2b4c6d8e0f1a3b5c7d9e1f ops@laptop| 算法 | 建议 |
|---|---|
ed25519 | 首选,短、快、安全 |
rsa -b 4096 | 老系统不支持 ed25519 时用 |
ecdsa | 少用,兼容性问题多 |
-C 是注释,写清是谁的哪台机器,方便以后从 authorized_keys 里清理。
私钥不要设空密码后随便放
id_ed25519(没有 .pub)是私钥,永远不要发给任何人。加个 passphrase,再用 ssh-agent 免重复输入:
bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519二、上传公钥
bash
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@10.0.0.31text
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@10.0.0.31's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@10.0.0.31'"手工方式:
bash
cat ~/.ssh/id_ed25519.pub | ssh root@10.0.0.31 \
'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'三、~/.ssh/config
管十几台机器的关键是这个文件:
ini
# ~/.ssh/config
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
TCPKeepAlive no
AddKeysToAgent yes
Host kafka-1
HostName 10.0.0.21
User root
Port 22
IdentityFile ~/.ssh/id_ed25519
Host kafka-2 kafka-3
HostName %h.internal
User root
IdentityFile ~/.ssh/id_ed25519
Host prod-*
User app
IdentityFile ~/.ssh/id_ed25519_prod
# 经跳板机
Host db-1
HostName 10.0.1.11
User root
ProxyJump bastion
Host bastion
HostName 203.0.113.10
User opsbash
ssh kafka-1
ssh db-1 # 自动经 bastion 跳转| 配置 | 作用 |
|---|---|
ServerAliveInterval 30 | 每 30 秒发心跳,防止 NAT 断连 |
AddKeysToAgent yes | 首次使用后自动加入 agent |
ProxyJump | 跳板机,替代老式 ProxyCommand |
%h | 引用 Host 名做模板 |
权限要求(不满足会直接拒绝):
bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config ~/.ssh/id_ed25519 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/id_ed25519.pub四、禁用密码登录
先确认密钥能登录,再改配置,否则会把自己锁在外面。
bash
ssh -o PreferredAuthentications=publickey root@10.0.0.31 'echo key-ok'text
key-ok改 /etc/ssh/sshd_config:
ini
PermitRootLogin prohibit-password
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2| 配置 | 说明 |
|---|---|
PermitRootLogin prohibit-password | root 只能用密钥(yes 允许密码,no 完全禁止 root) |
PasswordAuthentication no | 禁用密码 |
MaxAuthTries 3 | 三次失败断开 |
ClientAliveInterval 300 | 5 分钟无响应断开 |
bash
sshd -ttext
# 无输出 = 配置正确bash
systemctl reload sshdbash
ssh -o PreferredAuthentications=password root@10.0.0.31text
root@10.0.0.31: Permission denied (publickey).看到 Permission denied (publickey) 就说明密码通道已关闭。
改完 sshd 不要关掉当前会话
保留一个已登录的窗口,另开一个窗口测试新连接。测试通过再关旧窗口。改错了还能从旧窗口改回来。
五、排障
bash
ssh -vvv root@10.0.0.31关注这几行:
text
debug1: Offering public key: /root/.ssh/id_ed25519 ED25519 SHA256:8f2c...
debug1: Authentications that can continue: publickey
debug1: Server accepts key: /root/.ssh/id_ed25519 ED25519 SHA256:8f2c...
debug1: Authentication succeeded (publickey).服务端日志:
bash
journalctl -u sshd -n 50 --no-pager
# 或
tail -f /var/log/securetext
sshd[41200]: Authentication refused: bad ownership or modes for directory /root| 报错 | 原因 | 处置 |
|---|---|---|
bad ownership or modes | .ssh 或家目录权限太宽 | chmod 700 ~/.ssh,家目录不能是 777 |
Permission denied (publickey) | 公钥没在 authorized_keys,或权限不对 | 检查文件内容与权限 |
Connection refused | sshd 没起 / 端口错 | ss -lntp | grep 22 |
Connection timed out | 防火墙/安全组 | 放通 22 |
Too many authentication failures | agent 里 key 太多 | IdentitiesOnly yes |
| 一直提示输密码 | 服务端 PasswordAuthentication yes 且密钥失败 | -vvv 看密钥是否被拒绝 |
SELinux 场景还要恢复上下文:
bash
restorecon -Rv ~/.ssh
ls -Z ~/.ssh/authorized_keystext
unconfined_u:object_r:ssh_home_t:s0 /root/.ssh/authorized_keys六、跳板机
ini
Host bastion
HostName 203.0.113.10
User ops
Host 10.0.1.*
User root
ProxyJump bastion之后 ssh 10.0.1.11 会自动经过 bastion。
ProxyJump 等价于:
bash
ssh -J ops@203.0.113.10 root@10.0.1.11老版本 OpenSSH(< 7.3)用:
ini
ProxyCommand ssh -W %h:%p bastion七、踩过的坑
| 现象 | 根因 | 处置 |
|---|---|---|
| 改完 sshd 自己连不上了 | 禁用了密码但密钥没配好 | 用云控制台的 VNC 进去改回 |
| 密钥登录还提示密码 | authorized_keys 权限 644 以上 | chmod 600 |
agent 里的 key 太多导致失败 | 逐个尝试超过 MaxAuthTries | IdentitiesOnly yes + 指定 IdentityFile |
| 复制公钥时多了换行 | Windows 编辑器 | cat -A 检查,或用 ssh-copy-id |
| 定时任务里 ssh 失败 | 没有 agent | 用专用密钥 + IdentityFile,不要依赖 agent |
| 连接一会儿就断 | NAT 超时 | ServerAliveInterval 30 |
| 换机器后指纹变了报警告 | 正常 | 确认无误后 ssh-keygen -R host |