ssh-copy-id报“permission denied (publickey)”本质是其底层ssh连接失败,主因包括:本地无法密码登录、非22端口未指定-p、远程家目录不可写、密钥文件名非默认需显式-i指定、或~/.ssh目录及authorized_keys权限非700/600。

能直接用 ssh-copy-id 就别手撸,但前提是它真能跑通;否则你得知道它卡在哪、权限错在哪、甚至它背后执行的到底是什么命令。
为什么 ssh-copy-id 会报 “Permission denied (publickey)”
这不是 ssh-copy-id 自己失败了,而是它根本没执行成功——你连远程主机都没进去,后续所有操作(追加公钥、修权限)全跳过。常见原因包括:
- 本地无法用密码登录:先手动运行
ssh user@host,输一次密码看能不能进。进不去,ssh-copy-id必然失败 - 远程 SSH 端口不是 22:必须加
-p参数,例如ssh-copy-id -p 2222 user@host;写成--port或漏掉-p都会静默失败 - 远程用户家目录不存在或不可写:比如 NFS 挂载、SELinux 限制、或 root 创建用户后没正确设置归属,导致
ssh-copy-id连上后连mkdir -p ~/.ssh都被拒绝
用 ssh-copy-id 时该指定哪个密钥文件
默认它会找 ~/.ssh/id_rsa.pub,但如果你生成的是 ed25519 密钥、或用了自定义名字(比如 id_work),就必须显式指定:
- 用 ed25519:运行
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host - 用自定义密钥:比如
ssh-keygen -t rsa -b4096 -f ~/.ssh/id_prod,就得配-i ~/.ssh/id_prod.pub - 不加
-i又没有默认密钥文件,ssh-copy-id会报错 “no identities found” 并退出
远程 .ssh 目录和 authorized_keys 权限为什么总出错
OpenSSH 默认启用 StrictModes yes,只要权限不对,就直接忽略公钥——哪怕内容完全正确。最常踩的坑是:
-
~/.ssh目录权限不是700(即drwx------):755、777、甚至 705 都不行,会被拒绝读取 -
~/.ssh/authorized_keys文件权限不是600(即-rw-------):644、640、664 全部无效,OpenSSH 会静默跳过整行 -
~/.ssh是软链接:OpenSSH 明确禁止,必须是真实目录;ls -ld ~/.ssh看到->就得重做 - 修复命令要登录远程后执行:
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
当 ssh-copy-id 失败时,怎么快速定位问题
加 -v(verbose)参数让它打印实际执行的命令,核心就这一句:
ssh user@host "mkdir -p .ssh && cat >> .ssh/authorized_keys"
你可以手动复现这串命令,观察哪一步卡住。例如:
- 如果
mkdir -p .ssh报 “Permission denied”,说明家目录或父目录权限/归属不对 - 如果
cat >> .ssh/authorized_keys报 “No such file or directory”,说明.ssh没创建成功,或路径拼错了(比如写成~/.ssh但 shell 没展开) - 执行完后立刻检查
~/.ssh/authorized_keys文件末尾是否新增了你的公钥行
真正麻烦的从来不是生成密钥,而是远程端那几个看似微小的权限位和路径细节——它们不会报错,只会让你反复 ssh 失败,还找不到原因。











