关键就两点:端口必须显式指定,公钥路径要准确;否则会连错端口、写空文件,导致后续始终无法免密。需先确认远程sshd已监听非标端口(如22222),再用ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22222 user@host分发公钥,最后用ssh -p 22222 user@host实测是否直连成功。

用 ssh-copy-id 初始化非标端口的免密登录,关键就两点:端口必须显式指定,公钥路径要准确;否则会连错端口、写空文件,导致后续始终无法免密。
确认远程服务已启用非标端口
先确保目标服务器已正确配置并监听你设定的端口(比如 22222):
- 编辑
/etc/ssh/sshd_config,确认有Port 22222这一行(可保留Port 22,但建议注释掉或删除以减少暴露面) - 检查
PubkeyAuthentication yes已开启;如需更高安全性,可设PasswordAuthentication no - 重启服务:
sudo systemctl restart sshd - 验证监听状态:
ss -tlnp | grep :22222,看到进程名含sshd才算生效
用 -p 指定端口 + -i 指定公钥路径
命令格式固定,顺序和参数不能错:
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22222 user@192.168.1.100-
-i后必须跟**公钥文件的完整路径**,推荐用~/.ssh/id_ed25519.pub或~/.ssh/id_rsa.pub,避免相对路径出错 -
-p必须紧跟在ssh-copy-id后,不能写成--port,也不能放在-i后面再加引号包裹(如"-p22222 user@host"是旧写法,不推荐) - 首次运行仍需输入一次远程用户的密码——这是唯一一次手动输密,之后就不再需要了
验证是否真正生效
别只看 ssh-copy-id 是否返回 “Number of key(s) added: 1”,要立刻实测:
- 执行:
ssh -p 22222 user@192.168.1.100 - 如果直接进入 shell,说明成功;若仍要输密码,常见原因有:
– 远程~/.ssh权限不是700(chmod 700 ~/.ssh)
–authorized_keys权限不是600(chmod 600 ~/.ssh/authorized_keys)
–sshd_config中AuthorizedKeysFile被改过路径,未指向默认位置
补充:没有 ssh-copy-id 怎么办
某些精简系统(如 Alpine、部分容器)可能没预装 ssh-copy-id,可用手动方式替代:
- 本地输出公钥内容:
cat ~/.ssh/id_ed25519.pub - 远程创建目录并追加:
ssh -p 22222 user@192.168.1.100 "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys",然后粘贴公钥回车结束 - 再补一句权限修复:
ssh -p 22222 user@192.168.1.100 "chmod 600 ~/.ssh/authorized_keys"











