现在默认用 ssh-keygen -t ed25519 最稳妥,因其更快、更短、更安全且openssh 6.5+全面支持;仅当兼容老旧系统(如centos 6)时才退选 rsa -b 4096,禁用dsa及2048位rsa。

ssh-keygen生成密钥对时该选什么算法和位数
现在默认用 ssh-keygen -t ed25519 最稳妥。ed25519 比 RSA 更快、更短、更安全,且 OpenSSH 6.5+ 全面支持(2026 年几乎所有发行版都满足)。如果目标服务器太老(比如 CentOS 6 或某些嵌入式系统),才退回到 ssh-keygen -t rsa -b 4096 —— 不要用 -b 2048,NIST 已建议淘汰;也别用 dsa,它已被 OpenSSH 7.0+ 默认禁用。
生成时不设密码短语(直接回车)虽方便自动化,但私钥文件一旦泄露即失守;若用于生产环境或共享机器,务必设密码短语。此时每次 ssh 或 scp 都会提示输入,可用 ssh-agent 缓存解密后的私钥,避免反复输。
上传公钥失败常见于权限或路径错误
最常卡在两处:远程 ~/.ssh 目录权限不是 700,或 authorized_keys 文件权限不是 600。SSH 服务端极其严格,哪怕 ~/.ssh 所属组有写权限(如 755),也会直接拒绝读取公钥文件,日志里只报 Authentication refused,不提具体原因。
-
ssh-copy-id能自动处理权限,优先用它:ssh-copy-id user@host - 若不可用(如 Alpine 或最小化镜像),手动执行时必须拆成三步:
mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys,缺一不可 - 确认公钥内容完整粘贴——
cat ~/.ssh/id_ed25519.pub复制整行(从ssh-ed25519开始,到邮箱或注释结束),中间不能换行、不能多空格
/etc/ssh/sshd_config 中真正起作用的配置项
很多教程照抄过时参数,实际只需关注三项:
-
PubkeyAuthentication yes—— 必须启用,RSAAuthentication是旧版兼容项,现代 OpenSSH 可忽略 -
AuthorizedKeysFile .ssh/authorized_keys—— 默认值,除非你改过路径,否则不用动;注意它不支持绝对路径写法(如/home/user/.ssh/...) -
PasswordAuthentication no—— 这是可选项,但要在确认免密登录稳定后再加,否则可能锁死自己
改完必须重启服务:sudo systemctl restart sshd(systemd 系统)或 sudo service ssh restart(SysVinit)。验证是否生效:运行 sudo ss -tnlp | grep :22,看监听进程是否已加载新配置。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
测试连接时为什么还弹密码框
不是配置没生效,就是客户端没用对方式。默认 ssh user@host 会按顺序尝试所有认证方法(keyboard-interactive → publickey → …),只要密码认证还开着,它就先试密码。
强制只走公钥认证,加这个参数:ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no user@host。如果这时连不上,说明公钥环节出问题;如果能连上,但没加参数时仍要密码,说明 PasswordAuthentication yes 还开着,或者服务端没重载配置。
调试关键命令:ssh -v user@host,重点看这几行:
-
debug1: Authentications that can continue: publickey,password→ 服务端认可公钥,但没禁用密码 -
debug1: Offering public key: /home/xxx/.ssh/id_ed25519 ED25519 SHA256:xxx→ 客户端确实发了公钥 -
debug1: Server accepts key→ 成功;若看到Authentication refused后直接 fallback 到 password,基本就是权限或路径问题
SELinux 或 AppArmor 也可能拦截,临时测可用 sudo setenforce 0 关闭 SELinux,再试一次。若恢复连接,就得用 restorecon -Rv ~/.ssh 修复上下文,而不是永久关 SELinux。










