通过 Netatalk 在 ACRH17 上使用 Time Machine

tech

This article was last updated on <span id="expire-date"></span> days ago, the information described in the article may be outdated.

因为家里的老 2.4GHz 路由器和蓝牙的冲突太严重了,每次使用 AirPods Pro 听歌,我的 MacBook Pro 就断流严重;所以决定买一个新的 5GHz 路由,当时想到的需求有:

  1. 家里只有 3 台设备,面积也很小,所以不需要太强的信号功率以及天线数量
  2. 能够在官方渠道买到 - 说这个是因为有朋友推荐什么 K2?
  3. 能够使用第三方固件,方便给家里人一起自由使用网络
  4. 支持 USB 口的外接存储,能够配合第三方固件使用 Time Machine 进行备份

在朋友的推荐之下选择了这款 ACRH17 路由。

买来新的路由器之后第一件事就是刷了 Merlin 固件,前三点都很好实现;但是第三方固件刷入之后官方的 Time Machine 支持却消失了。

在一番查找之后决定安装 Netatalk 服务启用 AFP 协议的支持,这是一个基于 Linux 的开源 AFP 实现,它依赖几个包使用:

  1. dbus - 一条软数据总线,用于不同进程之间的数据交换
  2. avahi - 这是一种零配置的广播服务,相信大家对 Bonjour 服务或多或少了解过
  3. netatalk - 这是我们今天的主角

在进行安装之前,我们有几个准备工作需要做:

  1. 准备我们的 Time Machine 磁盘进行分区格式化

  2. 扩展 JFFS 分区 - ACRH 默认的 JFFS 分区是内置的只有 15MB,在第三方固件下不仅无法启用软件中心,并且我们需要安装的这些包至少需要占用 40MB 的空间,所以我们需要对 JFFS 分区进行扩展

  3. 安装 entware 和软件包环境 - 我们需要安装的依赖需要一个 entware 包管理器进行管理

接下来我们就开始吧!


准备工作

准备 Time Machine 磁盘

首先准备一块磁盘,我们的 Time Machine 最好准备两倍于磁盘大小的的分区,我这里使用了一个 500GB 的机械硬盘,并分区,因为在 ACRH17 上只有一个 USB 接口,所以后期我们的 JFFS 分区也需要拓展到这上面,所以我们需要对这块硬盘进行两个分区:

  • 一个小的 ext4 分区,用于拓展 JFFS,我给了 5 GB
  • 剩下大小分成一个区,格式需要 NTFS/etx4,不过听说 NTFS 的支持有问题,于是我格式化为了 ext4

有的朋友可能想在路由上做这件事,我不建议,因为这可能会花你很多时间,路由器的性能不好,并且用命令行还是不如 GUI 界面方便嘛。

拓展 jffs 分区

在磁盘准备完成之后,我们就开始拓展 JFFS 分区,它的原理是:

在内置的 JFFS 分区的 scripts 目录下放置脚本,这些脚本在 boot 时会自动执行,脚本将我们的给定分区重新挂载到 JFFS 分区并复制内容

使用方式就是在 /jffs/scripts 复制两个脚本:

  • post-mount - 用于挂载分区并复制内容,内容很长,我放在了 OSS 上,大家可以下载

    1
    wget https://oss.init.blog/scripts/post-mount
  • unmount - 用于反挂载

    1
    2
    3
    4
    #!/bin/sh

    kill -9 $(pidof skipd)
    cd /koolshare/perp && sh perp.sh stop
  • 对上面的两个脚本给定运行权限

    1
    2
    chmod a+x post-mount
    chmod a+x unmount

  • 最后在我们新的 JFFS 扩展分区创建 jffs 文件夹,以便脚本能够识别我们要使用哪个分区进行扩展

    1
    mkdir /mnt/xxx/jffs

    这里把 xxx 换成你的卷标即可

最后重启,我们就能看到分区以及被挂载:

在管理页面也能够看到分区被扩展:

安装 Entware 以及环境

网上都说 Merlin 固件自带 Entware 的安装脚本 entware-install.sh,如果有的话,可以这样安装:

1
entware-setup.sh

但是我这个三方固件中没有,所以我们需要手动安装

