协议简介
| 协议 | macOS 支持 | 性能表现 |
|---|---|---|
| AFP | 已弃用 | 自 2013 年(OS X 10.9)苹果宣布弃用自家的 AFP,不再推荐使用。 |
| SMB | 亲儿子 | macOS 的第一优先、系统默认的文件共享协议,大部分情况都能正常工作,但是在密集型操作经常出现问题。 |
| NFS | 兼容可用 | 能稳定使用的版本只支持到 NFSv3,但也能提供比 SMB 更好的稳定性。 |
SMB
SMB 是 macOS 默认的网络协议,因此在生态体验上苹果做了很多的优化。
- 网络邻居与自动发现:局域网内的 SMB 共享可用通过 mDNS/Bonjour 自动出现在访达的侧边栏。
- 密码与钥匙串整合:SMB 共享密码可用直接保存在 macOS 钥匙串中。
- macOS 专有元数据:标签、颜色、拓展属性等 macOS 极度依赖的拓展属性支持,SMB 配合服务端的 vfs_fruit 模块,能完美原生处理 macOS 的元数据。
已知缺陷:
- 在文件夹中包含大量文件、持续高带宽读写工作负载下会出现性能下降,甚至连接异常断开问题。
- 元数据操作(文件列表、文件创建、文件删除)的速度明显偏慢。
优化措施:
Turn off packet signing for SMB 2 and SMB 3 connections - Apple Support
Adjust SMB browsing behavior in macOS - Apple Support
NFS
SMB 因为支持 macOS 完整生态,每次读取需要疯狂的请求各种元数据,尤其是网络受限环境中会加重延迟,经常出现彩虹圈。NFS 因为 macOS 没有做深度的整合,反而更加纯粹。
macOS 默认使用的 NFSv3 虽然古老,但是仍然支持 READDIRPLUS,READDIRPLUS 允许客户端发一条请求,服务端就把该目录下所有文件的名字和文件基本属性一次打包返回。在网络层面上用最少的请求次数完成目录读取,效率极高。
优点:
- 更稳定、更可持续的吞吐量
- 处理大量媒体文件时表现好
- 连续读写操作期间性能下降更少
缺陷:
- macOS 对 NFS 协议支持较为保守,无法使用最新的协议特性
- NFS 对权限映射处理较为简单,不支持复杂的 ACL,多用户管理权限麻烦。
按照使用场景选择
如果使用 TimeMachine 备份,SMB 是唯一的选择。
媒体工作者,更适合用 NFS,对处理大量小文件效率相比 SMB 快至少一倍。
NFS 在 macOS 上的使用配置方案
以下以 Debian 独立 KDC、群晖 Synology NAS 和 macOS 原生 NFS 客户端为例,介绍 NFSv3/TCP + Kerberos krb5p + rw 读写按需挂载的配置方式。KDC 负责签发身份票据,NAS 负责文件服务与权限控制,macOS 使用原生 autofs 在访问挂载目录时建立连接。
前置环境与示例命名
| 角色 | 环境与用途 |
|---|---|
| KDC | Debian,已安装 krb5-kdc、krb5-admin-server、krb5-user,使用 MIT Kerberos 建立独立 Realm |
| NAS | 群晖提供 NFS 服务、Kerberos keytab 导入及用户 ID 映射;示例导出路径为 /volume2/photo |
| 客户端 | macOS,使用系统自带的 kinit、kgetcred、klist、vifs、automount 和 nfsstat |
| Kerberos Realm | EXAMPLE.COM,配置中的大小写保持一致 |
| KDC 公网域名 | kdc.example.com,A 记录指向 KDC 的实际公网地址,例如文档示例地址 203.0.113.10 |
| NAS 访问域名 | nas.example.com,解析到客户端能够访问的 NAS 地址,同时用于挂载和服务身份命名 |
| 用户身份 | alice@EXAMPLE.COM,映射到 DSM 本地普通用户 alice |
| NFS 服务身份 | nfs/nas.example.com@EXAMPLE.COM |
| 日常挂载点 | /Volumes/photo |
| KDC 管理入口 | kdc-server,表示管理员已在本机 SSH 配置中定义的主机别名 |
以上域名、地址、用户名和 SSH 别名均为示例,使用时统一替换为自己的配置。准备前确认三端时间同步、名称解析和所需网络路径可用。数据库主密码、Kerberos 用户密码和 macOS 管理员密码分别在各自交互提示中输入,不放进配置、命令行或笔记。keytab 含服务长期密钥,应按凭据文件保管。
方案选择
- 独立 MIT Kerberos KDC:在 Debian 上建立 Realm,不接入 AD、LDAP 或 OIDC;DSM 通过显式映射将 Kerberos 身份关联到本地用户,再由共享权限和文件权限决定访问范围。
- 公网 DNS 与显式 KDC 地址:客户端通过
kdc.example.com取票,不依赖 VPN 或 DNS SRV 记录;在客户端配置中明确指定 KDC。 - NFSv3/TCP +
sec=krb5p:使用 Kerberos 认证,并对受保护的 NFS RPC 数据提供完整性与加密保护。 - 管理面与票据服务分离:先在回环地址完成 KDC 初始化和本机自检,再将票据服务 88 端口改为全地址监听;改密 464 和管理 749 仍限本机,管理操作通过 SSH 进入服务器后执行。
- 原生 autofs 读写按需挂载:使用
vifs在/etc/fstab中添加rw条目,由原生自动挂载器接管;普通用户先取得票据,再直接访问挂载目录。不在自动挂载配置中保存密码,也不使用 NAS 服务 keytab 代替用户登录。
认证和文件传输是两条连接:macOS 向公网 KDC 申请票据,随后直接向 NAS 发起 NFS 请求,照片数据不经过 KDC。nas.example.com 应解析到客户端实际可达的 NAS 地址;公网 KDC 的接入与 NFS 数据通路分别规划,后者还需满足 NFSv3 所需的 RPC 服务和网络条件。
1. 配置 Debian KDC 的本机引导环境
以下配置文件位于 Debian 服务器。先备份现有非密钥配置,再写入;本步骤保持所有 Kerberos 接口仅监听回环地址。
/etc/krb5.conf:
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
dns_canonicalize_hostname = false
rdns = false
ticket_lifetime = 10h
renew_lifetime = 7d
forwardable = false
[realms]
EXAMPLE.COM = {
kdc = 127.0.0.1:88
kpasswd_server = 127.0.0.1:464
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM这里的回环 KDC 地址仅供 Debian 本机初始化和验证;NAS、Mac 使用后文的公网 KDC 地址。
/etc/krb5kdc/kdc.conf:
[kdcdefaults]
kdc_listen = 127.0.0.1:88
kdc_tcp_listen = 127.0.0.1:88
[realms]
EXAMPLE.COM = {
database_module = EXAMPLE.COM
key_stash_file = /etc/krb5kdc/stash
acl_file = /etc/krb5kdc/kadm5.acl
kadmind_listen = 127.0.0.1:749
kpasswd_listen = 127.0.0.1:464
max_life = 10h
max_renewable_life = 7d
default_principal_flags = +preauth
supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
}
[dbmodules]
EXAMPLE.COM = {
db_library = db2
database_name = /var/lib/krb5kdc/principal
}
[logging]
kdc = SYSLOG:INFO:DAEMON
admin_server = SYSLOG:INFO:DAEMON
default = SYSLOG:INFO:DAEMON/etc/krb5kdc/kadm5.acl 仅保留说明,不授权远程 Kerberos 管理员:
# Administration is performed locally with sudo kadmin.local.
# No remote administration principal is authorized in this phase.三份文件均归 root:root;krb5.conf 权限为 0644,kdc.conf 和 kadm5.acl 为 0600。数据库采用 Debian 本机 DB2 路径,未引入 LDAP 后端。
2. 初始化 Realm 数据库并启动服务
从本机终端通过已有 SSH alias 执行,在交互提示中输入并确认数据库主密码:
ssh -t kdc-server -- 'kdb5_util create -r EXAMPLE.COM -s'初始化生成 /var/lib/krb5kdc/principal* 数据库文件,以及 /etc/krb5kdc/stash。-s 创建 stash,供服务启动时读取主密钥;主密码仍需独立妥善保管。
初始化完成后启动服务并检查:
ssh -o BatchMode=yes -o ConnectTimeout=8 kdc-server -- \
'systemctl restart krb5-kdc.service krb5-admin-server.service'
ssh -o BatchMode=yes -o ConnectTimeout=8 kdc-server -- \
'systemctl is-active krb5-kdc.service krb5-admin-server.service; ss -H -lntup'此时两个服务应为 active,88、464、749 均只监听 127.0.0.1。本节用于首次建库;已有 Realm 时从其当前状态继续,不重新初始化数据库。
3. 创建用户、NFS 服务身份并导出 keytab
进入 KDC 本机管理终端:
ssh -t kdc-server -- 'umask 077; kadmin.local -r EXAMPLE.COM'在 kadmin.local 中按顺序执行:
addprinc alice@EXAMPLE.COM
addprinc -randkey nfs/nas.example.com@EXAMPLE.COM
ktadd -k /root/nas-nfs.keytab nfs/nas.example.com@EXAMPLE.COM
quit第一条命令交互设置用户密码;NFS 服务使用随机密钥,再导出供群晖使用的 keytab。示例暂存在服务器家目录,文件为 root:root、0600。
上述命令用于首次创建。ktadd 默认会随机化服务密钥并增加 KVNO,后续重复执行应按密钥轮换处理,同时更新 NAS 上的 keytab。
4. 在 KDC 本机验证用户与服务密钥
在开放公网票据服务前,先用独立缓存完成用户认证、NFS 服务取票和 keytab 校验:
ssh -t kdc-server -- '
set -eu
umask 077
cache=/root/krb5cc-nfs-verify
test ! -e "$cache"
test ! -L "$cache"
trap "if test -e \"$cache\"; then kdestroy -c \"FILE:$cache\"; fi" EXIT
kinit -c "FILE:$cache" alice@EXAMPLE.COM
kvno -c "FILE:$cache" -k /root/nas-nfs.keytab nfs/nas.example.com@EXAMPLE.COM
klist -e -c "FILE:$cache"
'用户密码在终端交互输入,退出时仅销毁该专用缓存。确认 kvno 输出包含 keytab entry valid,并通过 klist -e 检查票据身份和加密类型。KVNO 随服务密钥版本变化,不固定为某个数值。
这里的 kvno 是 Debian 工具,macOS 原生客户端可使用后文的 kgetcred 单独验证服务取票。
5. 配置群晖 NFS Kerberos 与用户映射
由管理员在自己的终端将 keytab 取到本机,再通过 DSM 的 HTTPS 管理界面导入:
umask 077
scp kdc-server:/root/nas-nfs.keytab "$HOME/Downloads/nas-nfs.keytab"在 DSM 中完成以下配置,具体菜单名称随版本略有差异:
- 在「控制面板 → 文件服务 → NFS」启用 NFS 服务,确保允许 NFSv3。
- 在 NFS「高级设置 → Kerberos 设置」导入包含
nfs/nas.example.com@EXAMPLE.COM的 keytab。 - 配置 ID 映射,将完整用户身份
alice@EXAMPLE.COM映射到 DSM 本地普通用户alice。 - 在
photo共享文件夹的 NFS 权限中允许客户端访问并设置读写权限,安全机制使用krb5p;确认导出路径为/volume2/photo。 - 为 DSM 用户
alice配置所需的共享与文件读写权限。Kerberos 负责确认身份,最终权限由 NAS 执行。
完成群晖 keytab 导入与 ID 映射后,挂载沿用 nas.example.com,使服务名称与 keytab 中的身份一致。本机下载副本在导入后按凭据管理要求保管或清理,不进入笔记附件或 Git。服务器上的临时 keytab 在完成导入与受保护的恢复副本保存后清理。
6. 配置公网 DNS 并开放 KDC 票据监听
配置公网 A 记录:
kdc.example.com -> 203.0.113.10本方案不依赖 Kerberos SRV 记录。DNS 就绪后,将 Debian /etc/krb5kdc/kdc.conf 的 [kdcdefaults] 改为:
[kdcdefaults]
kdc_listen = 88
kdc_tcp_listen = 88Realm 内的以下设置保持不变:
kadmind_listen = 127.0.0.1:749
kpasswd_listen = 127.0.0.1:464仅重启票据服务:
ssh kdc-server -- 'systemctl restart krb5-kdc.service'预期监听状态:
| 地址 | 协议 | 用途 |
|---|---|---|
0.0.0.0:88、[::]:88 | TCP/UDP | 全地址票据服务 |
127.0.0.1:464 | TCP/UDP | 本机改密 |
127.0.0.1:749 | TCP | 本机管理 |
后文的 Mac 配置使用公网 TCP 88 取票,云安全组及主机防火墙需允许该通路。公网防护措施见本节末尾。
Debian /etc/krb5.conf 继续保留回环 KDC 地址,供服务器本机使用;NAS 与 Mac 通过公网域名访问 KDC。
7. 配置 macOS 并获取用户票据
在 macOS /etc/krb5.conf 中写入以下配置;若已有其他 Realm,合并相应配置项:
[realms]
EXAMPLE.COM = {
kdc = tcp/kdc.example.com:88
}
[domain_realm]
nas.example.com = EXAMPLE.COM这里显式使用 TCP 访问公网 KDC,并将 NAS 域名映射到目标 Realm。
在普通用户终端检查当前票据,不加 sudo:
/usr/bin/klist -v首次使用、没有目标身份的有效票据或票据已到期时,执行:
/usr/bin/kinit alice@EXAMPLE.COM
/usr/bin/klist -vkinit 交互输入的是 Kerberos 用户密码,票据存入该用户的 macOS 原生 API 缓存。确认 principal 为 alice@EXAMPLE.COM,并存在未到期的 krbtgt/EXAMPLE.COM@EXAMPLE.COM。有多个缓存时,可以明确选择要检查的身份:
KRB5CCPRINCIPAL=alice@EXAMPLE.COM /usr/bin/klist -vNFS 服务票据可在访问共享时按需获取。若需要在挂载前单独检查服务取票,可执行:
/usr/bin/kgetcred nfs/nas.example.com@EXAMPLE.COM
/usr/bin/klist -v票据有效期、加密类型及 renewable 等标志以 klist 为准。自动挂载不负责交互取票或保存用户密码;没有可续期票据或已超过可续期范围时,重新运行 kinit。
8. 使用 vifs 配置日常 rw 按需挂载
采用 macOS 原生 autofs,不再使用手动只读实验挂载。先查看 /etc/auto_master,确认已有以下直接映射:
/- -static-static 从 /etc/fstab 读取不带 net 选项的条目,并使用其中明确指定的挂载点。有这条映射时,无需追加另一条 /- 映射,也无需创建额外的 auto_nas 文件。
使用系统提供的编辑入口:
sudo vifs在 /etc/fstab 中添加下面完整的一行,保留其他已有条目:
nas.example.com:/volume2/photo /Volumes/photo nfs rw,vers=3,tcp,resvport,hard,intr,retrycnt=0,sec=krb5p,realm=EXAMPLE.COM,principal=alice@EXAMPLE.COM,sprincipal=nfs@nas.example.com,rdirplus,dsize=32768,rsize=32768,wsize=32768,readahead=16,acregmin=5,acregmax=60,acdirmin=5,acdirmax=60,nosuid,nodev 0 0六个字段依次是来源、挂载点、文件系统类型、逗号分隔的选项、dump 字段和 fsck 顺序;末尾为 0 0。不要添加 net 选项,否则会进入另一类映射而不再按这里指定的固定路径挂载。
示例使用 /Volumes/photo,也可换成自己的目录,但应先正常卸载占用该路径的旧共享。挂载点由 autofs 管理,无需提前手动创建或再执行一次 mount。
| 参数 | 用途 |
|---|---|
rw | 客户端读写挂载,具体文件权限仍由 NAS 用户及共享权限控制 |
vers=3,tcp | 固定 NFSv3 与 TCP 数据连接 |
resvport | 使用保留源端口,兼容要求该设置的服务端 |
sec=krb5p | Kerberos 认证、完整性保护和传输加密 |
realm=EXAMPLE.COM | 显式指定 Realm |
principal=alice@EXAMPLE.COM | 指定用于挂载凭据的用户身份,与普通用户取票身份对应 |
sprincipal=nfs@nas.example.com | 指定 macOS NFS 使用的 GSS 主机服务名 |
hard,intr | 保持请求重试,允许终止信号中断因服务端无响应而等待的调用 |
retrycnt=0 | 初次挂载只尝试建立连接一次,不控制已挂载文件操作的重试 |
rdirplus,dsize=32768 | 目录读取时附带属性信息,目录读取尺寸请求为 32 KiB |
rsize=32768,wsize=32768,readahead=16 | 读写块大小为 32 KiB,预读值为 16 |
acregmin=5,acregmax=60 | 普通文件属性缓存有效期范围为 5~60 秒 |
acdirmin=5,acdirmax=60 | 目录属性缓存有效期范围为 5~60 秒 |
nosuid,nodev | 不执行远端文件的 set-user-ID/set-group-ID 语义,不解释远端设备文件 |
这里不设置 nobrowse,方便从 Finder 使用共享;读写方案不采用 soft 或可能牺牲持久性的 async 写入选项。hard,intr 仍可能在网络中断时等待服务器,应关闭占用共享的应用后正常卸载,避免对尚有写入的共享强制卸载。
注意区分两种服务名:KDC、keytab 和 kgetcred 使用 nfs/nas.example.com@EXAMPLE.COM;macOS 挂载参数 sprincipal 使用 nfs@nas.example.com。
保存后重新加载自动挂载映射:
sudo /usr/sbin/automount -cv该命令更新映射并清除缓存,真正的 NFS 挂载由后续访问 /Volumes/photo 触发。sudo 输入的是 macOS 管理员密码,与前面的 Kerberos 用户密码分开。日常访问不需要反复执行 automount -cv,修改挂载配置后再重新加载即可。
9. 以普通用户直接验证文件读写
确认已有有效票据后,在不加 sudo的终端直接进入挂载目录。以下命令使用独立小目录完成创建、写入、读取和列目录检查,成功后清理验证文件,不递归扫描照片库:
(
set -e
cd /Volumes/photo
check_dir="$(mktemp -d ./nfs-check.XXXXXXXX)"
touch "$check_dir/probe.txt"
printf '%s\n' 'NFS read-write check' > "$check_dir/probe.txt"
cat "$check_dir/probe.txt"
ls -la "$check_dir"
rm "$check_dir/probe.txt"
rmdir "$check_dir"
)cd 触发按需挂载,touch 检查创建文件,printf 写入内容,cat 验证读取结果,ls 检查目录项和属性访问。预期输出包含 NFS read-write check 以及 probe.txt 的目录信息。ls 只列出这个小目录,不对大型照片目录做完整枚举。若某一步失败,命令会停止,按错误检查票据、NAS 读写权限与 ID 映射。
10. 使用 nfsstat 检查实际挂载参数
在访问目录、触发挂载之后执行:
/usr/bin/nfsstat -m /Volumes/photo重点检查当前挂载参数,而不只看原始选项:
| 检查项 | 配置目标 |
|---|---|
| 来源与目标 | nas.example.com:/volume2/photo → /Volumes/photo |
| 协议与传输 | vers=3,tcp,NFS 数据端口通常为 2049 |
| 读写状态 | 挂载标志不含 ro,并通过前面的普通用户创建、写入和读取验证 |
| 安全机制 | sec=krb5p |
| 身份 | principal=alice@EXAMPLE.COM,Realm 为 EXAMPLE.COM |
| 服务名显示 | sprincipalm=nfs@nas.example.com |
| 等待行为 | hard,intr |
| 读写尺寸 | rsize=32768,wsize=32768 |
| 目录与预读 | 配置请求 rdirplus,dsize=32768,readahead=16 |
| 属性缓存 | 文件与目录的最短 5 秒、最长 60 秒 |
读写挂载通常不会额外打印一个 rw 标志,因此结合挂载标志和实际文件操作确认。尺寸可能受服务端能力约束,以 Current mount parameters 中的实际结果为准。sprincipalm 是 nfsstat 的显示字段,写入配置时仍使用 sprincipal。
访问后还可以再次执行 klist -v,检查 NFS 服务票据和有效期。
11. 日常使用与撤销配置
日常使用时,先用 klist -v 检查票据;需要重新认证时运行 kinit alice@EXAMPLE.COM,随后直接访问 /Volumes/photo。Finder 中可通过「前往文件夹」输入该路径,并按需要加入侧边栏。
票据过期后重新取票,自动挂载与取票分别处理。不将用户密码写入登录脚本,也不把 NAS 服务 keytab 放到客户端作为免密用户凭据。
需要撤销时,先关闭正在使用共享的文件和应用,用 sudo vifs 仅删除对应的 NFS 条目、保留其他条目,再正常卸载并重新加载映射:
sudo /sbin/umount /Volumes/photo
sudo /usr/sbin/automount -cv可选路径与安全增强
- 收敛公网暴露:可选择私网、VPN 或有条件的来源限制;保留公网 KDC 时,保持管理端口仅本机开放,并补充限速、认证失败告警、适度锁定策略及安全更新。
- HTTPS 接入:可评估 KKDCP 代理承载 Kerberos 请求,部署前验证 macOS、NAS 和所用客户端的兼容性。
- NFS 数据通路:公网接入 NFSv3 时,单独规划 rpcbind、mountd 及锁服务等 RPC 端口与防护,区分 NFS 数据保护与辅助服务暴露面。
- 集中身份:多用户规模扩大后,可评估 AD 或 LDAP 与 Kerberos、DSM 的整合,统一账户生命周期,并分别规划每个用户的票据与共享权限。
- 票据与密钥策略:按实际票据属性设计续期和到期提醒,核对客户端加密类型;服务密钥轮换时同步更新 NAS keytab。
- 备份与恢复:为数据库一致性导出、现行配置、stash、服务 keytab 及主密码恢复材料建立独立加密备份,安排隔离恢复演练。补充越权拒绝、票据到期重登、休眠唤醒和网络切换验证。
自动挂载参考
- Apple:auto_master 手册:
-static、/etc/fstab和直接映射的关系。 - Apple:automount 手册:映射重新加载及缓存清理。
- 本机可通过
man vifs、man fstab、man mount_nfs、man nfsstat查看对应系统版本的命令和参数说明。
参考文档
- Network Storage Protocols on macOS: SMB, AFP, and NFS – Softron Support Desk
- MIT Kerberos 1.21:krb5.conf:Realm、客户端票据选项与名称解析配置。
- MIT Kerberos 1.21:kdc.conf:监听地址、数据库、预认证与加密类型。
- MIT Kerberos 1.21:kadmin.local:principal 管理与 keytab 导出。
- Synology DSM:NFS:NFS Kerberos 设置与用户映射入口。
- Synology DSM:NFS 权限:共享导出与安全机制设置。
- Apple:mount_nfs 手册源文件与 NFS GSS 服务名处理:原生挂载参数与服务名称格式。