把 AMH 备份通过 SFTP 保存到 Mac mini 的一次整理记录

最近在整理家里的 Mac mini 服务器时,把 AMH 面板生成的备份文件通过 SFTP 保存到 Mac mini 上,并顺手做了自动保留策略。这个过程看起来只是“把备份传到另一台机器”,但实际涉及外网入口、SFTP 账号、备份目录、macOS 定时任务和权限限制。

这篇文章记录一下完整思路:为什么选择 SFTP,Mac mini 端怎么接收备份,备份文件怎么清理,以及这次踩到的 macOS 后台任务权限问题。出于安全考虑,文中不写具体域名、端口、账号和完整目录。

为什么不用 SMB 直接暴露到公网

Mac mini 在家里承担了一部分家庭服务器职责,本地可以通过 SMB 做文件共享。但把 AMH 备份从外部服务器传回家里时,我没有选择把 SMB 端口暴露到公网。

原因很直接:SMB 更适合局域网文件共享,不适合作为公网入口。把 SMB 暴露出去,安全风险和后续维护成本都比较高。相比之下,SFTP 基于 SSH,认证和传输都更适合作为外网文件传输入口。

整体方案

最终采用的结构是:AMH 所在服务器通过 SFTP 连接家里的 Mac mini,把备份文件上传到 Mac mini 的专用备份目录。家里的路由器只开放一个自定义外部端口,并转发到 Mac mini 的 SSH 服务。

这个方案里有几个关键点:

  • 公网入口只用于 SFTP,不开放 SMB;
  • 外部端口使用自定义端口,不直接暴露默认习惯配置;
  • Mac mini 上准备专用目录接收 AMH 备份;
  • 备份文件落地后,由 Mac mini 本机负责定期清理旧文件。

这样做的好处是职责清楚:AMH 只负责生成和上传备份,Mac mini 负责保存和整理备份,本地磁盘空间由 Mac mini 的保留策略控制。

备份文件的命名规则

AMH 生成的备份文件名里包含日期和时间,大致类似下面这种格式:

YYYYMMDD-HHMMSS.tar.gz.amh

这个文件名格式有一个好处:按文件名排序,基本就等于按时间排序。后面做自动清理时,可以直接利用这一点保留最新的若干份备份。

为什么还要做自动清理

备份最容易出现的两个问题,一个是没有备份,另一个是备份一直堆积直到磁盘被占满。AMH 备份文件如果长期保留,每天积累下来会占用越来越多空间。

所以这次没有只停留在“能上传成功”,而是同时加了一条保留策略:只保留最新 30 份 AMH 备份,删除更早的匹配文件。

清理规则如下:

  • 只处理 AMH 备份专用目录;
  • 只匹配符合命名规则的 .tar.gz.amh 文件;
  • 保留最新 30 份;
  • 超过数量后,按文件名时间删除更早的旧备份。

清理脚本的思路

清理脚本没有直接删除目录下所有旧文件,而是先做了几个限制:

  • 只检查备份目录当前这一层,不递归处理其他目录;
  • 只匹配指定后缀的 AMH 备份文件;
  • 文件名必须符合日期加时间的格式;
  • 先排序,再删除超出保留数量的旧文件;
  • 每次运行都会写日志。

这样可以避免误删不相关文件。比如目录里临时放了说明文档、手动导出的压缩包或其他测试文件,只要文件名不符合规则,就不会被清理脚本处理。

脚本还支持 dry run,也就是只预览会删除哪些文件,不实际删除。这一点在第一次上线清理任务时很有用,可以先确认匹配结果没有问题,再正式执行。

用 macOS 后台任务每天自动运行

Mac mini 上的自动任务使用 macOS 自带的后台任务机制管理。AMH 备份清理任务设置为每天凌晨运行,避开日常使用和备份上传的高峰时间。

这里有一个很重要的经验:不要直接让后台任务从“文稿”目录运行脚本,也不要把自动运行日志写回“文稿”目录。macOS 对后台任务访问用户文档目录有隐私权限限制,直接这样做很容易遇到 Operation not permitted。

最终的处理方式是:项目目录里的脚本作为维护源文件;真正让后台任务执行的脚本副本放到用户脚本目录;自动运行日志写到用户日志目录。这样结构更符合 macOS 的习惯,也更容易长期稳定运行。

这次踩到的权限问题

排查过程中,自动任务曾经出现过类似这样的错误:

Operation not permitted

这个错误不一定代表脚本写错了,更常见的原因是 macOS 隐私权限拦截了后台任务。尤其是脚本在读取外接数据卷目录,或者从受保护的用户目录执行、写日志时,更容易触发限制。

如果移动脚本和日志位置后仍然无法读取备份目录,就需要到“系统设置 -> 隐私与安全性 -> 完全磁盘访问权限”里给实际执行脚本的 shell 程序授权,然后重新触发任务或等待下一次自动运行。

验证方式

上线这种自动清理任务时,我会分三步验证:

  1. 先确认 SFTP 能把 AMH 备份上传到 Mac mini;
  2. 再用 dry run 检查清理脚本会匹配哪些文件;
  3. 最后看自动任务日志,确认它能在计划时间运行并写入结果。

当备份数量没有超过 30 份时,脚本会记录“无需删除”。这也是正常结果,说明它已经能看到目录并识别备份文件。等数量超过保留上限以后,它才会开始删除更早的文件。

最终形成的方案

整理后,这套 AMH 备份到 Mac mini 的方案可以概括为:

  1. 公网入口只开放 SFTP,不开放 SMB;
  2. 路由器只转发一个自定义 SFTP 入口到 Mac mini;
  3. AMH 服务器定期把备份上传到 Mac mini 的专用目录;
  4. 备份文件使用带日期时间的固定命名格式;
  5. Mac mini 每天自动清理旧备份;
  6. 只保留最新 30 份,避免备份无限占用磁盘;
  7. 脚本和日志放在适合后台任务运行的位置,减少 macOS 权限问题。

小结

这次整理的重点,不只是让 AMH 备份能传到 Mac mini,而是把“传输、落地、保留、日志、权限”这几件事串起来。SFTP 负责安全传输,专用目录负责存放备份,后台任务负责定时清理,保留策略负责控制磁盘占用。

家庭服务器里的备份方案,最怕只做半截。能上传只是第一步;能长期自动运行、出问题能看日志、磁盘不会被旧备份塞满,才算是真正可维护。