ssh免密登录

场景

  • 客户端:Win10(自带 OpenSSH)、或任一 Linux 桌面
  • 目标设备:Debian / Ubuntu(新)、CentOS 7(老)、OpenWrt(dropbear)
  • 目标:从客户端免密 ssh / scp 到目标设备

密钥类型和长度怎么选

ssh-keygen -t <type> 支持的算法与推荐:

类型现状建议
ed25519现代首选,密钥小、速度快、安全性高默认用这个
rsa兼容性最好,老设备必要时用必须 -b 4096,不要再用 2048
ecdsaNIST 曲线,坊间对其随机数实现存疑不推荐
dsa已废弃,OpenSSH 7.x 起逐步禁用不要用

一句话:能用 ed25519 就用 ed25519;老设备不认就退回 rsa -b 4096

各目标设备的兼容性:

  • Debian / Ubuntu(任何仍在维护的版本)ed25519 没问题。
  • CentOS 7(OpenSSH 7.4):ed25519 支持,直接用。
  • OpenWrt(dropbear 2020.79+,即 OpenWrt 19.07 之后):ed25519 支持。再老的固件(15.x / 18.06)只认 rsa,这时生成 -t rsa -b 2048(dropbear 在极老硬件上处理 4096 位会慢、甚至内存不足)。

生成命令:

1
2
3
4
5
# 推荐(大多数场景)
ssh-keygen -t ed25519 -C "dajon@laptop-$(date +%F)"

# 兼容老设备(OpenWrt 15.x 之类)
ssh-keygen -t rsa -b 4096 -C "dajon@laptop-$(date +%F)"
  • -C 是注释,加上日期方便以后在 authorized_keys 里一眼认出是哪台机器哪年的 key。
  • 一路回车;passphrase 留空方便自动化,想更安全就设置一个,然后配合 ssh-agent 免每次输入。
  • 默认路径:Linux 在 ~/.ssh/,Win10 在 C:\Users\<用户>\.ssh\
  • 文件命名:id_ed25519 / id_ed25519.pub,或 id_rsa / id_rsa.pub

客户端:生成密钥

Linux 客户端

1
ssh-keygen -t ed25519

Win10 客户端(自带 OpenSSH)

Win10 1809+ 原生自带 OpenSSH,PowerShell 里直接:

1
ssh-keygen -t ed25519

如果提示找不到命令,控制面板 → 应用 → 可选功能 → 添加 “OpenSSH 客户端”。密钥会生成在 C:\Users\<用户>\.ssh\

目标设备:部署公钥

通用快捷方式(Linux 客户端首选)

1
2
3
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
# 非默认端口:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 user@host

会自动处理 ~/.ssh 目录、权限、追加到 authorized_keys

Win10 没有 ssh-copy-id,用 PowerShell 一行搞定:

1
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

Debian / Ubuntu / CentOS 7(标准 OpenSSH)

手动部署就是把公钥内容追加到目标机的 ~/.ssh/authorized_keys

1
2
3
4
5
# 目标机上
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "<粘贴客户端 id_ed25519.pub 的内容>" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

CentOS 7 额外一步(SELinux):如果是 scp 拷过去的文件,SELinux context 可能不对,导致 sshd 无法读:

1
restorecon -R -v ~/.ssh

OpenWrt(dropbear,不是 OpenSSH)

OpenWrt 默认用 dropbear,密钥文件和普通 Linux 不一样

  • 所有用户(其实只有 root)的公钥都写到 /etc/dropbear/authorized_keys(单文件,不分用户)
  • 文件权限必须 0600,目录 0700
1
2
3
4
5
# 在 OpenWrt 上执行
mkdir -p /etc/dropbear
chmod 700 /etc/dropbear
echo "<粘贴公钥>" >> /etc/dropbear/authorized_keys
chmod 600 /etc/dropbear/authorized_keys

或者本地一行推过去:

1
cat ~/.ssh/id_ed25519.pub | ssh [email protected] "cat >> /etc/dropbear/authorized_keys && chmod 600 /etc/dropbear/authorized_keys"

想禁止密码登录(仅限 LAN 内安全时这么干):

1
2
3
4
5
# OpenWrt 上
uci set dropbear.@dropbear[0].PasswordAuth='off'
uci set dropbear.@dropbear[0].RootPasswordAuth='off'
uci commit dropbear
/etc/init.d/dropbear restart

权限要求(90% 的免密失败都栽这儿)

目标机必须满足:

路径权限属主
~不能对 group/other 可写当前用户
~/.ssh700当前用户
~/.ssh/authorized_keys600当前用户

一行体检:

1
ls -ld ~ ~/.ssh ~/.ssh/authorized_keys

~/.ssh/config 进阶(强烈推荐配一次)

客户端写 ~/.ssh/config,以后只用 alias,省敲:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Host myvps
    HostName vps.example.com
    User root
    Port 22
    IdentityFile ~/.ssh/id_ed25519

Host openwrt
    HostName 192.168.1.1
    User root
    IdentityFile ~/.ssh/id_ed25519

Host serv00
    HostName s7.serv00.com
    Port 22
    User dajon
    IdentityFile ~/.ssh/id_ed25519

之后 ssh myvps / scp file myvps:/tmp/ 即可;rsync、git over ssh 也都能用。

Win10 下同样,文件路径 C:\Users\<用户>\.ssh\config

故障排查速查

连上去还是要密码? 按这个顺序查:

  1. 本地 key 是否被加载:ssh -v user@host 2>&1 | grep -i offering
  2. 目标机 /var/log/auth.log(Debian/Ubuntu)或 /var/log/secure(CentOS);OpenWrt 看 logread | grep dropbear
  3. 目标机 ~/.ssh~/.ssh/authorized_keys 权限(见上表)
  4. CentOS 7 试一下 restorecon -R -v ~/.ssh
  5. /etc/ssh/sshd_configPubkeyAuthentication yesPermitRootLogin 别设成 no
  6. OpenWrt 确认公钥在 /etc/dropbear/authorized_keys(不是 ~/.ssh/!)

指定某个 key 登录(多 key 环境调试用):

1
ssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes user@host
使用 Hugo 构建
主题 StackJimmy 设计