一直是使用 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