问题现象
在为QNAP配置SSH连接时,出现了以下现象:
- 使用Windows自带OpenSSH直连QNAP时,初期出现
Corrupted MAC on input。 - 改为密码登录后,可以正常登录QNAP。
- 本机公钥已写入远端后,私钥登录仍然失败,报错为
Permission denied (publickey)。
最终结论
本问题的根因是 QNAP/QTS 的 SSH 公钥认证目录权限异常,导致服务端明确拒绝读取 authorized_keys。
关键根因如下:
- QNAP 实际生效的 SSH 公钥目录不是表面看到的路径,而是映射到:
/mnt/sync/.config/ssh
-
该目录的 owner 不正确,最初表现为 UID
1000,而不是admin,导致 sshd 在StrictModes检查时直接拒绝公钥认证。 -
QNAP 上 admin 的真实家目录和交互登录目录并不完全一致:
/etc/passwd 中 admin 的家目录是 /share/homes/admin
交互登录实际落在 /root
/root/.ssh 又是 /etc/config/ssh 的软链接
因此不能只看一个路径表象,必须结合 sshd 日志定位真实拒绝点。
关键诊断过程
密码 SSH 可用,说明不是网络不通
通过密码 SSH 验证,目标机可登录,返回:
## hostname
QNAP
## whoami
admin
这一步证明:
- 主机在线。
- SSH 服务在线。
- 用户名密码正确。
远端环境识别
进一步读取系统信息后:
hostname: QNAP
osName: Linux
osVersion: QTS 6.0.0 (20251125)
kernelVersion: 6.6.32-qnap
OpenSSH初期失败并不能说明密钥未部署
即使远端已有公钥,仍然可能因为服务端权限检查失败而出现以下错误:
Permission denied (publickey)
因此不能把这些错误直接等价于“公钥没写进去”。
admin 用户与路径映射检查
通过远端检查得到:
admin:x:0:0:administrator,,administrator,:/share/homes/admin:/bin/sh
以及:
/root/.ssh -> /etc/config/ssh
说明:
- admin 的 passwd 家目录是
/share/homes/admin。 - 登录后实际使用
/root。 /root/.ssh又指向/etc/config/ssh。
sshd 配置检查
读取到 /etc/ssh/sshd_config 关键配置如下:
39:#StrictModes yes
43:#PubkeyAuthentication yes
44:#AuthorizedKeysFile .ssh/authorized_keys
这意味着:
- 默认仍然会启用
StrictModes。 - 默认允许公钥认证。
- 服务端会检查
.ssh/authorized_keys。
核心证据:sshd 调试日志
为了拿到服务端的明确拒绝原因,在远端起了一个调试 sshd 到 2222 端口:
/usr/sbin/sshd -D -d -f /etc/ssh/sshd_config -p 2222
随后用本机私钥去连接该调试端口,读取 /tmp/sshd.out,得到最关键证据:
debug1: trying public key file /root/.ssh/authorized_keys
Authentication refused: bad ownership or modes for directory /mnt/sync/.config/ssh
Failed publickey for admin from 客户端 port 53564 ssh2: RSA SHA256
这条日志已经直接说明根因:
- sshd 确实找到了公钥路径。
- sshd 拒绝的原因不是 key 内容不匹配,而是目录 owner 或 mode 不合法。
- 真正出问题的目录是:
/mnt/sync/.config/ssh
关键输出证据
错误 owner 修复前
drwx------ 2 1000 administrators 15 Mar 8 09:03 /mnt/sync/.config/ssh
修复后
drwx------ 2 admin administrators 15 Mar 8 09:03 /mnt/sync/.config/ssh
-rw------- 1 admin administrators 741 Mar 8 09:21 /mnt/sync/.config/ssh/authorized_keys
PowerShell 私钥登录成功证据
使用 Posh-SSH 的 KeyFile 模式验证成功,返回:
QNAP
admin
最终解决方案
最终采用的方案如下:
- 为 QNAP 单独生成了一把新的 RSA 密钥:
C:\Users\用户名\.ssh\qnap_admin_rsa
- 将对应公钥写入两个位置:
/etc/config/ssh/authorized_keys
/share/homes/admin/.ssh/authorized_keys
- 修正 admin 家目录及 .ssh 相关权限:
chmod 711 /share/homes/admin
chmod 700 /share/homes/admin/.ssh
chmod 600 /share/homes/admin/.ssh/authorized_keys
- 修正 QNAP 实际生效目录的所有权和权限:
chown admin:administrators /mnt/sync/.config/ssh
chown admin:administrators /mnt/sync/.config/ssh/authorized_keys
chmod 700 /mnt/sync/.config/ssh
chmod 600 /mnt/sync/.config/ssh/authorized_keys
过程中使用过的重要命令
生成 RSA 密钥
ssh-keygen -t rsa -b 4096 -C qnap-admin-rsa -f C:\Users\用户名\.ssh\qnap_admin_rsa -N ""
PowerShell 验证密码 SSH
Import-Module Posh-SSH
$sec = ConvertTo-SecureString '密码' -AsPlainText -Force
$cred = [pscredential]::new('admin',$sec)
$s = New-SSHSession -ComputerName QNAP -Credential $cred -AcceptKey
Invoke-SSHCommand -SessionId $s.SessionId -Command 'hostname; whoami'
PowerShell 验证私钥 SSH
Import-Module Posh-SSH
$cred = [pscredential]::new('admin',(ConvertTo-SecureString 'x' -AsPlainText -Force))
$s = New-SSHSession -ComputerName QNAP -Credential $cred -KeyFile C:\Users\用户名\.ssh\qnap_admin_rsa -AcceptKey -Force
Invoke-SSHCommand -SessionId $s.SessionId -Command 'hostname; whoami'
启动调试 sshd
/usr/sbin/sshd -D -d -f /etc/ssh/sshd_config -p 2222
查看服务端拒绝原因
tail -n 120 /tmp/sshd.out
修正 QNAP 实际生效目录的 owner 和权限
chown admin:administrators /mnt/sync/.config/ssh
chown admin:administrators /mnt/sync/.config/ssh/authorized_keys
chmod 700 /mnt/sync/.config/ssh
chmod 600 /mnt/sync/.config/ssh/authorized_keys
排障经验总结
这次问题有几个很关键的经验点:
Permission denied (publickey)不代表公钥一定没写进去,也可能是服务端权限检查拒绝。- QNAP/QTS 的
.ssh路径存在软链接和真实目录映射,必须看 sshd 调试日志,不然很容易误判。 - 写
authorized_keys时必须避免任何会折行、转码或插入 BOM 的写法。 - 对老系统或兼容层较复杂的设备,单独生成一把 RSA key 往往更稳妥。
- 诊断 SSH 问题时,最有效的方法往往不是盲改,而是直接起调试 sshd,读服务端日志。
当前状态
截至本次排障结束:
- QNAP 已经可以通过私钥无密码 SSH 登录。
- Posh-SSH 的纯 PowerShell 验证已经通过。