1
2
3
4
5
6
7
8
9
mkdir /jffs/entware-ng.arm
ln -nsf /jffs/entware-ng.arm /tmp/opt
wget -O - http://pkg.entware.net/binaries/armv7/installer/entware_install.sh | /bin/sh
echo "#!/bin/sh" > /jffs/scripts/services-start
echo "ln -ns /jffs/entware-ng.arm /tmp/opt" >> /jffs/scripts/services-start
echo "/opt/etc/init.d/rc.unslung start" >> /jffs/scripts/services-start
echo "#!/bin/sh" > /jffs/scripts/services-stop
echo "/opt/etc/init.d/rc.unslung stop" >> /jffs/scripts/services-stop
chmod a+rx /jffs/scripts/*

这个脚本做的主要事情就是安装 entware,并且将其链接到 /opt/etc 目录,这样我们就可以使用其中的组件;之后在管理脚本中添加了启用和禁用的功能。

最后我们安装 busybox 和 vim 包,方便后面的使用:

1
2
3
opkg update
opkg install busybox
opkg install vim

安装 Netatalk 及其环境

安装配置 dbus

这个包有些 ROM 内置有安装,有些没有,我们需要分情况处理

  • 如果系统 ROM 内已经安装,那么我们就无需再次安装了,需要配置用户/用户组:

    1. 查看配置文件 /etc/dbus-1/system.conf:

      1
      2
      <!-- Run as special user -->
      <user>nobody</user>

      修改你的用户名为 <user> 节点内的用户,或者创建一个用户

    2. 查看配置文件 /etc/dbus-1/system.d/*.conf:

      1
      2
      3
      <policy group="lp">
      <allow send_destination="org.bluez"/>
      </policy>

      查看 group 属性,并新建用户组,例如这里:

      addgroup lp

  • 很多 ROM 内置的没有安装,那么使用 opkg install dbus 安装,并在下面的配置文件中的修改对应属性为你现在使用的用户名:

    /opt/etc/dbus-1/system.conf

重启,使用命令进行测试:

1
dbus-daemon --session --print-address --fork --print-pid

当看到类似这样的输出就说明配置成功了:

1
2
unix:abstract=/tmp/dbus-CSy0dphkTM,guid=24e009e82bece7928f58cc4b5b39c4f6
2900

这说明我们的 dbus 已经可以成功创建虚拟总线。

安装配置 avahi

我的这个第三方固件很奇怪,内置的也有 avahi 服务,并且是可以启用的,但是我找了半天也没有找到他使用的配置文件,并且 afpd 服务也事实上不能正常使用,于是我还是使用 opkg 安装了 avahi 包

使用包管理器安装:

1
opkg install avahi-daemon avahi-utils

这个 avahi 包需要一个叫 nobody/nogroup 的用户与组身份运行 daemon 守护进程,大家根据情况运行创建用户用户组的命令就好:

1
2
adduser nobody
addgroup nogroup

之后我们创建一个 avahi 的服务配置文件 /opt/etc/avahi/services/afpd.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_afpovertcp._tcp</type>
<port>548</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=TimeMachine</txt-record>
</service>
</service-group>

这指定守护进程监听 548 端口,之后我们重启服务即可:

1
/opt/etc/init.d/S42avahi-daemon restart

如果遇到问题发现不能启动,或者启动之后使用 check 发现守护进程 dead 了,那么使用 avahi-daemon --debug 命令查看错误日志,一般都是因为 dbus 的服务出现问题。

安装配置 netatalk

安装很简单:

1
opkg install netatalk

编辑配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Global]
; 路由器的 IP 地址
afp listen = 192.168.50.1
; 执行 hostname 命令查看
hostname = hostname
uam list = uams_guest.so uams_dhx.so uams_dhx2.so
uam path = /opt/lib/uams
mimic model = TimeCapsule6,106
; 和上面一样指定域
hosts allow = 192.168.50.0/16
; 禁用客人登录
; guest account = bobody

[TimeMachine]
; TimeMachine 盘的路径
path = /mnt/TM
; TimeMachine 用户
valid users = timemachine
time machine = yes
cnid scheme = dbd
ea = auto
file perm = 0664 directory perm = 0775

我们需要给 Netatalk 服务创建一个新的用户,我这里用户名是 timemachine

1
adduser timemachine

把新建的用户添加到你的管理员组:

1
adduser -G timemachine admin

重启服务:

1
/opt/etc/init.d/S27afpd restart

在 macOS 上挂载并开始备份

上面的步骤如果没有错误,那么就可以挂载磁盘了,在 FInder 中使用 Ctrl+K 连接到我们的 afpd 服务,在连接时输入刚刚创建的 timamachine 用户名和密码:

之后在 FInder 中就可以看到挂载成功的磁盘:

右边的是 afpd 服务,左边的是 smb 服务,哈哈,库克就觉得 Windows 真的丑 :)

之后在 Time Machine 中就可以指定刚刚的磁盘并开始备份了,首次备份比较久,我花了一个晚上,速度可以用 30MB/s 左右,换算过来大概是 200Mbps 的速度:

但至少我们不用再每天拔插硬盘备份了,折腾一次还是比较有意义的:

之前看到网上说可以用 smb 服务创建虚拟镜像盘进行备份,我尝试过,并不可行,并且想想在 Linux 系统是使用 smb 服务就感觉不靠谱。

祝大家使用愉快 :)

Author: 桂小方

Permalink: https://init.blog/time-machine-netatalk-acrh17/

文章许可协议:

如果你觉得文章对你有帮助,可以 支持我

Comments