拓冰建站拓冰建站
首页 / 资讯中心 / 正文

群晖Linux短密码与SSH免密登录多机互信实战

1. 从需求到方案群晖Linux短密码与免密登录的整体思路群晖NAS跑的是Linux底子DSM只是套在Linux上面的管理界面。很多人第一次用群晖习惯在网页端点点点等到要写脚本、做定时备份、批量同步多台机器时才会发现SSH才是真正顺手的地方。短密码、免密登录、多个群晖互相信任这三个需求常常一起出现测试环境里不想每次输一长串复杂密码自动化脚本里不能人工输入密码多台NAS之间又要像一台机器那样互相调用命令、推送文件。关键词先摆出来群晖、Linux、短密码、免密登录这篇文章就围着它们展开。我自己手里长期维护着几台群晖有放在机柜里的也有放在办公室角落当备份节点的。最开始我也觉得短密码没必要反正密码管理器能记住。后来做实验室环境临时账号给同事用每天登录几十次复杂密码反而成了负担。再后来做多机同步脚本里写明文密码又不放心于是把短密码和SSH密钥免密登录拆开处理短密码只给内网、低权限、可随时删除的账号免密登录只走密钥不给密码留机会。这个思路不复杂但每一步都有细节尤其是群晖的DSM和标准Linux发行版有差异照搬网上的教程很容易卡在权限、家目录、PAM策略这几个地方。这篇内容适合三类人看第一类刚接触群晖想搞明白DSM里的用户、密码、SSH到底和普通Linux有什么不同第二类已经开了SSH但被“Permission denied (publickey)”折磨过第三类手里有两台以上群晖想用一台管理机统一发命令、统一备份。下面我会先讲整体设计再拆短密码设置接着把单机免密登录和多机互信串起来最后给排查表和长期维护经验。命令都是我在DSM 7上实际跑过的不同版本可能有细微差异我会把差异点标出来。1.1 为什么短密码和免密登录总是被一起提起短密码和免密登录看起来是两件事其实背后是同一个问题认证成本。短密码降低的是人工输入成本免密登录降低的是自动化脚本的认证成本。两者都在牺牲一部分安全性来换效率所以必须配合补偿措施。我的做法是短密码只用于内网测试账号并且给这些账号加上登录来源限制、失败锁定、定期清理免密登录只用于固定管理机到固定NAS私钥不落地到共享目录公钥只追加不覆盖出问题能快速撤销。群晖的DSM在密码策略上比普通Linux发行版更“图形化”。网页端 Control Panel 里能设置最小长度、复杂度、过期时间但有些版本对管理员账号有额外强制。你如果直接在网页端把策略改宽普通用户可能能设短密码但管理员账号仍然会被拦。这时候就要知道底层有synouser、passwd、chpasswd这些命令它们走的认证路径不完全一样。搞懂哪条路径被PAM拦、哪条路径绕过了前端策略短密码设置就不会变成玄学。免密登录的核心是SSH公钥认证。群晖的SSH服务就是OpenSSH配置文件在/etc/ssh/sshd_config用户公钥放在~/.ssh/authorized_keys。听起来和Ubuntu、Debian一样但群晖有两个坑一是用户家目录默认可能没启用二是家目录权限和属主会被DSM的某些服务改动。很多人把公钥追加进去了权限也改了还是登不上就是因为家目录服务没开或者.ssh目录被重新创建成了错误权限。把这两个点记住后面排查会省很多时间。多个群晖免密登录本质上是在单机免密的基础上做批量分发和主机别名管理。你可以在每台NAS上分别生成密钥互相交换公钥也可以选一台管理机生成一套密钥把公钥分发到所有NAS。两种方式我都用过前者适合NAS之间互相备份后者适合一台跳板机管理整个机房。选哪种取决于你的信任模型如果管理机被入侵私钥泄露所有NAS都会受影响如果每台NAS独立密钥泄露范围小但管理起来麻烦。我的建议是生产环境用独立密钥测试环境用统一管理机并且给私钥加密码短语配合ssh-agent使用。1.2 方案选型DSM图形界面、SSH命令、密钥体系怎么配合短密码这部分优先级从高到低是先改DSM密码策略让网页端允许短密码如果网页端仍然拦再用synouser --setpw直接改如果系统PAM策略也拦并且你确认只是内网测试再考虑临时调整PAM的minlen。为什么这么排序因为DSM网页端的策略修改是可逆的、有记录的系统升级后不容易丢synouser是群晖自带工具比手改/etc/shadow安全PAM配置改起来影响所有用户升级还可能被覆盖放到最后。免密登录这部分密钥类型我首选ed25519。RSA也不是不能用但同样安全强度下RSA密钥更长老设备兼容性更好新设备没必要。群晖DSM 7的OpenSSH版本足够新ed25519完全支持。生成密钥时我会加-a 100做KDF轮数私钥加密码短语然后在管理机上用ssh-agent缓存。如果这台管理机只用于自动化登录本身已经受严格控制也可以不加密码短语但一定要限制私钥文件权限并且不要把私钥放在群晖的共享文件夹里。多群晖场景我会额外做三件事第一给每台NAS在~/.ssh/config里起别名比如nas-a、nas-b避免记IP第二用IdentitiesOnly yes防止SSH客户端拿错密钥第三把所有公钥追加操作写成脚本或Ansible任务避免手动复制漏字符。公钥是一行文本复制时多一个空格、少一个换行都会导致认证失败。手动操作容易出错批量操作更容易出错所以能自动化就自动化。安全边界也要提前定好。短密码账号不允许登录SSH或者只允许从特定内网IP登录免密登录的账号不给root权限需要提权时用sudo关闭密码认证之前必须先用密钥登录成功并且保留一个已登录的会话防止配置写错把自己锁在外面。这些不是可选项是底线。下面进入具体操作。2. 群晖Linux短密码设置从策略到命令的落地细节2.1 DSM密码策略在哪里改哪些限制会拦住短密码群晖DSM 7的密码策略入口在 Control Panel User Group Advanced Password Settings。这里能看到几个关键选项密码最小长度、是否要求包含大小写字母、数字、特殊字符、是否禁止用户名出现在密码里、密码过期天数、密码历史记录。很多教程只说“取消复杂度”但实际拦住短密码的往往是“最小长度”。如果你的DSM版本允许把最小长度设成小于8那普通用户就能在网页端设置短密码。如果最小长度下限就是8网页端怎么改都没用只能走命令行。还有一个容易忽略的点管理员组的账号可能受到更严格的策略限制。DSM 7把默认admin账号禁用之后你新建的管理员账号仍然可能被要求强密码。这时候可以尝试把该账号临时移出administrators组设完短密码再移回去但我不推荐这么做因为管理员短密码风险太高。更合理的做法是管理员账号保持强密码另建一个普通用户用于内网测试给这个普通用户设短密码。短密码只在小范围、低权限、可删除的场景里用这是原则。修改策略后已有用户的密码不会自动变短只是下次修改时允许短密码。如果你想让某个用户立即变成短密码可以在 User Group 里选中用户点 Edit重新输入新密码。如果网页端仍然提示“密码强度不足”说明前端策略或后端PAM还有一层校验。这时候先别急着改PAM先用SSH登录用synouser试一下很多时候群晖自带的用户管理工具能直接改成功。注意短密码只建议在内网测试账号上使用。不要把管理员账号、SSH登录账号、SMB共享账号设成短密码。如果必须给SMB共享用短密码至少要在群晖防火墙上限制来源IP并开启自动封锁。2.2 用SSH命令设置短密码synouser、passwd与PAM的边界先在DSM里开启SSH服务。路径是 Control Panel Terminal SNMP Terminal勾选 Enable SSH service。端口默认22如果你改过端口后面命令要加-p。然后用管理员账号登录ssh admin192.168.1.10登录后提权sudo -i群晖自带的用户管理命令是synouser。查看用法synouser --help给普通用户设置短密码synouser --setpw testuser 123456这条命令我在DSM 7上实测可用它直接更新用户密码不经过网页端那套强度校验。如果提示synouser: command not found说明你的DSM版本路径不同可以试/usr/syno/sbin/synouser --setpw testuser 123456另一个常用命令是passwdpasswd testuser但passwd会走PAM策略如果系统要求最小长度8你输入123456会被拒绝提示“密码太短”或“密码强度不足”。这时候可以看PAM配置grep -R pwquality\|cracklib\|minlen /etc/pam.d/如果输出里有minlen8或类似配置说明PAM在拦。你可以临时备份并修改对应的配置文件比如cp /etc/pam.d/common-password /etc/pam.d/common-password.bak vi /etc/pam.d/common-password把minlen8改成minlen4或者把ucredit、lcredit、dcredit、ocredit这些复杂度要求去掉。改完后passwd就能设短密码。但我要提醒三点第一不同DSM版本的PAM文件路径可能不一样有的在/etc/pam.d/password有的在/etc/pam.d/system-auth第二DSM系统升级可能覆盖这些文件升级后短密码策略可能失效第三改PAM影响所有用户包括管理员所以改完要尽快恢复或加注释。如果系统里有chpasswd也可以用它批量改echo testuser:123456 | chpasswdchpasswd通常也绕过部分PAM校验但有些群晖版本没带这个命令。你可以用which chpasswd检查。如果都没有最后的手段是直接改/etc/shadow但我不建议因为群晖的密码哈希格式和用户数据库同步机制比较复杂手改容易导致用户无法登录。优先用synouser。提示修改PAM配置前先备份改完后用另一个终端测试登录不要关闭当前SSH会话。如果配置写错当前会话还能救回来。2.3 短密码的使用边界与安全补偿短密码设好之后不能就这么放着。我的做法是给短密码账号加四道限制。第一道是群晖防火墙只允许内网网段访问DSM和SMB比如只允许192.168.1.0/24。路径是 Control Panel Security Firewall。第二道是自动封锁在 Control Panel Security Auto Block 里开启设置尝试次数和封锁时间防止有人暴力猜短密码。第三道是账号权限短密码账号只给只读权限不给管理员组不给SSH登录权限。第四道是定期清理给短密码账号设一个过期日期到期自动禁用。如果你用短密码登录SMB共享还要注意客户端缓存。Windows和macOS都会缓存网络凭据改完密码后可能仍然用旧密码认证导致登录失败。这时候要在Windows的“凭据管理器”里删除对应条目或者在macOS的钥匙串访问里删除。群晖侧也可以用smbstatus看当前连接但DSM默认可能没装完整Samba工具。最直接的办法是重启SMB服务synosystemctl restart smbd短密码还有一个隐藏风险日志里会记录登录失败但不会记录你用的是短密码还是长密码。如果你开了邮件通知频繁的失败登录会刷屏。我的经验是把自动封锁的阈值调到5次封锁时间设成30分钟这样既能防暴力又不会因为自己输错几次就把自己锁死。如果把自己锁了可以用另一个管理员账号登录DSM在 Auto Block 里解除封锁。最后再强调一次短密码只适合内网测试、临时演示、一次性账号。生产环境、远程访问、管理员账号一律用长密码加二次验证。免密登录虽然方便但私钥泄露的风险比短密码更大所以下一节我们把密钥体系讲透。3. SSH免密登录群晖密钥生成、下发与权限踩坑3.1 密钥生成ed25519还是RSA参数怎么选在管理机上生成密钥。管理机可以是你的笔记本电脑也可以是另一台Linux服务器甚至是一台群晖。我通常选一台常年开机的设备作为管理机。生成命令ssh-keygen -t ed25519 -a 100 -C nas-admin-key -f ~/.ssh/id_ed25519_nas参数解释-t ed25519指定密钥类型-a 100做100轮KDF增加暴力破解难度-C是注释建议写清楚用途和生成日期比如nas-admin-key-20250101-f指定私钥文件路径避免覆盖默认的id_ed25519。执行后会提示输入密码短语。如果这台管理机只用于自动化并且物理安全有保障可以直接回车留空如果多人使用一定要设密码短语然后用ssh-agent缓存。生成完成后会得到两个文件~/.ssh/id_ed25519_nas是私钥~/.ssh/id_ed25519_nas.pub是公钥。私钥权限必须是600公钥可以644。检查ls -l ~/.ssh/id_ed25519_nas* chmod 600 ~/.ssh/id_ed25519_nas chmod 644 ~/.ssh/id_ed25519_nas.pub如果你想用RSA命令是ssh-keygen -t rsa -b 4096 -C comment -f ~/.ssh/id_rsa_nas。RSA 4096兼容性最好但密钥更长认证时稍微慢一点。群晖DSM 7支持ed25519所以新环境我建议用ed25519。如果你有很老的NAS或网络设备只支持RSA再单独生成RSA密钥。还有一个细节如果你在群晖上生成密钥群晖的默认shell可能是ash或bashssh-keygen命令是有的。但群晖的家目录路径是/volume1/homes/用户名不是标准的/home/用户名。生成密钥前先确认当前用户的家目录echo $HOME如果输出/volume1/homes/admin那密钥就会放在/volume1/homes/admin/.ssh下。这个路径在DSM里是持久化的重启不会丢。如果$HOME是/root或/tmp就要小心可能重启后丢失。3.2 把公钥放到群晖ssh-copy-id、手动追加、权限修正最简单的方法是ssh-copy-idssh-copy-id -i ~/.ssh/id_ed25519_nas.pub admin192.168.1.10执行后会提示输入群晖密码成功后会看到“Number of key(s) added: 1”。但群晖默认可能没装ssh-copy-id你的管理机如果是macOS可能也需要手动安装。如果没有这个命令用下面这条手动追加cat ~/.ssh/id_ed25519_nas.pub | ssh admin192.168.1.10 umask 077; mkdir -p ~/.ssh; cat ~/.ssh/authorized_keys; chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys这条命令做了几件事umask 077保证新建文件默认只有属主可读写mkdir -p ~/.ssh创建目录cat 追加公钥不会覆盖已有公钥最后修正权限。为什么要追加而不是覆盖因为一台群晖可能有多个人、多台管理机需要免密登录覆盖会把别人的公钥删掉。追加之前最好先看看现有内容ssh admin192.168.1.10 cat ~/.ssh/authorized_keys如果文件不存在cat会报错没关系直接追加就会创建。但要注意群晖的用户家目录服务必须开启。路径是 Control Panel User Group Advanced User Home勾选 Enable user home service。如果这个服务没开~/.ssh可能指向一个临时目录或者根本不存在。开启后每个用户的家目录会在/volume1/homes/用户名下创建。这个设置对免密登录非常关键很多人卡在这里。权限是第二个大坑。OpenSSH对权限很严格.ssh目录必须是700authorized_keys必须是600家目录不能是777也不能是组可写。群晖上有时家目录权限是755这是正常的但如果变成775或777SSH会拒绝使用公钥。检查命令ls -ld ~ ~/.ssh ~/.ssh/authorized_keys正确输出类似drwxr-xr-x ... /volume1/homes/admin drwx------ ... /volume1/homes/admin/.ssh -rw------- ... /volume1/homes/admin/.ssh/authorized_keys如果.ssh目录是755改成700chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys如果家目录属主不对用管理员账号修正sudo chown -R admin:users /volume1/homes/admin注意users组是群晖的默认用户组不同版本可能不同可以用id admin查看。3.3 首次登录验证与常见报错公钥放好后在管理机上测试ssh -i ~/.ssh/id_ed25519_nas admin192.168.1.10如果还是提示输入密码说明公钥认证没生效。加-v看详细过程ssh -v -i ~/.ssh/id_ed25519_nas admin192.168.1.10重点看几行Offering public key表示客户端提供了公钥Server accepts key表示服务端接受了Authentication succeeded (publickey)表示成功。如果看到Permission denied (publickey,password)说明公钥被拒绝但密码认证还开着。这时候检查服务端配置sudo vi /etc/ssh/sshd_config确认这几项PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys有些教程会让你改AuthorizedKeysFile为绝对路径比如/volume1/homes/%u/.ssh/authorized_keys但群晖的%u展开可能和标准OpenSSH不同。我建议保持默认.ssh/authorized_keys前提是家目录服务已开启。改完配置后重启SSHsudo synosystemctl restart sshd如果synosystemctl不存在试sudo systemctl restart sshd或者sudo /usr/syno/bin/synosystemctl restart sshd重启后不要关闭当前会话另开一个终端测试。如果新终端登不上当前会话还能改回来。另一个常见问题是公钥内容被换行或截断。authorized_keys里每个公钥必须是一行以ssh-ed25519或ssh-rsa开头以注释结尾。如果你是从聊天工具复制的可能会多出空格或换行。检查awk {print NF, $1, $2} ~/.ssh/authorized_keys正常每个公钥有3个字段类型、Base64、注释。如果字段数不对说明格式有问题。注意关闭密码认证之前必须先用密钥登录成功并且保留至少一个已登录的SSH会话。群晖没有像某些Linux发行版那样的救援模式配置写错可能只能通过物理按键重置或重装DSM。4. 多台群晖免密登录从单点到批量管理4.1 统一管理机与SSH Config别名手里有多台群晖时第一件事是选一台管理机。管理机可以是你的主力电脑也可以是一台常开的Linux小主机甚至是一台群晖。我的习惯是用一台低功耗Linux机器做管理机专门跑备份脚本和Ansible。在这台管理机上生成一套密钥然后把公钥分发到所有群晖。这样你只需要记住一套密钥不用每台NAS都生成一次。接下来配置~/.ssh/config给每台NAS起别名。假设你有三台群晖IP分别是192.168.1.10、192.168.1.11、192.168.1.12端口都是22用户都是admin。配置如下Host nas-a HostName 192.168.1.10 User admin Port 22 IdentityFile ~/.ssh/id_ed25519_nas IdentitiesOnly yes Host nas-b HostName 192.168.1.11 User admin Port 22 IdentityFile ~/.ssh/id_ed25519_nas IdentitiesOnly yes Host nas-c HostName 192.168.1.12 User admin Port 22 IdentityFile ~/.ssh/id_ed25519_nas IdentitiesOnly yesIdentitiesOnly yes很重要。如果你有多个密钥SSH客户端可能会按顺序尝试尝试次数太多会被服务端拒绝。加上这个选项后客户端只用指定的密钥。配置好后测试ssh nas-a hostname ssh nas-b hostname ssh nas-c hostname如果每台都能返回主机名说明别名和免密都生效了。如果某台还要密码回到上一节检查公钥和权限。别名还有一个好处你可以用循环批量执行命令for h in nas-a nas-b nas-c; do echo $h ssh $h uptime done这个循环在写批量脚本时非常方便。如果你用Ansible~/.ssh/config里的别名也能直接用在inventory里。4.2 批量下发公钥shell循环与Ansible两种做法如果只有两三台群晖用shell循环就够了for h in 192.168.1.10 192.168.1.11 192.168.1.12; do echo $h ssh-copy-id -i ~/.ssh/id_ed25519_nas.pub admin$h done每台会提示输入一次密码。如果管理机没装ssh-copy-id用前面手动追加的命令改成循环PUB$(cat ~/.ssh/id_ed25519_nas.pub) for h in 192.168.1.10 192.168.1.11 192.168.1.12; do echo $h ssh admin$h umask 077; mkdir -p ~/.ssh; grep -q $PUB ~/.ssh/authorized_keys 2/dev/null || echo $PUB ~/.ssh/authorized_keys; chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys done这里加了grep -q判断避免重复追加。注意公钥里的特殊字符可能被shell解释所以用了单引号。如果你的公钥注释里有单引号要特别处理。如果群晖数量多或者你想把公钥管理纳入配置管理用Ansible更合适。Ansible不需要在群晖上安装客户端只要有SSH和Python就能跑。群晖DSM 7自带Python3但路径可能不在默认PATH里。先测试连通性[dsm] nas-a ansible_host192.168.1.10 ansible_useradmin nas-b ansible_host192.168.1.11 ansible_useradmin nas-c ansible_host192.168.1.12 ansible_useradmin保存为hosts.ini然后ansible dsm -i hosts.ini -m ping -k-k表示询问SSH密码。如果群晖的Python路径不对可能会报错。可以在inventory里指定[dsm:vars] ansible_python_interpreter/usr/local/bin/python3或者用raw模块绕过Pythonansible dsm -i hosts.ini -m raw -a mkdir -p ~/.ssh chmod 700 ~/.ssh echo ssh-ed25519 AAAA... your-comment ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys -k等免密登录生效后就可以不用-k直接用authorized_key模块批量管理ansible dsm -i hosts.ini -m authorized_key -a useradmin key{{ lookup(file,~/.ssh/id_ed25519_nas.pub) }}这条命令会把公钥追加到所有主机的admin用户下。如果你在龙蜥OS8这类标准Linux发行版上做过Ansible免密登录会发现套路完全一样只是群晖的Python路径和用户组名需要微调。4.3 多群晖之间的互信A到B、B到C、定时备份有时候免密登录不是从管理机到NAS而是NAS和NAS之间互相访问。比如NAS-A要把数据备份到NAS-BNAS-B要把日志同步到NAS-C。这种场景有两种做法第一种是每台NAS生成自己的密钥互相交换公钥第二种是选一台NAS作为管理机由它分发密钥。我倾向于第一种因为备份链路通常是固定的独立密钥泄露范围小。以NAS-A到NAS-B为例。先在NAS-A上以admin用户生成密钥ssh adminnas-a ssh-keygen -t ed25519 -a 100 -C nas-a-to-nas-b -f ~/.ssh/id_ed25519_backup然后把公钥追加到NAS-Bcat ~/.ssh/id_ed25519_backup.pub | ssh adminnas-b umask 077; mkdir -p ~/.ssh; cat ~/.ssh/authorized_keys; chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys测试ssh -i ~/.ssh/id_ed25519_backup adminnas-b hostname成功后就可以用rsync做备份rsync -avz --delete -e ssh -i ~/.ssh/id_ed25519_backup -p 22 /volume1/data/ adminnas-b:/volume1/backup/data/参数解释-a归档模式保留权限、时间、符号链接-v显示详细过程-z传输压缩--delete让目标目录和源目录保持一致源里删除的文件目标也删除。--delete要慎用第一次跑之前先用--dry-run看效果rsync -avz --delete --dry-run -e ssh -i ~/.ssh/id_ed25519_backup -p 22 /volume1/data/ adminnas-b:/volume1/backup/data/确认无误后再去掉--dry-run。在群晖上做定时任务可以用 Control Panel Task Scheduler新建“用户定义的脚本”把rsync命令写进去设置每天凌晨执行。脚本里最好加日志和退出码判断#!/bin/bash LOG/volume1/scripts/rsync_$(date %F).log rsync -avz --delete -e ssh -i /volume1/homes/admin/.ssh/id_ed25519_backup -p 22 /volume1/data/ adminnas-b:/volume1/backup/data/ $LOG 21 if [ $? -eq 0 ]; then echo OK $(date) $LOG else echo FAIL $(date) $LOG fi群晖的任务计划默认以root或指定用户运行注意脚本里的密钥路径要写绝对路径不要用~因为任务计划的环境变量可能和你登录时不一样。如果脚本跑失败先看日志再看sudo tail -f /var/log/auth.log里有没有SSH认证错误。4.4 关闭密码登录与限制来源当所有群晖都能用密钥登录后就可以考虑关闭密码认证。但这一步要非常谨慎。先在一台NAS上测试确认密钥登录稳定再批量操作。编辑/etc/ssh/sshd_configsudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sudo vi /etc/ssh/sshd_config修改以下项PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no PermitRootLogin no AllowUsers admin192.168.1.*AllowUsers限制只有内网网段的admin用户能登录。如果你有多个用户用空格分隔。改完重启sudo synosystemctl restart sshd重启前一定要保留一个已登录的SSH会话。重启后另开终端测试密钥登录成功后再关闭旧会话。如果测试失败旧会话还能把配置改回来。如果你的群晖暴露在公网关闭密码认证几乎是必须的但更根本的做法是不要直接暴露SSH端口通过内网访问或跳板机访问。群晖的防火墙也可以限制SSH来源IP路径是 Control Panel Security Firewall新建规则只允许管理机IP访问22端口。提示关闭密码认证后如果私钥丢失你还能通过DSM网页端登录重新生成密钥或临时开启密码认证。所以DSM管理员账号的强密码和二次验证一定要保留。5. 常见问题与排查技巧实录5.1 短密码相关故障速查短密码设置过程中最常见的问题是“网页端改不了”“命令改了不生效”“SMB登录失败”。下面这张表是我自己遇到过的场景和解决办法你可以对照排查。症状可能原因解决办法DSM网页端提示密码强度不足密码策略最小长度或复杂度未放开Control Panel User Group Advanced调整最小长度和复杂度管理员账号可能仍受限改用普通用户passwd命令拒绝短密码PAM的pwquality或cracklib限制备份后临时调整/etc/pam.d/下的minlen或改用synouser --setpwsynouser提示命令不存在路径未加入PATH使用/usr/syno/sbin/synouser绝对路径短密码改完SMB登录仍用旧密码客户端缓存了旧凭据Windows凭据管理器删除条目macOS钥匙串删除重启SMB服务短密码账号被自动封锁多次输错触发Auto Block用管理员账号登录DSM解除封锁调整阈值和封锁时间短密码账号无法SSH登录该账号没有SSH权限或PAM拒绝短密码账号建议不给SSH权限如果必须给检查AllowUsers和PAM短密码还有一个隐蔽问题DSM的密码历史记录。如果你设置了“记住最近5次密码”改回旧短密码可能被拒绝。这时候要么换一个没用的短密码要么临时把历史记录改成0改完再恢复。我的经验是短密码账号本来就是一次性的没必要在历史记录上纠结直接新建一个账号更省事。5.2 免密登录失败速查免密登录失败的原因很多但90%集中在权限、路径、配置这三类。下面这张表按出现频率排序。症状可能原因解决办法仍然提示输入密码公钥未生效或服务端未开启PubkeyAuthentication检查sshd_config确认PubkeyAuthentication yes用ssh -v看公钥是否被提供Permission denied (publickey).ssh或authorized_keys权限不对chmod 700 ~/.sshchmod 600 ~/.ssh/authorized_keys确保家目录不是组可写公钥追加后无效公钥被换行、截断或包含多余空格检查authorized_keys每行是否完整字段数是否为3只有第一次能登录重启后失效家目录服务未开启.ssh在临时目录Control Panel User Group Advanced开启User Home服务多台NAS中某台特别慢DNS反向解析或网络问题在sshd_config中设置UseDNS no重启SSHssh-copy-id命令不存在管理机未安装该工具用手动追加命令或用Ansible的authorized_key模块密钥正确但被拒绝服务端尝试次数用尽在客户端~/.ssh/config加IdentitiesOnly yes只提供指定密钥排查时我习惯按这个顺序先在客户端用ssh -vvv看详细日志确认公钥有没有被提供再在服务端看/var/log/auth.log确认服务端为什么拒绝然后检查权限和路径最后检查sshd配置。不要一上来就改配置先把日志读明白。群晖的日志可能在/var/log/auth.log也可能在/var/log/messages如果找不到用sudo find /var/log -name *auth*搜一下。还有一个坑DSM升级后sshd配置可能被重置或者用户家目录权限被改。升级前备份/etc/ssh/sshd_config和所有用户的authorized_keys。升级后如果免密登录失效先检查这两处。我的做法是把公钥备份到管理机的密码管理器或加密笔记里同时保留一份在群晖的共享文件夹里但共享文件夹权限要限制不能是公开共享。5.3 多群晖批量操作踩坑多台群晖批量操作时最容易踩的坑是主机名冲突和端口不一致。群晖默认主机名可能是DiskStation如果你有多台Ansible或脚本里用主机名区分会混乱。建议给每台NAS设置唯一主机名路径是 Control Panel Network General Server Name。SSH端口也可能不同有的用户为了减少扫描会把SSH改成2222或其它端口。批量脚本里要把端口作为变量不要写死22。另一个坑是known_hosts。当你重装DSM或更换IP后管理机的known_hosts里还保留旧指纹SSH会报“REMOTE HOST IDENTIFICATION HAS CHANGED”并拒绝连接。解决办法ssh-keygen -R 192.168.1.10或者删除~/.ssh/known_hosts里对应行。批量清理可以用循环for h in 192.168.1.10 192.168.1.11 192.168.1.12; do ssh-keygen -R $h doneAnsible场景下如果群晖没有Python或Python路径不对ping模块会报错。这时候可以用raw模块先做基础操作或者设置ansible_python_interpreter。群晖DSM 7的Python3路径通常是/usr/local/bin/python3但也可能因套件而变。用which python3确认。如果群晖上装了Python套件路径可能是/volume1/appstore/python3/bin/python3也要写进inventory。还有一个细节群晖的authorized_keys文件可能被DSM的某个服务重写。我遇到过在DSM升级后部分用户的.ssh目录权限变成755导致公钥认证失败。解决办法是写一个开机任务定期修正权限chmod 700 /volume1/homes/admin/.ssh chmod 600 /volume1/homes/admin/.ssh/authorized_keys但不要用root乱改属主否则DSM的Web服务可能无法读取用户文件。修正前先用id admin确认属主和组。5.4 我的避坑清单最后整理一份我自己的避坑清单都是实际踩过的坑。第一改任何SSH配置前先备份并且保留一个已登录会话。第二公钥只追加不覆盖追加前先grep判断是否已存在。第三私钥不要放在共享文件夹不要用邮件或聊天工具传输。第四短密码账号不要给管理员权限不要开SSH。第五多台NAS批量操作前先在一台上验证脚本再复制到其它机器。第六DSM大版本升级前导出用户列表和SSH配置升级后逐项验证。第七定期轮换密钥至少每年一次人员离职后立即撤销其公钥。这些经验看起来琐碎但每一条都对应一个真实的故障。免密登录本身不复杂复杂的是群晖的权限体系和用户家目录机制。你把权限、路径、配置这三样搞明白剩下就是重复劳动。6. 安全加固与长期维护让免密登录不变成后门6.1 密钥生命周期管理免密登录一旦配好很容易被遗忘。很多人配完就再也不管直到私钥泄露或者人员变动才想起来。我的做法是给每套密钥建立台账记录生成日期、用途、绑定的管理机、分发的NAS列表、公钥指纹。查看指纹ssh-keygen -lf ~/.ssh/id_ed25519_nas.pub输出类似256 SHA256:xxxx comment。把指纹记下来以后在NAS的authorized_keys里看到可疑公钥可以比对指纹。轮换密钥时先生成新密钥追加到所有NAS验证新密钥能登录再从authorized_keys里删除旧公钥。不要先删旧公钥否则新密钥有问题时会被锁在外面。删除公钥可以用sed或手工编辑ssh adminnas-a vi ~/.ssh/authorized_keys删除后保存权限会自动保留。如果是批量删除可以用Ansible的authorized_key模块指定stateabsentansible dsm -i hosts.ini -m authorized_key -a useradmin keyssh-ed25519 AAAA... old-key stateabsent私钥加密码短语后自动化脚本怎么用两种办法一种是用ssh-agent在脚本运行前把私钥加入agent另一种是生成一个专用的、无密码短语的部署密钥只允许执行特定命令。第二种更安全因为即使密钥泄露攻击者也只能执行受限命令。在authorized_keys里可以加限制commandrsync --server --sender -vlogDtpre.iLsfxC . /volume1/data/,no-port-forwarding,no-agent-forwarding,no-X11-forwarding ssh-ed25519 AAAA...这样该公钥只能用于rsync备份不能开shell。具体命令要根据你的rsync版本调整可以用rsync --server的日志来确认。这个功能在群晖上也能用但配置起来比较绕适合对安全要求高的场景。6.2 群晖侧面的加固免密登录只是SSH的一部分群晖本身的安全设置也要跟上。第一禁用默认admin账号创建一个新的管理员账号并开启二次验证。第二开启自动封锁和防火墙只允许内网访问DSM和SSH。第三关闭不需要的服务比如Telnet、FTP、SNMP减少攻击面。第四开启日志中心把SSH登录日志发送到另一台设备或邮件通知。第五定期检查authorized_keys看看有没有不认识的公钥。群晖的SSH登录日志可以用sudo tail -f /var/log/auth.log如果日志里出现大量Failed password或Invalid user说明有人在扫描。即使关闭了密码认证扫描仍然会消耗资源。可以用防火墙直接封掉非内网IP或者改SSH端口。改端口能减少日志噪音但不能替代防火墙。我的做法是SSH只监听内网IP如果群晖有多个网卡在sshd_config里加ListenAddress 192.168.1.10这样即使有公网IPSSH也不会监听在公网接口上。修改后重启sshd用netstat -tlnp | grep 22确认监听地址。二次验证方面群晖支持Google Authenticator兼容的OTP。开启后网页端登录需要输入动态码SSH登录如果配置PAM也可以要求动态码。但SSH免密登录和OTP会冲突密钥认证不需要密码自然也不会触发OTP。如果你既要免密又要二次验证可以用AuthenticationMethods publickey,keyboard-interactive但这会让自动化脚本无法运行。我的建议是管理机的私钥加密码短语SSH只允许内网OTP主要用于网页端和SMB不要在自动化SSH链路上强加OTP。6.3 自动备份脚本示例把前面的rsync命令封装成一个可复用的脚本放在管理机或群晖的任务计划里。下面是我在群晖上常用的备份脚本模板#!/bin/bash # 备份NAS-A的data目录到NAS-B # 需要提前配置好SSH免密登录 SRC/volume1/data/ DSTadminnas-b:/volume1/backup/data/ KEY/volume1/homes/admin/.ssh/id_ed25519_backup LOG_DIR/volume1/scripts/logs LOG_FILE$LOG_DIR/rsync_$(date %Y%m%d_%H%M%S).log mkdir -p $LOG_DIR echo 开始备份 $(date) $LOG_FILE rsync -avz --delete \ -e ssh -i $KEY -p 22 -o StrictHostKeyCheckingyes \ $SRC $DST $LOG_FILE 21 RET$? if [ $RET -eq 0 ]; then echo 备份成功 $(date) $LOG_FILE else echo 备份失败退出码 $RET $(date) $LOG_FILE fi # 只保留最近30天的日志 find $LOG_DIR -name rsync_*.log -mtime 30 -delete exit $RET在群晖任务计划里新建“用户定义的脚本”用户选择admin时间设成每天凌晨2点。脚本里的路径都要写绝对路径因为任务计划的环境变量和你SSH登录时不一样。如果脚本执行失败先看日志文件再看sudo tail -f /var/log/auth.log。StrictHostKeyCheckingyes表示严格检查主机指纹第一次连接前需要先把NAS-B的指纹加入known_hosts。可以用ssh-keyscan -p 22 192.168.1.11 ~/.ssh/known_hosts这样脚本就不会因为首次连接询问指纹而卡住。6.4 升级与迁移时的注意事项DSM大版本升级前我会做三件事备份/etc/ssh/sshd_config备份所有用户的~/.ssh/authorized_keys记录当前密钥指纹。升级后检查这三项。如果免密登录失效先对比配置文件再检查家目录权限。群晖升级有时会重置SSH服务把PasswordAuthentication改回yes这不算大问题但如果你之前关闭了密码认证升级后可能会重新打开需要再关一次。迁移到新群晖时用户和权限不会完全跟着硬盘走。如果你把硬盘从旧NAS移到新NASDSM会尝试保留数据但用户家目录和SSH配置可能需要手动恢复。最稳妥的做法是在新NAS上重新创建用户重新分发公钥然后用rsync把数据同步过去。不要直接把旧NAS的/etc/ssh目录复制到新NAS因为不同DSM版本的OpenSSH配置可能有差异容易导致SSH服务起不来。如果你用Ansible管理多台群晖升级后可以用ansible dsm -i hosts.ini -m ping快速检查连通性。如果某台失败先单独SSH登录排查。Ansible的raw模块在群晖Python路径变化时特别有用可以用它先修复Python路径或权限再恢复正常模块。我在几台群晖上跑了两年多的免密备份最大的体会是短密码和免密登录都不是一劳永逸的事。短密码账号要定期清理密钥要定期轮换配置要定期备份。每次DSM升级后花十分钟检查SSH和家目录权限比出问题后花两小时排查划算得多。如果你刚开始折腾建议先在一台测试机上把流程跑通记录每一步的输出和报错再复制到生产环境。这样即使遇到问题你也有对照不会手忙脚乱。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门