Samba 文件共享部署 SOP(dell-R620)¶
实现体:
samba_ins/Python 部署工程(main.py+deployer.py+utils/) 配置源:config/samba_deploy.yaml本文第 5 章为等价操作序列,供人阅读与手工复核;幂等、备份与回滚一律以实现体为准。
1. 背景¶
Windows 工作站需要读写 dell-R620(Ubuntu 24.04.3 LTS)上的 /home/rain/Documents,用于日常文件交换与工程交付。
变更前实测状态:
- 未安装 Samba 服务端,仅有客户端库(
cifs-utils、libsmbclient0、samba-libs) - 无
/etc/samba目录,无smbd.service - 445 / 139 端口空闲,无进程占用
- 主机未启用任何防火墙(ufw 未激活、firewalld inactive、iptables INPUT 策略 ACCEPT)
因此这是一次首次部署,而非配置变更。
2. 目标¶
变更完成后应达到的可验证状态:
smbd、nmbd、wsdd三个服务均为active且enabled- 445 / 139 (TCP) 仅监听 192.168.31.249(br0),不再监听
0.0.0.0 - 137 / 138 (UDP) 由 nmbd 提供;3702 (UDP) 由 wsdd 提供(含组播 239.255.255.250)
- Samba 账号
smbuser可通过认证,且对/home/rain/Documents具备读、写、可遍历权限 - Windows 侧可通过
\\192.168.31.249\Documents读写文件 - 敏感目录
.trae、.idea、.git、.env、.venv、.vscode对客户端不可见且不可访问 - 连续执行两次,第二次零变更、全跳过
3. 前置条件¶
| 项 | 要求 | 实测 |
|---|---|---|
| 执行权限 | 当前账号具备免密 sudo | rain 属 sudo 组,sudo -n true 成功 |
| 软件源 | apt 源可用 | cn.archive.ubuntu.com + security 可达,samba 候选 2:4.19.5+dfsg-4ubuntu9.7 |
| 共享目录 | 已存在且为目录 | /home/rain/Documents,2.4G,属主 rain:rain,初始权限 755 |
| 端口 | 445/139 无占用 | 空闲 |
| 磁盘余量 | ≥ 1GB | / 剩 163G,/data 剩 1.7T |
| 密码来源 | 环境变量 SMB_PASSWORD |
禁止写入任何文件或脚本 |
| 网络可达 | Windows 与 192.168.31.249 二层可达 | Windows 侧 ping 通,TTL=64 |
所需工具(由工程 venv 提供,不装进系统 Python):Python ≥ 3.9、PyYAML、paramiko;共享库 /home/rain/py_public_modules 经 .pth 引入。
4. 影响范围¶
- 主机:dell-R620 单台。单主机变更,无冗余节点,出问题没有其他节点可顶替,故第 6、7 章按最坏情况写实。
- 新增组件:软件包
samba、wsdd、smbclient;系统账号smbuser(无家目录、/usr/sbin/nologin,附加组 rain);systemd unit/etc/systemd/system/wsdd.service(Ubuntu 官方 wsdd 包不含 unit,由本工程维护)。 - 覆盖的文件:
/etc/samba/smb.conf(覆盖前带时间戳备份)。 - 权限变更:
/home/rain/Documents由 755 → 775(补组写位,使 rain 组成员smbuser可写)。原权限记录于logs/share_permission_before(内容755 rain:rain),仅改本目录权限位,不改属主、不改上级目录。 - 是否停服:不停服,不重启系统。仅在配置变更时对
smbd/nmbd执行restart(秒级中断);变更时无客户端连接,实际无感。 - 同机其它业务:本机是 KVM 宿主,运行 openwrt + k8s 三控三节点共 7 台虚机,另有 Docker。本变更不触碰 netplan / 网桥 / 路由 / sysctl / iptables,对虚机与 k8s 无影响。
- 窗口期:无需专门窗口。建议避开 Windows 侧正在传输大文件的时段。
- 新增端口暴露:445/139 (TCP)、137/138 (UDP)、3702 (UDP),均仅绑定 br0;无主机防火墙,同网段主机可探测到这组端口。
5. 分步操作¶
对应实现文件:
main.py(入口)、deployer.py(SambaDeployer,生命周期与方法见下) 以实现体为准:以下为等价手工序列,不承担幂等与错误处理;幂等、备份、回滚由工程实现。
5.1 触发部署¶
cd /home/rain/Documents/samba_ins # 进入工程目录
.venv/bin/python -m py_compile main.py deployer.py utils/*.py # 语法自检,失败则不进入下一步
.venv/bin/python main.py --config config/samba_deploy.yaml --dry-run # 预演:只输出待变更项,不改系统
SMB_PASSWORD='***' DEBIAN_FRONTEND=noninteractive \
.venv/bin/python main.py --config config/samba_deploy.yaml # 正式部署(密码经环境变量传入,不落盘)
5.2 实现体实际执行的系统动作¶
sudo apt-get install -y samba wsdd smbclient # 装包;已安装的包由 dpkg-query 判定后跳过
sudo useradd --no-create-home --shell /usr/sbin/nologin --groups rain smbuser # 建专用账号;已存在则跳过
sudo smbpasswd -s -a smbuser # 设 Samba 密码:经 stdin 传两遍,不进命令行、不落盘
sudo chmod g+w /home/rain/Documents # 补组写位(原 755 记录于 logs/share_permission_before)
sudo install -m 0644 -o root -g root <tmp> /etc/samba/smb.conf # 【高危】覆盖配置;覆盖前已备份 smb.conf.bak.<时间戳>
sudo install -m 0644 -o root -g root <tmp> /etc/systemd/system/wsdd.service # 写 wsdd unit(官方包不含)
sudo systemctl daemon-reload # 使新 unit 被 systemd 识别
sudo systemctl enable smbd nmbd wsdd # 设开机自启;已 enabled 则跳过
sudo systemctl restart smbd nmbd # 载入新配置(仅配置有变更、或仍以通配地址监听时执行)
sudo systemctl start wsdd # 启动 wsdd;已 active 则跳过
关键实现细节:
- 配置渲染不含时间戳等易变内容,保证 SHA256 比对可判定幂等(
deployer.py:_render_smb_conf) - 备份统一走
sudo cp -a(deployer.py:_backup_file),因/etc下文件属主为 root,基类auto_backup()无权限 - 覆盖类动作前先比对哈希,一致则跳过且不产生冗余备份
6. 验证¶
6.1 本机验证¶
systemctl is-active smbd nmbd wsdd # 期望:三行均为 active
systemctl is-enabled smbd nmbd wsdd # 期望:三行均为 enabled
ss -tlnp | grep -E ':445|:139' # 期望:仅 192.168.31.249:445 与 :139,无 0.0.0.0
ss -ulnp | grep -E ':137|:138|:3702' # 期望:nmbd 的 137/138、wsdd 的 3702(含组播)
sudo testparm -s /etc/samba/smb.conf # 期望:返回 0,输出有效配置
sudo pdbedit -L # 期望:含 smbuser 条目
ls -ld /home/rain/Documents # 期望:drwxrwxr-x(775)
sudo -u smbuser test -w /home/rain/Documents && echo OK # 期望:输出 OK
端到端认证与共享可见性(smbclient 已随部署安装):
# 用 authfile 传凭据,避免密码出现在命令行
printf 'username=smbuser\npassword=***\n' > /tmp/smb_auth && chmod 600 /tmp/smb_auth
smbclient -L 192.168.31.249 -A /tmp/smb_auth -m SMB3 # 期望:列出 Documents 与 IPC$
smbclient //192.168.31.249/Documents -A /tmp/smb_auth -m SMB3 -c 'ls' # 期望:列出目录内容
smbclient //192.168.31.249/Documents -A /tmp/smb_auth -m SMB3 -c 'ls .trae' # 期望:NT_STATUS_NO_SUCH_FILE(被 veto 阻止)
rm -f /tmp/smb_auth
注意:配置了
bind interfaces only后 smbd 不再监听 127.0.0.1,本机自检必须使用 192.168.31.249。
6.2 Windows 侧验证¶
ping 192.168.31.249 # 期望:可通
Test-NetConnection 192.168.31.249 -Port 445 # 期望:TcpTestSucceeded : True
net use Z: \\192.168.31.249\Documents /user:smbuser *** # 期望:命令成功完成
也可在资源管理器地址栏直接输入 \\192.168.31.249\Documents;若在「网络」中查看,应能看到主机 DELL-R620。
6.3 幂等复跑¶
SMB_PASSWORD='***' .venv/bin/python main.py --config config/samba_deploy.yaml
# 期望输出:状态一致,无需变更,跳过备份与执行;状态: skipped
7. 回滚¶
触发判据(任一达标即回滚,不临场判断):testparm 返回非 0 / 某服务非 active / smbclient 认证失败 / AppArmor 出现 smbd 拒绝记录 / 幂等复跑出现非跳过变更。
cd /home/rain/Documents/samba_ins
.venv/bin/python main.py --config config/samba_deploy.yaml --rollback # 高危,需交互输入 YES 确认
实现体按序遍历执行:
sudo systemctl disable --now wsdd nmbd smbd # 停止并取消自启
sudo apt-get remove -y samba wsdd smbclient # 卸载本次安装的软件包
sudo smbpasswd -x smbuser # 移除 Samba 账号密码
sudo userdel smbuser # 删除系统账号
sudo install -d -m 0755 /etc/samba # 若变更前已有配置备份,则重建目录并恢复
sudo cp -a <最新备份> /etc/samba/smb.conf
sudo chmod 755 /home/rain/Documents # 按 logs/share_permission_before 记录恢复目录权限
备份位置:
/etc/samba/smb.conf.bak.<YYYYmmdd-HHmmss>/etc/systemd/system/wsdd.service.bak.<YYYYmmdd-HHmmss>- 目录权限原值:
logs/share_permission_before
回滚后验证:445/139 不再监听、id smbuser 不存在、/etc/samba/smb.conf 已还原或不存在、ls -ld /home/rain/Documents 恢复为 755。
注意:--rollback 卸包后 /etc/samba 目录可能被一并清除;若变更前该目录已存在历史配置,务必确认上表中最新备份存在,实现体会在卸载后重建目录并恢复。
8. 风险说明¶
| 风险点 | 说明 | 缓解措施 |
|---|---|---|
| 无主机防火墙 | 本机 ufw 未启用,445/139/137/138/3702 对整个 192.168.31.0/24 可达(含 7 台虚机) | 已用 Samba 自身 hosts allow = 127.0.0.1 192.168.31.0/24 + hosts deny = 0.0.0.0/0 收敛;如需更严可启用 ufw |
| 敏感目录外泄 | 共享根为整个 Documents,含 .trae、.idea 等可能存有凭据的目录 |
veto files + delete veto files = no 硬排除,实测访问返回 NT_STATUS_NO_SUCH_FILE |
| 目录权限放宽 | chmod g+w 使 rain 组全体获得 Documents 写权限 |
当前 rain 组成员仅 rain 与 smbuser;原权限 755 已记录,可一键恢复 |
| 密码强度与泄露 | 密码已在对话中出现,且为人工设定的较短口令 | 密码不落盘;建议连通后轮换为强口令,并改用 --force 重设 |
| 双 IP 混淆 | 本机 br0=192.168.31.249 与 eno2=192.168.31.250 同网段 | 已 bind interfaces only 仅绑 br0,客户端统一用 249,从 250 访问会失败(预期行为) |
| 单点主机 | 本机同时承载 KVM 与 k8s,但本变更不触碰虚拟化与网络配置 | 变更仅新增用户态服务;未修改 netplan/网桥/路由/sysctl |
| wsdd unit 归属 | Ubuntu 官方 wsdd 包不含 systemd unit,unit 由本工程维护 | unit 内容纳入哈希比对与备份,随工程一同回滚;升级 wsdd 包不会覆盖该 unit |
| AppArmor | 装包引入 usr.sbin.smbd profile,理论上可能拦截共享路径访问 |
部署流程内置拦截检查(读 30 分钟内内核日志中的 DENIED 记录),实测无拒绝 |
| 冗余备份 | 早期执行产生过内容相同的备份文件 | 现逻辑仅在内容确实变更时备份;历史冗余备份已于 2026-09-16 按哈希校验后清理完毕 |
来源:
/home/rain/Documents/samba_ins/docs/SOP.md| 最后更新:2026-09-16 10:56(由build/sync.py同步,请勿在站点侧修改)