
凌晨 1:40,深圳设计组和伦敦营销组又在群里互相“问候”——同一个 KV_2025Q4.psd,两边同时改,最后谁都合不上。早上洛杉矶同事醒来,看到三份“最终版(final_final_3)”,想骂人但忍住了。我端着冷掉的咖啡,盯着机柜里那台刚上架的 1U 服务器,决定把这件事一口气解决:Samba + 细粒度 POSIX ACL + 版本快照 + 审计 + 防误删。
下面是我完整的落地过程、踩坑记录和优化心得。
1. 现场环境与目标
1.1 机房与硬件(真实参数)
| 项目 | 配置 |
|---|---|
| 位置 | 香港 MEGA-i(低丢包、连中美欧都算稳) |
| 服务器 | Dell R6525(AMD EPYC 7313P, 16C/32T) |
| 内存 | 128GB DDR4 ECC |
| 系统盘 | 2 × 480GB SATA SSD(RAID1, mdadm) |
| 数据盘 | 4 × 3.84TB NVMe U.2(RAID10, mdadm) |
| 网卡 | 2 × 10GbE(bond0, mode=802.3ad, LACP) |
| OS | Ubuntu Server 22.04 LTS(5.15 内核) |
| 文件系统 | XFS(noatime, inode64, reflink=1, ftype=1) |
| 时间 | chrony 同步至香港 NTP 池 |
选 XFS 是因为在海量小文件+并发元数据操作下更稳,且支持 reflink,后面做快照硬链接/轻量拷贝更友好。
1.2 网络质量(我测过的三地 RTT)
| 地点 | 平均 RTT | 抖动 | 丢包 |
|---|---|---|---|
| 深圳办公室 | 17 ms | 2 ms | <0.1% |
| 伦敦 WeWork | 172 ms | 12 ms | 0.2% |
| 洛杉矶 SoCal | 146 ms | 9 ms | 0.1% |
1.3 目标拆解
- 并发冲突:启用 SMB2/3 租约(leases)+ 严格锁定(strict locking)+ 禁止客户端离线缓存。
- 权限管理:用 POSIX ACL 做细粒度控制,配合 setgid 保证新文件继承组;Samba 用 acl_xattr 保持一致。
- 回滚与追责:vfs recycle 防误删、shadow_copy2 对接快照,“以前的版本”能一键还原;full_audit 做审计。
- 跨国 WAN 优化:合理的 SMB3 参数(credits/read/write/trans 上限)、适度压缩、禁用 SMB1。
- 可维护:结构清晰、日志可读、出问题能快速定位。
2. 系统准备
# 1) 基础更新与工具
apt update && apt -y upgrade
apt -y install samba acl attr chrony xfsprogs mdadm iftop nload ethtool smbclient
# 2) 时间同步(chrony)
timedatectl set-timezone Asia/Hong_Kong
systemctl enable --now chrony
# 3) 数据盘阵列(示例,已线下完成)
# mdadm --create /dev/md10 --level=10 --raid-devices=4 /dev/nvme[0-3]n1
# mkfs.xfs -m reflink=1,crc=1 -f /dev/md10
mkdir -p /srv/samba
echo '/dev/md10 /srv/samba xfs defaults,noatime,inode64 0 0' >> /etc/fstab
mount -a
3. 目录与权限模型设计
3.1 用户与组(按团队分组)
# 组
groupadd cn_design
groupadd uk_marketing
groupadd us_pm
groupadd eng_shared
# 示例用户(按需接入 LDAP/AD 亦可)
useradd -m -s /bin/bash alice && usermod -aG cn_design,eng_shared alice
useradd -m -s /bin/bash bob && usermod -aG uk_marketing bob
useradd -m -s /bin/bash chris && usermod -aG us_pm chris
3.2 目录结构
mkdir -p /srv/samba/{projects,exchange,archive}
chown root:eng_shared /srv/samba/projects
chown root:eng_shared /srv/samba/exchange
chown root:eng_shared /srv/samba/archive
# 保证新建的子目录继承组(setgid)
chmod 2775 /srv/samba/{projects,exchange,archive}
3.3 ACL 策略(默认 ACL + 授权矩阵)
| 共享 | 目的 | 组权限 | 说明 |
|---|---|---|---|
| projects | 正式协作区 | cn_design:rwX, uk_marketing:rwX, us_pm:rX |
设计和营销可改,PM 只读 |
| exchange | 临时交换区 | eng_shared:rwX |
默认 7 天自动清理 |
| archive | 发版归档 | eng_shared:rX |
只读,按季度归档 |
应用 ACL:
# projects
setfacl -R -m g:cn_design:rwX,g:uk_marketing:rwX,g:us_pm:rX /srv/samba/projects
setfacl -R -d -m g:cn_design:rwX,g:uk_marketing:rwX,g:us_pm:rX /srv/samba/projects
# exchange
setfacl -R -m g:eng_shared:rwX /srv/samba/exchange
setfacl -R -d -m g:eng_shared:rwX /srv/samba/exchange
# archive
setfacl -R -m g:eng_shared:rX /srv/samba/archive
setfacl -R -d -m g:eng_shared:rX /srv/samba/archive
注意:-d 是设置默认 ACL,确保新文件/目录也继承;X 只在目录或已有执行位时赋予执行权限,避免把文件设成可执行。
4. Samba 安装与核心配置
4.1 安装与版本确认
apt -y install samba
smbd -V
# 我这里是 4.15.x(Ubuntu 22.04 默认),支持 SMB3_11 leases/credits/压缩等
4.2 完整 smb.conf(生产可用基线)
备份原始文件:cp /etc/samba/smb.conf /etc/samba/smb.conf.bak.$(date +%F)
[global]
workgroup = WORKGROUP
server string = HK-Files-01
netbios name = HK-FILES-01
# 安全:禁 SMB1
server min protocol = SMB2_10
server max protocol = SMB3_11
# 时区/字符
unix charset = UTF-8
dos charset = CP950
# Leases/锁定/一致性
smb2 leases = yes
kernel share modes = yes
strict locking = yes
posix locking = yes
# 禁止客户端离线缓存,减少冲突
csc policy = disable
# ACL 映射与扩展属性
vfs objects = acl_xattr recycle full_audit shadow_copy2 catia streams_xattr
map acl inherit = yes
store dos attributes = yes
# 对 Mac 友好,避免 ._ 文件与奇怪字符
catia:maps = :hex
# 流式元数据(PSDs/Office 附属数据)
streams_xattr:prefix = user.
# 回收站(版本化 + 保留目录结构)
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch = yes
recycle:maxsize = 0
recycle:exclude = *.tmp,~$*,*.bak,*.obj
recycle:exclude_dir = .recycle
# 影子副本(配合后文 LVM 快照)
shadow:snapdir = /srv/snapshots
shadow:basedir = /srv/samba
shadow:sort = desc
shadow:localtime = yes
shadow:format = @GMT-%Y.%m.%d-%H.%M.%S
# 审计
full_audit:prefix = %u|%I|%S
full_audit:success = open,close,rename,unlink,write,mkdir,rmdir,chmod,connect
full_audit:failure = none
full_audit:facility = LOCAL7
full_audit:priority = NOTICE
# WAN 优化(高延迟提高窗口/并发度)
smb2 max credits = 8192
smb2 max read = 8388608
smb2 max write = 8388608
smb2 max trans = 8388608
# SMB3 压缩:对文档类利好(视 CPU)
smb compress = yes
# 日志
log level = 1
max log size = 4096
# 绑定网口与访问控制(按需)
interfaces = bond0, lo
bind interfaces only = yes
hosts allow = 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
hosts deny = 0.0.0.0/0
load printers = no
printing = bsd
[projects]
path = /srv/samba/projects
browseable = yes
read only = no
force group = eng_shared
create mask = 0664
directory mask = 2775
# Office/PS 等避免乐观锁导致的并发覆盖
veto oplock files = /*.mdb/*.accdb/*.sqlite/*.sqlitedb/*.pst/*.ost/~$*.doc?/~$*.xls?/~$*.ppt?/*.psd/
# 一致性优先:禁用客户端缓存
csc policy = disable
[exchange]
path = /srv/samba/exchange
browseable = yes
read only = no
force group = eng_shared
create mask = 0664
directory mask = 2775
csc policy = disable
[archive]
path = /srv/samba/archive
browseable = yes
read only = yes
csc policy = disable
生效并检查:
testparm -s
systemctl enable --now smbd nmbd
关键点解释
strict locking = yes:保证 Office/PSD 这类文件的独占性,避免“互相覆盖”。
smb2 leases:现代 SMB 的“租约”机制,比老 oplocks 更稳。
veto oplock files:对 Access/SQLite/Outlook PST 等强制禁租约,防止损坏。
credits/read/write/trans:拉大窗口,跨洲传大文件不被 RTT 卡死。
shadow_copy2:配合快照,让 Windows “以前的版本”可见。
catia/streams_xattr:混合 Win/Mac 团队时很有用,少很多奇怪文件。
5. 文件快照与“以前的版本”
我用 LVM 快照 + 只读挂载 + shadow_copy2,生成 Windows 可见的 @GMT-YYYY.MM.DD-HH.MM.SS 目录。
5.1 LVM 与快照目录
# 假设 /srv/samba 在卷组 vgdata 的逻辑卷 lvdata 上
lvdisplay | grep lvdata
mkdir -p /srv/snapshots/projects
# 定义一个每小时快照脚本:/usr/local/sbin/snap_projects.sh
cat >/usr/local/sbin/snap_projects.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
STAMP=$(date +@GMT-%Y.%m.%d-%H.%M.%S)
SNAP=lvdata_${STAMP}
lvcreate -s -n "${SNAP}" -L 50G vgdata/lvdata
mkdir -p /srv/snapshots/projects/"${STAMP}"
# 只读挂载快照
mount -o ro,nouuid -t xfs /dev/vgdata/${SNAP} /srv/snapshots/projects/"${STAMP}"
# 清理 14 天前的快照(按需)
find /srv/snapshots/projects -maxdepth 1 -type d -name '@GMT-*' -mtime +14 -print0 \
| xargs -0 -I{} bash -c 'umount "{}" || true; SNAP=$(basename "{}"); lvremove -f /dev/vgdata/lvdata_${SNAP}'
EOF
chmod +x /usr/local/sbin/snap_projects.sh
# cron 每小时跑一次
echo '12 * * * * root /usr/local/sbin/snap_projects.sh >/var/log/snap_projects.log 2>&1' >/etc/cron.d/samba_snap
快照大小 -L 50G 需按一天改动量预估,过小会早早失效;生产可做监控告警。
5.2 Windows 端效果
打开 \\HK-FILES-01\projects,右键文件 → 属性 → 以前的版本,就能看到时间点,点开即还原/对比。
6. 客户端接入与参数建议
6.1 Windows
# 以用户 alice 连接
cmd /c "net use * \\HK-FILES-01\projects /user:alice /persistent:yes"
组策略里把 脱机文件关掉(已在服务端 csc policy = disable),双保险。
Office 打开时能看到“只读/占用”提示,避免两地同时写。
6.2 macOS
Finder → 前往 → 连接服务器:smb://HK-FILES-01/projects
在 smb:// 下优先走 SMB3;catia/fruit/streams_xattr 组合能减少 “._*” 和资源叉问题(此处用了 catia 与 streams_xattr,若以 Mac 为主可再加 fruit,但需评估与 Win 的兼容性,通常问题不大)。
6.3 Linux(只读示例)
mount -t cifs //HK-FILES-01/projects /mnt/projects \
-o vers=3.1.1,username=chris,uid=1002,gid=$(getent group us_pm|cut -d: -f3),ro,actimeo=1
7. 冲突测试与审计
7.1 并发写入模拟
我让伦敦的 Bob 和深圳的 Alice 同时打开同一份 KV_2025Q4.psd:
第二个打开的会收到“只读/占用”的提示;
smbstatus 能看到当前锁与连接:
smbstatus --locks
smbstatus --shares
7.2 审计日志(full_audit)
/var/log/syslog 或 LOCAL7(按 rsyslog 配置)会有:
alice|10.23.4.5|projects|open|/srv/samba/projects/KV_2025Q4.psd
bob|172.22.3.9|projects|rename|.../final_final_2.psd -> final_final_3.psd
这在复盘“谁在什么时间改了什么文件”时很关键。
8. 日常维护与自动化
8.1 定期清理临时交换区
cat >/usr/local/sbin/cleanup_exchange.sh <<'EOF'
#!/usr/bin/env bash
find /srv/samba/exchange -type f -mtime +7 -print -delete
find /srv/samba/exchange -type d -empty -mtime +2 -print -delete
EOF
chmod +x /usr/local/sbin/cleanup_exchange.sh
echo '27 3 * * * root /usr/local/sbin/cleanup_exchange.sh >/var/log/cleanup_exchange.log 2>&1' >/etc/cron.d/samba_cleanup
8.2 logrotate(示例)
cat >/etc/logrotate.d/samba-audit <<'EOF'
/var/log/syslog {
daily
rotate 14
compress
delaycompress
missingok
notifempty
}
EOF
9. 性能与可靠性优化心得
| 优化点 | 经验值/建议 | 作用 |
|---|---|---|
smb2 max credits = 8192 |
跨洲长 RTT 时吞吐更平滑 | 大文件传输更稳 |
smb2 max read/write/trans = 8MB |
避免频繁往返 | 提升有效带宽 |
smb compress = yes |
文档类显著,图像类视情况 | 节省带宽,但吃 CPU |
| 关闭 SMB1 | 必须 | 安全与性能 |
strict locking = yes + csc policy = disable |
必须 | 减少并发覆盖 |
veto oplock files |
针对 DB/PST/SQLite | 避免文件损坏 |
| XFS + noatime | 默认就好 | 元数据更快 |
setgid + 默认 ACL |
必须 | 新文件自动对齐权限 |
| 快照保留 7–14 天 | 看容量 | 防误删/快速回滚 |
避免的坑
- 不要乱动老掉牙的 socket options(TCP_NODELAY 等),现代内核与 Samba 已调优。
- acl_xattr:ignore system acls = yes 会让 xattr 与 POSIX ACL 脱节,不利于我们用 getfacl/setfacl 运维,因此不要开。
- create mask/directory mask 如果设得过严,会“吃掉”ACL;我用 0664/2775 是为了配合组继承与默认 ACL。
- Mac/Win 混用时,没开 catia/streams_xattr,容易出现中文名异常和 ._* 垃圾文件。
10. 故障与排查实录(真实经历)
症状:伦敦同事说新建的文件别人看不到写权限。
定位:getfacl 发现目录的 默认 ACL 丢了;追溯审计,某次临时维护把目录 chmod -R 过。
处理:
# 重新打默认 ACL
setfacl -R -d -m g:cn_design:rwX,g:uk_marketing:rwX,g:us_pm:rX /srv/samba/projects
# 防呆:把顶层目录改成 root:eng_shared, 2775,禁止非 root 改权限
chown root:eng_shared /srv/samba/projects
chmod 2775 /srv/samba/projects
chattr +i /srv/samba/projects # 顶层目录上锁(如需严格)
复盘:文档化权限基线,任何 chmod -R 必须走变更,同步执行 testparm -s 和 getfacl 校验。
11. 验收清单(我上线前后的 checklist)
- testparm -s 无报错
- smbstatus 能看到锁,二次打开被只读
- Windows “以前的版本”可见,能还原
- 回收站 .recycle/%U 生效,能恢复误删
- 审计日志落地并归档
- 三地大文件传输稳定(不掉速/不断流)
- getfacl 与实际权限一致,新建文件权限正确
- Mac/Win 命名兼容,无奇怪文件
12. 把“final_final_3.psd”变成历史
上线一周后,群里安静了许多。深圳的 Alice 说,再也没见过“我这边是最新的你那边覆盖了”的吵架;伦敦的 Bob 学会了在“以前的版本”里拿回被误改的图层;洛杉矶的 Chris 半夜醒来,发现文件夹里不再横着十几个“FINAL”。
我又在凌晨 1 点走进冷气过猛的机房,摸了一下 R6525 的面板,灯在稳稳地闪。那一刻我知道:这套 Samba + ACL + 快照 + 审计 的组合拳,终于把跨国团队的协作,拉回到了“可控”的轨道上。
附:常用命令小抄
# 检查 Samba
testparm -s
systemctl status smbd nmbd
tail -f /var/log/syslog
# 在线连接/锁
smbstatus --shares
smbstatus --locks
# 权限核对
getfacl /srv/samba/projects | less
# 性能临时观测
iftop -i bond0
nload bond0
你可以照抄的最小可用配置(起步版)
目录与 ACL
mkdir -p /srv/samba/projects
groupadd eng_shared
chown root:eng_shared /srv/samba/projects
chmod 2775 /srv/samba/projects
setfacl -m g:eng_shared:rwX /srv/samba/projects
setfacl -d -m g:eng_shared:rwX /srv/samba/projects
/etc/samba/smb.conf 关键片段
[global]
server min protocol = SMB2_10
server max protocol = SMB3_11
vfs objects = acl_xattr recycle
map acl inherit = yes
store dos attributes = yes
smb2 leases = yes
strict locking = yes
csc policy = disable
[projects]
path = /srv/samba/projects
read only = no
create mask = 0664
directory mask = 2775
起步跑通后,再逐步加上 full_audit、shadow_copy2、catia/streams_xattr、credits/读写窗口等优化项。