简介:这份资源面向在 Debian Jessie 与 Stretch 上运维 Samba 4(AD-DC)的 Linux 系统管理员和运维工程师,汇集了作者日常使用的实用脚本,用于解决域控备份、SePrivileges 权限核查、sysvol ACL 检查与设置、域信息查看等常见运维问题,适合具备一定 Samba 与 AD 基础的中级读者参考。压缩包共 25 个文件,以 12 个 sh 脚本为主体,辅以 9 个 txt 操作记录与 howto 说明、3 个 md 文档及 1 个 backup_samba4 备份脚本,整体约 71KB,体积轻量便于随取随用。目前已有 250 人学习。资源价值在于脚本可直接落地:备份脚本基于原始 samba_backup 修改,权限与 sysvol 检查脚本只读展示、不改动配置,域信息工具同时兼容 AD 成员与 AD DC;配套 howto 覆盖最小化 AD 搭建、成员文件服务器权限示例与检查流程,便于读者对照理解脚本用途并快速排错。
1. Samba 4 运维脚本包:把域控日常从手敲命令里捞出来
接手一台 Debian 上的 Samba 4 域控,最磨人的不是装,是装完之后那些重复活:sysvol 到底同步没同步、备份有没有真的跑成功、某个用户改完密码多久生效、共享权限被谁动过。命令行一条条敲当然能查,但每次都要翻历史记录拼参数,时间一长就容易漏。这份脚本包就是冲这个场景来的——一组面向 Samba 4 的 Shell 脚本,作者在 Debian Jessie 和 Debian Stretch 上做过验证,覆盖备份、sysvol 处理、状态信息采集这类高频动作。它不适合想从零学 Samba 原理的人,适合已经在维护域控、想把日常巡检和备份固化成脚本的从业者。下面按「脚本能干什么、怎么落地、哪里会翻车」拆开讲,参数和边界都给到能直接抄的程度。
2. 脚本包的能力边界:先看清它替你干了哪几件事
拿到一个 Shell 脚本包,第一反应不该是直接bash xxx.sh,而是先弄清它依赖什么、假设了什么环境。Samba 4 的运维脚本尤其如此,因为 AD DC 模式下的目录结构、权限模型和普通文件服务器差别很大,脚本写死一个路径,换台机器就可能全盘失效。这一章先把脚本包的能力面和前置条件摊开,再谈怎么跑。
2.1 从文件名和调用方式反推脚本职责
这类脚本包通常按动作命名,比如备份类、sysvol 类、信息采集类。判断职责最直接的办法不是读全部代码,而是先看每个脚本头部的变量定义和它调用的外部命令。常见做法是先跑一遍静态扫描:
# 列出脚本包内所有 shell 文件,并提取每个文件头部 40 行做快速审阅 find ./samba4-scripts -type f -name "*.sh" -print0 | while IFS= read -r -d '' f; do echo "===== $f =====" head -n 40 "$f" done这段的作用是把「这个脚本假设了哪些路径、调用了 samba-tool 还是 rsync、有没有硬编码域名」一次性暴露出来。重点看三类信息:一是SAMBA_*或DC_*之类的变量默认值,二是samba-tool子命令的用法,三是备份目标路径是否写死。参数上,head -n 40可以按需加大到 80,脚本头部注释多的包看得更全。如果某个脚本第一行不是#!/bin/bash而是#!/bin/sh,在 Debian 上要留意它是否用了 bash 特有语法,Stretch 默认的 dash 会在[[ ]]这类写法上直接报错。
审阅时还要确认脚本是否依赖samba-tool的版本行为。Samba 4 在不同小版本间,samba-tool domain backup和samba-tool ntacl sysvolreset的参数有过调整,Jessie 自带的 Samba 版本偏老,Stretch 稍新,脚本作者既然说两个版本都测过,通常会在注释里标注兼容分支。看到if samba-tool ... 2>/dev/null这种写法,说明作者做了容错,但也意味着失败可能被吞掉,后面排查章节会专门讲这个坑。
2.2 运行前置条件:域控角色、权限与依赖命令
脚本能跑通的前提是这台机器确实是 Samba AD DC,而不是成员服务器或独立文件服务器。验证方式不是看smbd进程在不在,而是查域功能级别和 sysvol 路径:
# 确认当前主机是 AD DC 角色,并输出域信息与 sysvol 路径 samba-tool domain level show samba-tool domain info 127.0.0.1 testparm -s 2>/dev/null | grep -E "server role|sysvol|private dir"samba-tool domain level show输出 domain 和 forest 的功能级别,能跑说明本机持有域数据库;domain info连本机 127.0.0.1 拿域 SID 和 DC 列表,连不上基本就是角色或服务有问题。testparm那段过滤出server role、sysvol、private dir三个关键项,server role = active directory domain controller是硬条件,sysvol和private dir给出实际路径,后面所有脚本的路径参数都要以这个输出为准,不能照抄示例里的/var/lib/samba/sysvol。
依赖命令方面,备份脚本一般会用到rsync、tar,sysvol 相关会用到samba-tool,信息采集可能用到smbclient、wbinfo。Debian 上这些不一定默认全装,先补齐再跑,避免脚本跑到一半才报 command not found:
# 安装脚本包常见依赖,Debian Jessie/Stretch 通用 apt-get update apt-get install -y rsync tar smbclient winbind samba-common-binwinbind在纯 DC 场景下不一定需要,但wbinfo做用户和组查询时要用;samba-common-bin提供testparm和部分samba-tool依赖。装完用command -v rsync samba-tool smbclient逐个确认路径存在,比等脚本报错再回头补要省事。权限上,备份 sysvol 和 private dir 需要 root,脚本里如果没做id -u判断,自己跑之前先sudo -i或确认当前是 root,否则会出现「部分文件读不到但脚本仍返回 0」的假成功。
2.3 把脚本参数化:路径、域名、备份目录怎么改
脚本包直接跑往往能用,但换环境就得改。与其逐个文件vim,不如把可变项抽成环境变量或统一配置文件。常见做法是在脚本包同级建一个env.sh,被各脚本source进去:
# env.sh:集中管理脚本包的可变参数,按本机 testparm 输出填写 export SAMBA_DOMAIN="EXAMPLE" # 短域名,大写 export SAMBA_REALM="EXAMPLE.LOCAL" # 完整 realm export SYSVOL_PATH="/var/lib/samba/sysvol" # 以 testparm 输出为准 export PRIVATE_DIR="/var/lib/samba/private" # 以 testparm 输出为准 export BACKUP_ROOT="/backup/samba" # 备份落盘根目录,需独立磁盘 export KEEP_DAYS=14 # 备份保留天数变量含义逐条说清:SAMBA_DOMAIN和SAMBA_REALM用于脚本里拼接 LDAP DN 或samba-tool的-H参数;SYSVOL_PATH和PRIVATE_DIR必须和testparm实际输出一致,写错会导致备份空目录却显示成功;BACKUP_ROOT建议放在和系统盘不同的挂载点,域控系统盘被备份撑满是经典翻车场景;KEEP_DAYS控制清理策略,后面清理脚本会读它。改完在脚本头部加一行source "$(dirname "$0")/env.sh",这样脚本从任何目录调用都能找到配置。参数化之后,同一套脚本在测试域控和生产域控之间迁移只需要换env.sh,不用动脚本本体,这也是判断一个脚本包值不值得长期用的重要标准。
3. 备份与 sysvol 处理:把高风险动作拆成可回滚的步骤
Samba 4 域控最不能出事的两块数据,一是域数据库(private dir 下的 sam.ldb 等),二是 sysvol 里的组策略和登录脚本。这两块的备份方式不一样,恢复顺序也有讲究,混在一起打包看着省事,真出事时往往恢复不干净。这一章按「先备份、再校验、后清理」的顺序落地,每一步都给可执行命令和判断依据。
3.1 域数据库备份:samba-tool domain backup 的正确用法
Samba 4 自带samba-tool domain backup,比直接 tar private dir 安全,因为它会在备份时处理数据库一致性。常用两种模式:online用于运行中的域控,offline用于停机维护窗口。日常巡检用 online:
# 在线备份域数据库到指定目录,文件名带时间戳便于轮转 TS=$(date +%Y%m%d-%H%M%S) BACKUP_DIR="${BACKUP_ROOT}/domain-${TS}" mkdir -p "$BACKUP_DIR" samba-tool domain backup online \ --server=127.0.0.1 \ --targetdir="$BACKUP_DIR" \ --no-secrets 2>&1 | tee "${BACKUP_DIR}/backup.log"--server=127.0.0.1指定从本机拉取,避免网络抖动;--targetdir是落盘目录,脚本里通常按时间戳建子目录;--no-secrets表示不备份密钥材料,适合日常备份,如果要做整机灾难恢复则去掉这个参数,但备份文件敏感度会上升,存放位置要收紧权限。tee把输出同时写日志,后面校验和排查都靠它。执行完检查退出码和日志里有没有Backup successful,只看目录非空是不够的——备份中途失败也可能留下半个目录。
备份产物一般是一个 tar.gz,校验分两层:先看压缩包完整性,再用samba-tool的恢复预检(不实际恢复)确认结构可读:
# 校验备份包完整性,并列出包内顶层结构确认关键目录存在 BK=$(ls -1t "${BACKUP_ROOT}"/domain-*/samba-backup-*.tar.gz | head -n 1) gzip -t "$BK" && echo "gzip ok" tar -tzf "$BK" | awk -F/ '{print $1"/"$2}' | sort -u | head -n 20gzip -t只验证压缩流没坏,tar -tzf列出内容,重点确认包内有private/、sysvol/这类顶层目录。如果列表里只有零星文件,说明备份时源路径就不对,回到env.sh核对PRIVATE_DIR。这一步花不了几秒,但能挡掉大部分「以为备份了其实没备」的情况。
3.2 sysvol 同步状态检查与 ACL 重置
sysvol 在多台 DC 之间靠复制同步,单台 DC 时问题不大,一旦有两台以上,GPO 不同步就是高频故障。检查思路是先看本机 sysvol 内容是否完整,再看复制状态。Samba 4 的复制状态可以用samba-tool相关子命令和repadmin风格的工具查,脚本包里通常封装成一条检查命令:
# 检查 sysvol 目录结构与 GPO 数量,并输出复制相关状态 ls -1 "${SYSVOL_PATH}/${SAMBA_DOMAIN}/Policies" | wc -l samba-tool ntacl sysvolcheck 2>&1 | tail -n 20第一条数 Policies 下的 GPO 目录数量,和预期值对比,突然变少说明同步或挂载出了问题;samba-tool ntacl sysvolcheck检查 sysvol 上的 NT ACL 是否和域内预期一致,输出里出现ERROR或大量MISMATCH就要处理。注意这个命令在部分 Samba 版本上只读检查,不会自动修,修要用sysvolreset,而sysvolreset会重写 ACL,属于高风险动作,执行前必须先做 3.1 的备份。
ACL 重置的典型触发场景是 GPO 应用报权限错误,或者从备份恢复 sysvol 之后。执行顺序固定为「备份 → 重置 → 再检查」:
# 高风险:重置 sysvol ACL,执行前确认已有可用备份 samba-tool ntacl sysvolreset samba-tool ntacl sysvolcheck 2>&1 | grep -c "ERROR" || truesysvolreset不带额外参数,它按域内对象重建 ACL,耗时和 GPO 数量相关。执行后立刻再跑sysvolcheck,用grep -c "ERROR"数错误行,理想结果是 0。如果错误数不降反升,多半是域内 GPO 对象本身损坏,这时候别反复重置,先查samba-tool gpo listall是否正常。血泪经验是:sysvolreset不是万能药,它只修 ACL 不修内容,GPO 文件本身缺失得从备份或另一台 DC 补。
3.3 备份轮转与清理:别让备份把系统盘撑爆
备份脚本跑通之后,第二个星期往往不是备份失败,而是磁盘满。轮转策略要在脚本里写死,不能靠人记得删。基于env.sh里的KEEP_DAYS,清理逻辑按目录修改时间删:
# 删除超过 KEEP_DAYS 的域备份目录,先 dry-run 再实删 find "${BACKUP_ROOT}" -maxdepth 1 -type d -name "domain-*" \ -mtime +"${KEEP_DAYS}" -print # 确认列表无误后去掉 -print 换成 -exec rm -rf {} +先-print看要删哪些,确认没有误伤再实删,这是清理脚本的固定习惯。-mtime +14表示修改时间超过 14 天,按目录算而不是按文件,因为每次备份是一个独立目录。参数上KEEP_DAYS别设太小,域控备份体积和 GPO 数量、用户数相关,保留两周是常见下限,有合规要求就往上加。清理脚本建议单独放 cron,和备份脚本错开时间,避免备份还在写就被删。
cron 配置示例,备份每天凌晨、清理每周一次:
# /etc/cron.d/samba-backup 0 2 * * * root /opt/samba4-scripts/backup-domain.sh >> /var/log/samba-backup.log 2>&1 30 3 * * 0 root /opt/samba4-scripts/cleanup-backup.sh >> /var/log/samba-backup.log 2>&1时间错开半小时以上,日志统一追加到同一文件便于按天排查。root字段不能省,备份需要 root 权限。配完用run-parts --test /etc/cron.d不适用,直接等一个周期或手动bash -x跑一遍脚本确认无交互提示,cron 环境没有 tty,任何read都会卡住。
4. 状态采集与巡检:把「域控还好吗」变成一条命令
域控出问题往往不是突然崩,而是先有一些小信号:复制延迟、DNS 记录缺失、时间偏移、磁盘水位。脚本包里的信息采集类脚本价值就在这里——把散落在多个命令里的检查项收成一份输出,巡检时扫一眼就知道要不要深入。这一章讲怎么用这类脚本,以及输出怎么读。
4.1 一条命令拿到域、复制、DNS 与磁盘概况
信息采集脚本通常聚合多个samba-tool子命令。如果脚本包里的采集脚本输出太杂,可以自己包一层,固定检查项:
# 域控巡检快照:域信息、DC 列表、DNS 记录数、磁盘水位 { echo "== domain info ==" samba-tool domain info 127.0.0.1 echo "== dc list ==" samba-tool domain dcpromo 2>/dev/null || samba-tool computer list | head echo "== dns zones ==" samba-tool dns zonelist 127.0.0.1 -U administrator --password="${ADMIN_PASS}" 2>/dev/null | head -n 20 echo "== disk ==" df -h "${SYSVOL_PATH}" "${BACKUP_ROOT}" } | tee "/var/log/samba-health-$(date +%F).log"domain info给域 SID 和 DC 列表;computer list在部分版本上比dcpromo更稳,用来确认 DC 计算机对象在;dns zonelist需要凭据,ADMIN_PASS从受限权限文件读,别写死在脚本里;df -h同时看 sysvol 所在盘和备份盘,两个盘任一超过 80% 都该处理。整段用tee落日志,按日期命名,巡检历史可回溯。参数上head -n 20防止 zone 多时刷屏,需要全量就去掉。
读输出时抓几个关键点:domain info里 DC 列表是否包含所有预期 DC,少一台说明复制链路可能断了;dns zonelist是否包含域的主 zone,缺了会导致客户端加域失败;df的Use%列是判断依据,不是看剩余绝对值。这些判断标准写进巡检记录模板,比每次凭感觉看要可靠。
4.2 复制延迟与时间偏移:两个最容易被忽略的指标
多 DC 环境下,复制延迟和时间偏移是很多「玄学」故障的根因。Samba 4 的复制可以用samba-tool drs showrepl看,时间偏移用w32tm风格或直接比对 DC 间时间:
# 查看 DRS 复制状态摘要,并比对本机与上游时间源偏差 samba-tool drs showrepl 2>&1 | grep -E "Last success|Last failure|consecutive failures" | head -n 20 chronyc tracking 2>/dev/null || timedatectl statusdrs showrepl输出里重点看Last success是否在预期复制周期内(默认几分钟到十几分钟),consecutive failures大于 0 就要查网络和凭据。时间部分,chronyc tracking给偏移量,没有 chrony 就用timedatectl看是否同步。Kerberos 对时间敏感,偏移超过 5 分钟就会出现认证失败,而现象往往是「密码明明对却登不上」,很容易往密码策略上查偏。把这两项加进日常巡检,能省掉大量排查时间。
4.3 把巡检输出接进告警:阈值怎么定
巡检脚本只落日志还不够,关键指标要能触发告警。最轻量的做法是在脚本末尾加判断,异常时返回非零并输出原因,交给上层 cron 邮件或监控 agent:
# 巡检阈值判断:磁盘超 80% 或复制连续失败则返回非零 DISK_PCT=$(df --output=pcent "${BACKUP_ROOT}" | tail -n 1 | tr -dc '0-9') FAILS=$(samba-tool drs showrepl 2>/dev/null | grep -c "consecutive failures: [1-9]") if [ "$DISK_PCT" -ge 80 ] || [ "$FAILS" -gt 0 ]; then echo "ALERT disk=${DISK_PCT}% repl_failures=${FAILS}" exit 1 fidf --output=pcent只取百分比列,tr -dc '0-9'去掉百分号;grep -c数连续失败行数。阈值 80% 是经验值,备份盘可以放到 85%,系统盘建议 75%。exit 1让 cron 按非零退出码触发告警邮件,比在脚本里自己发邮件更通用。注意grep -c在无匹配时返回 1,配合|| true或直接判断数值,别让脚本因为「没有失败」反而报错退出。
5. 避坑与排查:五个真实会遇到的翻车点
脚本跑不起来的原因,八成不是脚本本身写错,而是环境假设不成立。下面五条按「现象 → 原因 → 解决」写,都是这类 Samba 4 脚本包在 Debian 上落地时反复出现的。
5.1 脚本返回 0 但备份目录是空的
现象:cron 日志显示备份脚本正常结束,退出码 0,但BACKUP_ROOT下只有空目录或半个 tar 包。原因:脚本里samba-tool domain backup的失败被2>/dev/null吞掉,或者PRIVATE_DIR路径写错导致源目录不存在,tar对空目录也能成功打包。解决:去掉关键命令的2>/dev/null,把 stderr 写进日志;备份后强制校验gzip -t和tar -tzf的顶层目录,校验不过就exit 1。我一般会在备份脚本末尾加一段「产物非空且可解压」的断言,不通过直接告警。
5.2 sysvolreset 之后 GPO 反而应用失败
现象:执行samba-tool ntacl sysvolreset后,sysvolcheck错误变少,但客户端组策略应用报错增多。原因:sysvolreset按域内对象重建 ACL,如果域内 GPO 对象本身和 sysvol 文件不一致(比如从旧备份恢复过),重置只是把 ACL 对齐到错误的对象状态。解决:重置前先samba-tool gpo listall核对 GPO 列表,和 sysvol 下 Policies 目录逐一比对,缺失的先从备份或另一台 DC 补齐,再重置。重置永远放在备份之后,且重置后要实际在客户端gpupdate验证,不能只看sysvolcheck。
5.3 Debian Jessie 上脚本报 [[ not found
现象:脚本在 Stretch 上正常,在 Jessie 上第一行就报[[ not found或Syntax error: "(" unexpected。原因:脚本 shebang 写的是#!/bin/sh,而 Debian 的/bin/sh指向 dash,不支持[[ ]]、数组等 bash 语法。解决:确认脚本用了 bash 特性就把 shebang 改成#!/bin/bash,或者用bash script.sh显式调用。批量检查可以grep -l '\[\[' *.sh找出用了[[但 shebang 是 sh 的文件。这类问题在跨 Jessie/Stretch 迁移时特别常见,因为两个版本的默认 shell 行为一致但脚本作者测试时可能用了 bash 调用。
5.4 cron 里跑正常、手动跑失败
现象:手动bash backup.sh一切正常,配到 cron 后日志里全是 command not found 或路径错误。原因:cron 的 PATH 极简,通常只有/usr/bin:/bin,samba-tool在/usr/sbin或/usr/local/sbin下就找不到;另外 cron 不加载用户环境变量,env.sh里的source如果用了相对路径也会失败。解决:脚本里用绝对路径调用命令,或在脚本开头export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin;source改成基于$0的绝对路径。配完用env -i /bin/bash script.sh模拟干净环境跑一遍,能提前暴露大部分环境依赖问题。
5.5 备份文件权限过宽导致敏感信息暴露
现象:备份目录ls -l显示 755,备份包内包含域数据库和可能的密钥材料。原因:脚本用默认 umask 创建目录,mkdir -p不指定权限,备份包继承目录权限。解决:备份根目录设 700,备份子目录创建时mkdir -m 700,备份包生成后chmod 600。如果用了--no-secrets,敏感度降低但仍含域数据,权限不能松。存放位置也别放在 Web 可访问目录或共享目录下,独立挂载点加严格权限是底线。
6. 进阶:把脚本包改造成可审计的运维流水线
脚本包能跑只是起点,真正省心的是让它「自己证明自己跑对了」。我在维护域控时养成的习惯是:任何高风险脚本执行前后都留可对比的快照,任何定时任务都带产物校验,任何告警都能追到具体哪一步失败。落到这份 Samba 4 脚本包上,可以做三件事。
第一,给每个脚本加统一的执行框架,记录开始时间、结束时间、退出码和关键产物路径,写进一个 JSON 行日志。这样巡检时不用翻散落的 stdout,直接按时间过滤就能看出哪次备份变慢、哪次 sysvol 检查错误数上升。第二,把 3.1 的备份校验和 4.3 的阈值判断抽成公共函数,所有脚本source同一份lib.sh,避免每个脚本各写一套判断逻辑导致标准不一。第三,定期做恢复演练——不是真恢复生产,而是在隔离环境用最近一次备份跑samba-tool domain backup restore到临时目录,确认包能解开、关键库文件在。备份没验证过恢复,等于没有备份,这句话在域控场景下尤其成立。
一个可复用的执行框架骨架长这样:
# lib.sh:统一记录脚本执行结果,供各脚本 source run_logged() { local name="$1"; shift local start end rc start=$(date +%s) "$@"; rc=$? end=$(date +%s) printf '{"script":"%s","start":%s,"end":%s,"rc":%s,"dur":%s}\n' \ "$name" "$start" "$end" "$rc" "$((end-start))" >> /var/log/samba-scripts.jsonl return "$rc" }run_logged接收脚本名和命令,执行后把耗时和退出码追加成 JSON 行,rc非零时上层 cron 仍能拿到失败状态。参数上dur用秒,够用且不引入额外依赖;日志按行追加,配合jq可以快速统计「过去七天备份平均耗时」这类指标。把这套框架套到备份、巡检、清理三个脚本上,运维就从「记得跑」变成「跑没跑、跑得对不对都有据可查」。
从那以后我每次改完域控脚本,都会先用env -i模拟干净环境跑一遍,再在隔离环境做一次恢复演练,两步都过才敢放进 cron。希望帮到你。
本文还有配套的精品资源,点击获取