群晖NAS SSH安全加固实战:从密钥管理到主动防御 📅 2026/7/4 13:06:54 1. 项目概述为什么你的群晖SSH登录还不够安全如果你已经按照官方文档在群晖DSM里配置了SSH密钥登录并且觉得“这下安全了”那我得给你泼点冷水。常规的密钥对登录比如用RSA密钥只是把“密码”这个大门换成了“钥匙”但门锁本身SSH服务的配置、钥匙的管理方式依然存在大量可被攻击者利用的薄弱环节。我见过太多案例用户配置了密钥却因为默认端口、允许root登录、不限制尝试次数等配置导致NAS依然暴露在风险中。这个指南要解决的就是“进阶安全”问题。它面向的是那些不满足于基础设置希望将自家群晖NAS的SSH访问安全提升到接近企业级水准的用户。无论是存放家庭珍贵照片、个人工作文档还是作为小型团队的开发环境或轻量级服务器一次未授权的SSH入侵都可能导致数据泄露、文件被加密勒索甚至成为攻击内网其他设备的跳板。通过一系列组合拳式的配置我们将构建一个“纵深防御”体系让SSH服务从“能用”变得“坚不可摧”。核心价值在于你不仅会得到一套可复现的配置步骤更能理解每一步背后的安全逻辑。这样当你的网络环境或需求变化时你知道该如何调整而不是机械地照抄命令。2. 整体安全架构与设计思路在动手修改任何配置之前我们必须先建立一个清晰的防御模型。单纯的“启用密钥”是一个单点措施而真正的安全是一个体系。我的设计思路围绕三个核心原则最小权限、深度隐藏、主动防御。2.1 最小权限原则收紧每一道缝隙这是安全配置的基石。它的核心思想是只授予完成工作所必需的最小权限。在SSH上下文中这意味着用户层面禁止高权限账户如root直接登录强制使用普通用户登录后再提权。服务层面关闭所有不必要的SSH功能比如X11转发、端口转发除非你明确需要。网络层面仅允许来自可信IP地址或网络的连接。这样做的目的是即使某个环节被突破例如密钥意外泄露攻击者获得的权限和移动能力也会受到极大限制无法轻易扩大战果。2.2 深度隐藏原则降低被扫描发现的概率互联网上充斥着自动化扫描工具它们24小时不间断地扫描公网IP的常见端口如22。一旦你的NAS IP和SSH端口被识别就会进入攻击者的“目标清单”。深度隐藏就是修改默认端口将SSH服务从22端口移到一个高位随机端口。禁用协议版本关闭存在已知缺陷的SSH-1协议。伪装服务通过端口敲门等技术让端口在扫描时“隐身”。这相当于把你的家门从热闹的主干道搬进了一条需要特定暗号才能找到的小巷。2.3 主动防御原则实时监控与自动封禁前两者是被动加固主动防御则是建立响应机制。我们需要工具来监控登录尝试实时记录所有成功和失败的SSH登录事件。识别恶意行为自动分析日志将多次尝试失败、扫描特定用户等行为判定为攻击。执行封禁策略自动将攻击源IP地址加入防火墙黑名单在一段时间内阻止其所有连接。这套组合拳下来你的SSH服务从一个显眼的“默认服务”变成了一个隐蔽、坚固且具备反击能力的“安全堡垒”。3. 前置准备与密钥对强化管理在开始配置DSM之前我们需要在本地客户端生成更安全的密钥并做好备份。很多人直接用默认的ssh-keygen -t rsa这已经不够看了。3.1 生成更安全的Ed25519密钥对目前Ed25519算法在安全性和性能上均优于传统的RSA。它生成的密钥更短签名速度更快且被认为更能抵抗某些类型的密码学攻击。在你的本地电脑如Mac、Linux或Windows的WSL上打开终端执行ssh-keygen -t ed25519 -C “your_emailexample.com” -f ~/.ssh/synology_ed25519-t ed25519指定密钥类型。-C添加一个注释通常用邮箱便于识别密钥用途。-f指定密钥文件的保存路径和名称。这里我建议使用synology_ed25519这样的自定义名与默认的id_ed25519区分开方便管理多台服务器。接下来程序会提示你输入密钥的密码passphrase。这里极其关键请不要直接回车跳过注意这个密码是加密你本地私钥文件的与登录DSM的密码无关。即使别人拷贝了你的私钥文件没有这个密码也无法使用。请务必设置一个强密码。3.2 私钥的安全存储与备份策略生成的synology_ed25519是私钥synology_ed25519.pub是公钥。私钥是你的“终极钥匙”必须妥善保管。本地加密存储确保~/.ssh目录权限为700私钥文件权限为600。chmod 700 ~/.ssh chmod 600 ~/.ssh/synology_ed25519备份到离线介质将私钥文件以及你记得的密码备份到加密的U盘或离线硬盘中并物理保管好。不要存放在网盘或邮箱里。使用SSH-Agent管理为了避免每次使用都输入密码可以将私钥添加到ssh-agent。eval “$(ssh-agent -s)” ssh-add ~/.ssh/synology_ed25519输入一次密码后当前会话内就不再需要了。对于macOS系统钥匙串可以更好地集成管理。3.3 上传公钥至群晖DSM现在将公钥上传到你的群晖NAS。官方文档的方法是使用File Station但通过命令行更快捷前提是你目前还能用密码登录SSH。首先用你熟悉的方式如SCP、或DSM文件管理将公钥文件synology_ed25519.pub上传到NAS的某个临时位置比如/tmp/。通过SSH密码登录NAS。执行以下命令将公钥内容追加到授权文件。注意这里我们是为一个普通用户配置而不是root。# 假设你的普通用户名是 ‘admin_user‘ sudo mkdir -p /var/services/homes/admin_user/.ssh sudo cat /tmp/synology_ed25519.pub /var/services/homes/admin_user/.ssh/authorized_keys sudo chown -R admin_user:users /var/services/homes/admin_user/.ssh sudo chmod 700 /var/services/homes/admin_user/.ssh sudo chmod 600 /var/services/homes/admin_user/.ssh/authorized_keys这里有几个关键点路径是/var/services/homes/[用户名]/.ssh/而不是/home。这是群晖的特有目录结构。必须严格设置目录和文件的权限SSH服务对权限非常敏感权限过宽会直接拒绝密钥登录。完成这步后你可以尝试用密钥登录一次验证基础配置是否成功ssh -i ~/.ssh/synology_ed25519 -p 22 admin_useryour_nas_ip如果提示输入私钥密码passphrase后能登录说明密钥配对成功。4. DSM SSH 高级安全配置实战密钥能用只是第一步。现在我们通过SSH服务的配置文件实施一系列加固措施。DSM的SSH配置文件路径是/etc/ssh/sshd_config。修改前务必备份原文件sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup.$(date %Y%m%d)4.1 修改默认端口与协议限制用sudo vim /etc/ssh/sshd_config编辑文件找到并修改以下参数# 将端口改为一个 1024-65535 之间的随机数例如 59222 Port 59222 # 明确只监听IPv4如果你需要IPv6可添加一行 ‘Port 59222‘ 在 ‘AddressFamily inet6‘ 下 AddressFamily inet # 禁用不安全的SSH-1协议 Protocol 2 # 限制监听的具体IP。如果你不需要从所有网卡访问可以绑定内网IP例如 192.168.1.x # ListenAddress 192.168.1.10为什么改端口这能过滤掉99%的自动化脚本扫描它们通常只扫22端口。选择一个不常见的高位端口如5xxxx但避免使用已知服务端口。4.2 严格的身份验证与登录策略这是配置的核心部分直接决定谁、以及如何能登录。# 禁止root用户直接SSH登录。永远通过普通用户登录后su或sudo。 PermitRootLogin no # 启用公钥认证并禁用密码认证。这是我们的主要目标。 PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no # 如果你有多个用户需要SSH访问可以明确允许或拒绝列表 # AllowUsers admin_user deploy_user # DenyUsers guest some_user # 限制每个未加密连接的最大认证尝试次数。与Fail2ban配合效果佳。 MaxAuthTries 3 # 限制同一IP的最大并发连接数防止洪水攻击 MaxSessions 5 MaxStartups 5:50:10实操心得在将PasswordAuthentication设为no之前务必确保你的密钥登录已经100%可用。最好打开两个SSH会话一个用于修改配置另一个保持登录作为“救援通道”。修改并重启服务后用新会话测试密钥登录成功后再关闭旧会话。否则你可能被锁在外面。4.3 超时与隧道功能控制减少会话被劫持的风险并关闭不必要的功能。# 设置客户端活跃检查如果300秒内无活动则发送心跳包。如果发送2次无响应则断开连接。 ClientAliveInterval 300 ClientAliveCountMax 2 # 禁用所有隧道功能除非你明确需要它们进行端口转发。 AllowTcpForwarding no X11Forwarding no PermitTunnel no4.4 应用配置与防火墙联动修改完成后保存文件并重启SSH服务。sudo systemctl restart sshd重要由于我们修改了端口必须同步更新DSM防火墙和路由器如果需要从外网访问的规则。DSM防火墙进入“控制面板” - “安全性” - “防火墙”。编辑现有规则或新建一条规则允许来自特定IP或所有IP不推荐对TCP 59222端口的访问。路由器端口转发如果你需要从外网访问在路由器上将WAN口的59222端口转发到NAS内网IP的59222端口。强烈建议结合VPN使用避免将SSH端口直接暴露在公网。现在你的SSH连接命令需要指定新端口ssh -i ~/.ssh/synology_ed25519 -p 59222 admin_useryour_nas_ip5. 部署Fail2ban实现主动防御Fail2ban是一个日志分析工具能监控系统日志如SSH登录失败当发现恶意行为如多次密码尝试失败时自动调用防火墙规则封禁对应IP一段时间。DSM基于Linux可以安装Fail2ban。5.1 通过Docker安装Fail2ban这是对DSM系统侵入性最小、最易管理的方式。假设你已在DSM上安装了Docker套件。创建配置和日志目录在Docker共享文件夹如docker下创建fail2ban目录并在其内部创建jail.local和filter.d等子目录。/volume1/docker/fail2ban/ ├── data/ ├── jail.local └── filter.d/准备jail.local配置文件这是主要的配置。内容示例如下[DEFAULT] # 封禁时间秒24小时 bantime 86400 # 查找时间窗口秒 findtime 600 # 在查找时间窗口内最大失败次数 maxretry 5 # 封禁动作使用iptables banaction iptables-multiport # 日志路径容器内路径通过卷映射到宿主机 logpath /var/log/messages # 是否启用 enabled true [sshd] # 启用SSH防护 enabled true # SSH特定日志路径 logpath /var/log/ssh.log # 过滤器名称 filter sshd # 端口必须与你修改后的SSH端口一致 port 59222创建docker-compose.yml文件在fail2ban目录下创建此文件用于定义容器。version: ‘3.8‘ services: fail2ban: image: crazymax/fail2ban:latest container_name: fail2ban network_mode: “host” # 使用主机网络模式以便直接操作宿主机iptables cap_add: - NET_ADMIN - NET_RAW volumes: - /volume1/docker/fail2ban/data:/data # 数据持久化 - /volume1/docker/fail2ban/jail.local:/etc/fail2ban/jail.local:ro - /var/log:/var/log:ro # 挂载宿主机日志 - /var/run/docker.sock:/var/run/docker.sock:ro # 如果需要监控Docker容器日志 restart: unless-stopped关键点network_mode: “host”和cap_add是让Fail2ban能有效操作宿主机防火墙的关键。启动容器在SSH中进入/volume1/docker/fail2ban目录执行sudo docker-compose up -d5.2 验证Fail2ban运行状态查看容器日志确认运行正常sudo docker logs fail2ban查看当前被封禁的IPsudo docker exec fail2ban fail2ban-client status sshd你可以故意用错误密钥或密码从另一台机器尝试登录几次观察该IP是否会被加入封禁列表。被封禁后尝试连接会超时或直接拒绝。5.3 Fail2ban高级配置技巧多服务防护你可以在jail.local中为其他服务如DSM web登录、其他自建服务添加段落只需指定正确的logpath和filter。邮件通知配置Fail2ban在封禁IP时发送邮件通知你。需要在jail.local的[DEFAULT]部分设置mta、destemail等参数。白名单将你的家庭公网IP或信任的IP段加入ignoreip防止误封。[DEFAULT] ignoreip 127.0.0.1/8 192.168.1.0/24 你的公网IP6. 终极隐藏端口敲门与双因子认证对于安全要求极高的场景可以进一步实施这两项措施。6.1 端口敲门端口敲门Port Knocking的原理是SSH端口默认关闭。客户端需要按特定顺序“敲击”连接一系列预先定义好的封闭端口服务端监听到这个正确的序列后才动态打开SSH端口一段时间。这需要你在路由器或NAS上运行一个守护进程如knockd。由于配置较为复杂且可能影响可用性仅建议高级用户在对公网暴露服务时考虑。一个简单的实现思路是使用Docker运行knockd镜像并配置iptables规则。6.2 SSH双因子认证在密钥的基础上再增加一层动态验证码如Google Authenticator。这实现了“你拥有的东西私钥 你知道的东西动态码”的双重认证。在DSM上实现相对麻烦因为需要编译PAM模块。更可行的方案是不直接加固DSM本身的SSH而是建立一个跳板机。在一台专门的低权限Linux虚拟机或容器上配置超强的SSH安全策略包括双因子所有外部访问先连接到这台跳板机通过严格认证后再从跳板机通过密钥连接到内网的群晖NAS。这样NAS的SSH服务甚至可以完全不对公网暴露。7. 日常维护、监控与故障排查安全配置不是一劳永逸的需要持续的观察和维护。7.1 关键日志监控位置SSH认证日志/var/log/ssh.log或journalctl -u sshd。重点关注Failed password和Accepted publickey条目。Fail2ban日志/volume1/docker/fail2ban/data/log/fail2ban.log根据你的挂载路径。查看封禁和解封记录。DSM系统日志控制面板里的“日志中心”查看“连接”日志。我习惯每周快速扫一眼这些日志了解是否有异常扫描或攻击尝试。7.2 常见问题与排查技巧问题1配置密钥后依然提示需要密码。排查检查DSM上authorized_keys文件的权限必须是600和所属用户。使用ssh -v查看详细连接过程通常在输出末尾会提示失败原因如“Permission denied (publickey)”可能伴随具体错误。问题2修改SSH端口后无法连接。排查确认sshd_config中Port设置已保存。确认已执行sudo systemctl restart sshd重启服务。确认DSM防火墙和路由器防火墙如适用已放行新端口。使用sudo netstat -tlnp | grep sshd命令查看sshd进程实际监听的端口号。问题3Fail2ban没有封禁攻击IP。排查检查Fail2ban容器是否正常运行sudo docker ps | grep fail2ban。检查jail.local中logpath指向的日志文件是否正确且容器有权限读取。检查filter是否匹配日志中的失败信息。可以手动测试sudo docker exec fail2ban fail2ban-regex /var/log/ssh.log /etc/fail2ban/filter.d/sshd.conf。确认宿主机防火墙是iptables因为network_mode: host下容器操作的就是宿主机iptables。问题4把自己锁在外面了。这是最糟糕的情况。预防永远比补救重要。预防在应用PasswordAuthentication no之前务必用两个独立会话测试密钥登录。确保DSM的另一个管理员账户也配置了密钥。补救如果物理上能接触到NAS可以通过连接显示器、键盘直接登录部分机型支持。或者群晖有更底层的“救援模式”或可以通过Synology Assistant进行本地网络重置但这可能会影响部分设置需查阅官方文档。7.3 备份与恢复策略配置文件备份定期备份/etc/ssh/sshd_config和你的jail.local等配置文件。密钥备份如前所述私钥的离线备份至关重要。文档记录记录下你修改的所有非默认端口号、允许的用户列表、白名单IP等。一旦需要重建环境这些信息能节省大量时间。经过以上从密钥管理、服务配置、主动防御到高级隐藏的层层加固你的群晖SSH服务已经能够抵御绝大多数自动化攻击和针对性渗透。安全是一个持续的过程保持系统更新、定期审查日志、紧跟安全社区动态才能让你的数字堡垒长久稳固。这套配置方案的核心思想可以迁移到任何Linux服务器上它教给你的不是一堆命令而是一套构建安全访问体系的方法论。