一直是使用 samba 服务作为 NAS,移动硬盘插在 mac 上作为 TimeMachine 备份盘,但这样还是太笨拙了。
为了实现无线备份,一种方法是购买 Apple TimeCapsule,另一种则是利用 Linux 设备来搭建 Netatalk  服务器。正好又一台闲置的 Ubuntu 机器,于是就决定采用这种方式。
Netatalk  是一个开源的 AppleTalk 通信协议的实现,可以通过在 Linux 系统上搭建 Netatalk 服务来作为 macOS 设备的 AFP 服务器、AppleTalk 路由等等。结合 avahi  服务,可以达到 Apple 原生设备的效果。
本文基于 Ubuntu 18.04 环境搭建,其他环境配置类似。
 
硬盘挂载与配置 查看已连接的硬盘 1 2 3 4 5 $ fdisk -l   								 ... /dev/sdb3  649940992 976773119 326832128 155.9G Apple HFS/HFS+   											 
 
HFS + 分区关闭 journal Mac 的 HFS + 分区一般都默认开启 journal 功能,因为 Linux 不支持读写 journaled HFS+,所以必须关闭这个功能。
可以把硬盘连接到 mac 操作
1 2 3 4 5 6 7 $ diskutil disableJournal disk0s2        Journaling has been disabled on disk0s2   $ diskutil enableJournal disk0s2 Journaling has been enabled on disk0s2 
 
或者直接在 linux 上操作,通过下载 journalling_off.c 源码编译运行来关闭
1 2 3 4 5 6 7 $ cd  /tmp $ curl https://pastebin.com/raw/W8pfgHRe -o journalling_off.c $ gcc journalling_off.c -o journalling_off $ sudo ./journalling_off/dev/sdb3   	 </code>sudo ./journalling_off/dev/sdb3 attributes = 0x80002100  journal has been disabled. 
 
如果网速不好,源码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include  <stdio.h>  #include  <stdlib.h>  #include  <unistd.h>  #include  <sys/types.h>  #include  <sys/mman.h>  #include  <fcntl.h>  #include  <byteswap.h>        int  main (int  argc, char  *argv []) {         int  fd = open (argv [1 ], O_RDWR);         if (fd < 0 ) {                 perror ("open" );                 return  -1 ;         }                 unsigned  char  *buffer = (unsigned  char  *) mmap (NULL , 2048 , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );         if (buffer == (unsigned  char *)0xffffffff ) {                 perror ("mmap" );                 return  -1 ;         }                 if ((buffer [1024 ] != 'H' ) && (buffer [1025 ] != '+' )) {                 fprintf (stderr , "% s: HFS+ signature not found -- aborting.\n" , argv [0 ]);                 return  -1 ;         }                 unsigned  long  attributes = *(unsigned  long  *)(&buffer [1028 ]);         attributes = bswap_32 (attributes);         printf ("attributes = 0x%8.8lx\n" , attributes);                 if (!(attributes & 0x00002000 )) {                 printf ("kHFSVolumeJournaledBit not currently set in the volume attributes field.\n" );         }                 attributes &= 0xffffdfff ;         attributes = bswap_32 (attributes);         *(unsigned  long  *)(&buffer [1028 ]) = attributes;                 buffer [1032 ] = '1' ;         buffer [1033 ] = '0' ;         buffer [1034 ] = '.' ;         buffer [1035 ] = '0' ;                 buffer [1036 ] = 0 ;         buffer [1037 ] = 0 ;         buffer [1038 ] = 0 ;         buffer [1039 ] = 0 ;                 printf ("journal has been disabled.\n" );         return  0 ; } 
 
挂载 1 2 3 $ sudo mkdir  /mnt/timemachine					 $ sudo mount  -t hfsplus -o force,rw /dev/sdb3 /mnt/timemachine   		 												 
 
Netatalk 编译安装与配置 由于 apt 上的 Netatalk 的版本太老,所以选择编译安装。 
编译 安装依赖库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ sudo apt install -y \ build-essential \ libevent-dev \ libssl-dev \ libgcrypt-dev \ libkrb5-dev \ libpam0g-dev \ libwrap0-dev \ libdb-dev \ libtdb-dev \ avahi-daemon \ libavahi-client-dev \ libacl1-dev \ libldap2-dev \ libcrack2-dev \ libdbus-1-dev \ libdbus-glib-1-dev \ libglib2.0-dev 
 
安装 checkinstall 
1 $ sudo apt install --yes  checkinstall 
 
