解决 Synology SSH 连接不上的问题

问题描述

群晖(Synology DSM)开启 SSH 服务后,使用公钥登录仍然失败,客户端只看到:

1
Permission denied (publickey)

一开始容易误判为 .ssh/authorized_keys 没配置好、客户端没有加载正确 key、SSH 服务没开,或者 DSM 的用户家目录路径理解错了。DSM 7 的 home 目录通常不是传统 Linux 的 /home/<用户名>,而是:

1
/var/services/homes/<用户名>

实际路径通常指向:

1
/volume1/homes/<用户名>

这次真正的问题不是公钥内容本身,而是 Synology 的 ACL 和 SSH 安全检查冲突:为了让 VerySync 同步,把 /volume1/homes/river 这个 home 根目录授权给了 verysync。但 Synology 的 SSH 会通过 syno_acl_safe_path() 检查 home path 的 ACL。只要 home 根目录上出现过宽的 ACL、非登录用户的 ACL,或者从父目录继承来的不安全 ACL,OpenSSH 就会拒绝读取 authorized_keys,最终表现为 Permission denied (publickey)

也就是说:

  • 公钥可能已经放对了。
  • .ssh/authorized_keys 权限也可能看起来没问题。
  • 但只要 home 目录本身的 Synology ACL 不“安全”,SSH 仍然会拒绝公钥登录。

解决步骤

先确认客户端确实在尝试公钥登录

本机执行:

1
ssh -v river@<群晖IP>

重点看调试输出里有没有:

1
Offering public key:

如果没有,说明客户端根本没有拿这个 key 去试,可以显式指定:

1
ssh -i ~/.ssh/id_ed25519 river@<群晖IP>

如果已经看到 Offering public key,但最后仍然是:

1
Permission denied (publickey)

就继续排查服务端。

确认 Synology 的 .ssh 位置和基础权限

在 NAS 上确认真实 home:

1
2
echo $HOME
pwd

DSM 7 常见路径是:

1
/var/services/homes/river

公钥文件应放在:

1
/var/services/homes/river/.ssh/authorized_keys

基础权限应为:

1
2
3
chmod 755 /var/services/homes/river
chmod 700 /var/services/homes/river/.ssh
chmod 600 /var/services/homes/river/.ssh/authorized_keys

并确认 owner 是登录用户自己:

1
2
ls -la /var/services/homes/river
ls -la /var/services/homes/river/.ssh

开启 Telnet 作为救援入口

如果 SSH 已经完全进不去,先在 DSM 里临时开启 Telnet:

1
控制面板 -> 终端机和 SNMP -> 启用 Telnet

从局域网机器连接群晖:

1
telnet <群晖IP>

登录后切换到有权限排查系统服务的账号。如果需要 root 权限,可以用管理员账号后再执行:

1
sudo -i

确认不是 SSH 服务或端口问题

先检查 DSM 里 SSH 服务是否已开启、端口是否正确,也可以在系统里看 SSH 相关进程是否存在:

1
ps | grep sshd

如果 SSH 服务已经在跑,但客户端依然连不上,就不要只盯着端口和防火墙,继续看服务端日志。

手动启动一个调试用 SSHD 获取服务端日志

DSM 自带的 SSH 服务日志不一定能在界面里直接看到。为了拿到更明确的错误信息,可以在 Telnet 会话里手动启动一个新的 sshd,监听临时端口,例如 2222

1
/bin/sshd -p 2222 -D -e

其中:

  • -p 2222:使用临时端口,避免影响原来的 SSH 服务。
  • -D:以前台方式运行,方便直接观察输出。
  • -e:把日志输出到标准错误,直接显示在当前终端。

然后在另一台机器上连接这个临时端口:

1
ssh -p 2222 <用户名>@<群晖IP>

这时 Telnet 里的 sshd 前台日志会打印更具体的失败原因。关键线索是 SSH 对用户 home 目录、.ssh 目录或 Synology ACL 的安全检查没有通过,可能会看到类似:

1
Authentication refused: bad ownership or modes for directory ...

或者与 Synology ACL 相关的 bad ACL permission / syno_acl_safe_path 之类信息。

这个日志说明问题不在客户端,也不只是 SSH 端口没开,而是登录用户目录权限不符合 SSH 的安全要求。

检查 Synology ACL

对 home 目录查看 ACL:

1
synoacltool -get /volume1/homes/river

synoacltool 里会看到类似:

1
2
3
0: user:river:allow:... (level:0)
1: group:users:allow:... (level:0)
2: user:verysync:allow:... (level:1)

这里的 level 表示 ACL 继承层级:

  • level:0:当前目录上直接定义的 ACL。
  • level:1:从父目录继承来的 ACL。
  • level:2:从更高层目录继承来的 ACL。

真正影响权限的是 allow / deny 和后面的权限位,但 Synology 的 SSH 安全检查有时也会被 inherited ACL 影响。也就是说,即使 .sshauthorized_keys 的传统 Unix 权限正确,只要 home path 上有不安全的 ACL,SSH 仍然会拒绝。

清理 home 根目录上的 VerySync ACL

不要给 /volume1/homes/river 本身添加 verysync ACL。home 根目录应该尽量保持干净:

1
2
3
4
5
6
synoacltool -del /volume1/homes/river
synoacltool -add /volume1/homes/river "user:river:allow:rwxpdDaARWcCo:fd--"

chmod 755 /volume1/homes/river
chmod 700 /volume1/homes/river/.ssh
chmod 600 /volume1/homes/river/.ssh/authorized_keys

如果 owner 被改坏,也要改回当前登录用户:

1
2
chown river:users /volume1/homes/river
chown -R river:users /volume1/homes/river/.ssh

这里的核心原则是:home 根目录不要给 verysynceveryone 或其他无关用户额外授权。

重新测试 SSH

修复后先测试临时端口:

1
ssh -p 2222 river@<群晖IP>

如果临时端口已经能登录,再回到 DSM 的正常 SSH 端口测试:

1
ssh river@<群晖IP>

确认正常后关闭 Telnet,避免留下不必要的明文登录入口。

调整 VerySync 的同步目录

如果只是给 home 下的某个子目录授权仍然不行,说明 VerySync 会访问或检查整个 home path,和 Synology SSH 的 safe path 检查天然冲突。不要继续污染 /volume1/homes/river 的 ACL。

更稳的做法是把同步目录移到 home 外:

1
2
3
mkdir -p /volume1/verysync/river
chown -R river:users /volume1/verysync/river
synoacltool -add /volume1/verysync/river "user:verysync:allow:rwxpdDaARWcCo:fd--"

然后让 VerySync 同步:

1
/volume1/verysync/river

如果希望在 home 目录里仍然能看到这个同步目录,可以放一个软链接:

1
ln -s /volume1/verysync/river /volume1/homes/river/Sync

这样 SSH 检查的 home 根目录仍然是干净的,VerySync 需要的 ACL 则只存在于 home 外的数据目录上。

根本原因

在配置 VerySync 的时候,把 /volume1/homes/river 这个 home 根目录授权给了 verysync 用户。Synology DSM 的 SSH 不只检查 .ssh/authorized_keys 的传统 Unix 权限,还会通过 syno_acl_safe_path() 检查 home path 的 Synology ACL。home 根目录上出现 verysync 这类额外 ACL 后,会被 SSH 判定为不安全,最终拒绝公钥登录。

一开始以为只要把权限改到 home 下的具体文件夹即可,但 VerySync 实际上还会访问或检查上级路径;如果不给 home 目录读取权限,它又无法正常同步。所以最终是给 home 目录的读取权限,具体目录再给完全控制权限。