也可以通过 下载 deb 包  来安装
1 2 $ cd  /tmp && curl http://archive.ubuntu.com/ubuntu/pool/universe/c/checkinstall/checkinstall_1.6.2-4ubuntu2_amd64.deb $ sudo dpkg -i checkinstall_1.6.2-4ubuntu2_amd64.deb 
 
设置环境变量
1 2 $ NETATALK_VERSION='3.1.11'  $ MAINTAINER='maywzh \<maywzh@gamil.com\>'   
 
下载 netatalk 源码
1 2 3 $ wget http://prdownloads.sourceforge.net/netatalk/netatalk-${NETATALK_VERSION} .tar.gz -P /tmp tar -xzf /tmp/netatalk-${NETATALK_VERSION} .tar.gz -C /tmp $ cd  /tmp/netatalk-${NETATALK_VERSION}  
 
编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ ./configure \ --with-init-style=debian-systemd \ --without-libevent \ --with-cracklib \ --enable-krbV-uam \ --with-pam-confdir=/etc/pam.d \ --with-dbus-daemon=/usr/bin/dbus-daemon \ --with-dbus-sysconf-dir=/etc/dbus-1/system.d $ make $ sudo checkinstall -D \ --pkgname='netatalk'  \ --pkgversion="${NETATALK_VERSION} "  \ --maintainer="${MAINTAINER} "  \ $ make install 
 
安装 安装依赖
1 2 3 4 5 6 7 8 9 10 11 $ sudo apt install -y \ avahi-daemon \ cracklib-runtime \ db-util \ db5.3-util \ libtdb1 \ libavahi-client3 \ libcrack2 \ libcups2 \ libpam-cracklib \ libdbus-glib-1-2 
 
安装编译包
1 2 $ sudo dpkg -i netatalk_3.1.11-1_amd64.deb $ sudo ldconfig 
 
检查安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ netatalk -v netatalk 3.1.11 - Netatalk AFP server service controller daemon This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Please see the file COPYING for  further information and details. netatalk has been compiled with support for  these features:       Zeroconf support:	Avahi      Spotlight support:	No                   afpd:	/usr/local/sbin/afpd             cnid_metad:	/usr/local/sbin/cnid_metad               afp.conf:	/usr/local/etc/afp.conf     netatalk lock file:	/var/lock/netatalk 
 
配置 配置文件 1 $ vim /usr/local/etc/afp.conf   
 
想深入了解配置请参考 官方文档 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [Global]   mimic model = AirPort               #指定在 macOS 的 Finder 显示的图标   log level = default:warn   log file = /var/log/afpd.log   hosts allow = 192.168.50.0/24       #子网 允许访问的主机地址,根据需要自行修改   hostname = M-AFP             		# 主机名 随意设置  uam list = uams_dhx.so uams_dhx2.so #默认认证方式 用户名密码登录 参看官方文档   [Homes]   basedir regex = /home               #用户的 Home 目录   [TimeMachine]   path = /mnt/TimeMachine             #数据目录   time machine = yes                  #yes 才支持 TimeMachine   spotlight = no                      #关闭 spotlight 索引   vol size limit = 155000             #限制 TimeMachine 存储容量,单位为 MB ;[Files]  							# ; 注释  ;path = /mnt/files                  #设置普通 afp 目录  
 
权限设置 创建一个新用户,用于访问 AFP 服务
1 2 $ useradd afp     $ paaswd afp      
 
Avahi 配置安装 Avahi 是一个开源项目,用于让 mac 在局域网自动发现 Linux AFP 服务器,具体可参看项目地址 https://github.com/lathiat/avahi。 
安装 这个简单,直接 yum 就行
1 $ sudo apt install avahi -y   
 
配置 配置文件位置在 /etc/avahi/services/afpd.service
1 $ vim /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'?>    <!DOCTYPE service-group  SYSTEM  "avahi-service.dtd" >    <service-group >    <name  replace-wildcards ="yes" > DUKE-NAS-AFP</name >   <service >    <type > _afpovertcp._tcp</type >    <port > 548</port >    </service >    <service >    <type > _device-info._tcp</type >    <port > 0</port >    <txt-record > model=Xserve</txt-record >    </service >    </service-group >   
 
服务启动 1 2 3 4 $ sudo systemctl start avahi-daemon   $ sudo systemctl start netatalk   $ sudo systemctl enable  avahi-daemon   $ sudo systemctl enable  netatalk   
 
查看 netatalk 和 avahi 端口是否启动监听,afp 监听 548 端口 请注意 Linux 防火墙问题,将对应端口放行
 
至此, netatalk 部署完成。
参考 
Install Netatalk 3.1.11 on Ubuntu 18.04 Bionic  
Zero-configuration networking