首页 / 资讯中心 / 文章详情

Debian 下 Samba 4 域控制器脚本化部署、备份与还原实战指南

Debian 下 Samba 4 域控制器脚本化部署、备份与还原实战指南 ★ FEATURED ARTICLE
简介面向基于Debian Jessie与Stretch部署Samba 4 AD域控的运维人员提供了一套作者长期使用的Shell脚本集合聚焦域控日常维护中的高频操作包括配置备份、SePrivileges特权查看、sysvol目录ACL检查与修复、域信息汇总展示等能够有效减少重复劳动并加快问题定位。压缩包内文件总数为25个其中12个为sh脚本构成核心工具9个为txt格式说明文档详细记录部署与检查步骤3个为md指南补充背景概念另有1个backup_samba4备份脚本包体仅71KB短小精悍。所有脚本均在Debian Jessie与Stretch服务器上实际测试适合具备一定Samba基础、正在维护或准备部署AD域控的读者。通过其中的检查脚本可清晰了解当前SePrivileges配置利用sysvol脚本可修复ACL异常域信息脚本则能快速输出关键参数配合多篇操作文档读者既能直接套用也能基于源码改进作为Samba 4管理员的手边工具尤其适合需要定期巡检或批量调整域控的环境。已有247人浏览学习可作为实践参考。1. Samba 4 脚本在 Debian Jessie 与 Stretch 上到底能解决什么从手工域控到一键交付我最早接触 Samba 4 域控制器是在 Debian Jessie 上当时还习惯一条条敲samba-tool domain provision敲完再手工配 Kerberos、改/etc/hosts、等 DNS 自检。单台机器没问题但一旦要重装、要加第二台域控、要给客户交付一套一模一样的 AD 环境手工流程就立刻翻车漏掉某个 DNS 记录、krb5.conf 大小写写错、sysvol 权限被顺手 chown 坏每个错误都能耗掉半天。后来我把整个流程脚本化把 provision、自启、备份、还原、健康检查全部固化成可重放的脚本才真正把 Samba 4 从「黑匣子」变成「可以运维的基础设施」。这篇笔记就是我在 Debian Jessie 和 Debian Stretch 上沉淀下来的那套方案脚本怎么写、参数怎么定、坑在哪以及怎么用脚本把域控撑到生产可用。2. 用 samba-tool domain provision 脚本化部署 DC最小可跑骨架与参数怎么定2.1 为什么 Samba 4 的部署必须先固化成脚本Samba 4的域控制器部署核心就是一条samba-tool domain provision它会把 AD 数据库、sysvol、Kerberos 密钥、DNS 记录等一次性生成出来。问题在于这条命令只在首次部署时跑一次跑完再跑容易把域配置搅乱所以大多数人对它的理解停留在「跑完就好了」一旦换机器就靠翻 shell history 找当初的参数。我一般会把 provision 固化成脚本原因有三个。第一provision 参数里有大量不能错的项目realm 必须全大写、domain 必须用 NetBIOS 短名、adminpass 不能出现在命令行历史里、--dns-backend选错会影响整个 DNS 服务。第二provision 不负责系统侧配置比如/etc/krb5.conf、/etc/hosts、DNS 解析指向这三处经常成为部署后 KDC 连不上的主因。第三脚本化之后新环境可以从准备系统包到最后验证一口气跑完交付时不再依赖个人记忆。需要说明的是这里讨论的场景是小型 AD 环境几十台机器、几台 DC 就够用。如果你面对的是数千人的大域应该优先考虑官方推荐的迁移工具链本文的脚本思路仍然适用但规模阈值不同。2.2 最小可用脚本域参数、管理员密码与 DNS 自检下面这个脚本是我在 Debian 8/9 上用的最小骨架核心逻辑就是先检查环境再执行 provision最后把生成的文件放到正确位置。注意其中有一个阶段是「DNS 自检」provision 会尝试解析自己的 DC 名称解析失败会直接中断。#!/usr/bin/env bash set -euo pipefail # 域参数按你的实际环境修改短域名建议小于 15 字符 REALMEXAMPLE.LOCAL DOMAINEXAMPLE ADMIN_PASS${ADMIN_PASS:-} # 从环境变量读取不要写死在脚本里 DNS_BACKENDSAMBA_INTERNAL # Samba 自带 DNS适合小型环境 TZ_REGIONAsia/Shanghai # 与站点规划保持一致 # 前置检查 if [[ $EUID -ne 0 ]]; then echo 请用 root 运行此脚本 exit 1 fi # 防止重复执行已存在域数据库时直接退出 if [[ -d /var/lib/samba/private ]] [[ -f /var/lib/samba/private/krb5.conf ]]; then echo 检测到已有域数据库脚本退出 exit 1 fi if [[ -z $ADMIN_PASS ]]; then echo 未设置 ADMIN_PASS 环境变量 exit 1 fi # 系统侧固定配置 echo $(hostname -s) $(hostname -f) /etc/hosts # 执行 provision这是整个脚本的核心 samba-tool domain provision \ --realm$REALM \ --domain$DOMAIN \ --adminpass$ADMIN_PASS \ --server-roledc \ --dns-backend$DNS_BACKEND \ --use-rfc2307 \ --function-level2008_R2 # 把生成的配置放到 Debian 约定位置 mv -f /var/lib/samba/private/krb5.conf /etc/krb5.conf mkdir -p /etc/samba cp -f /var/lib/samba/smb.conf /etc/samba/smb.conf这里有几个参数必须说明白。--realm必须和 DNS 域名完全一致并且全大写Kerberos 对 realm 大小写敏感部署后想改 realm 基本等于重建域。--domain是 NetBIOS 短名不能超过 15 个字符也不能带点。--adminpass我坚持从环境变量读避免命令出现在 shell history 里实在要传明文至少马上执行unset ADMIN_PASS。--dns-backendSAMBA_INTERNAL是小型环境最省心的选择Samba 自己维护 DNS 记录不需要额外装 BIND 或 dnsmasq。--use-rfc2307会在域结构里补充 POSIX 属性后续如果你要用 SSSD 或给 Linux 客户端做用户映射这组属性是前提。2.3 重跑防护与三种生成文件的落位脚本里我加了「重复执行直接退出」的判断这个判断不算严格但对生产环境够用。更稳妥的做法是把判断写成「检测到/var/lib/samba/private/sam.ldb存在就拒绝执行」因为 private 目录里才放着真正的 AD 数据库。provision 生成的文件分三处。第一处是/var/lib/samba/private/包括sam.ldb、krb5.conf、secrets.ldb权限默认是 0700属主默认是 root不要手动 chown否则 Samba 用另一个系统用户启动时反而读不到这一点在给某客户环境做迁移时踩过。第二处是/etc/samba/smb.confprovision 会生成一个基础配置Debian 上通常需要把它复制到/etc/samba下否则 samba 服务启动时读不到。第三处是/var/lib/samba/sysvol/用来存放组策略文件。对于smb.confprovision 生成的内容里idmap config *这些段不建议手工改动。实际操作中常见的问题是有人自作主张往[global]里加security user在 AD DC 模式下这是多余甚至有害的DC 模式下的安全模型由server role自动决定。3. 把 Samba 4 DC 交给 Systemd自启、Kerberos 联动与日志量控制3.1 Stretch 自带服务单元Jessie 需要手写一个Debian 9 Stretch 的 samba 包里已经带了一个samba-ad-dc.service单元专门给 AD DC 使用安装后直接systemctl enable samba-ad-dc就行。但 Debian 8 Jessie 的 samba 默认只有samba.service这个单元在 AD DC 模式下并不完全适用最典型的症状是启动后服务显示 active 但实际监听端口不对查看ss -lnt发现 389、88 这些端口根本没起来。我在 Jessie 上的做法是自己写一个单元文件放到/etc/systemd/system/samba-ad-dc.service内容如下[Unit] DescriptionSamba AD DC Afternetwork.target network-online.target Wantsnetwork-online.target [Service] Typenotify ExecStart/usr/sbin/samba -D ExecReload/bin/kill -HUP $MAINPID PIDFile/run/samba/samba.pid LimitNOFILE16384 [Install] WantedBymulti-user.targetTypenotify 需要 samba 编译时带 systemd 支持Debian 官方包没问题。执行systemctl daemon-reload后 enable 这个服务重启后 DC 会自动拉起来。3.2 开机顺序和 DNS 就绪的联动AD DC 启动时要做 DNS 自检如果机器的网络没就绪服务会反复重启。这就是为什么单元文件里要加上network-online.target。很多人的做法是只写Afternetwork.target这在系统启动阶段可能不够因为 network.target 只表示网络接口已注册不代表已经拿到 IP 或路由可用。我一般会再叠加一个判断在启动脚本或单元里等待 DNS 能被正常解析。最省事的办法是编辑/etc/systemd/system/samba-ad-dc.service.d/override.conf[Service] ExecStartPre/bin/bash -c until getent hosts $(hostname -f); do sleep 2; done这段逻辑的意思是启动真正执行前先反复解析自己的完整域名解析成功才继续如果 60 秒内一直失败服务的启动会被拖住此时去看journalctl -u samba-ad-dc就会看到ExecStartPre超时的信息。3.3 Kerberos realm、krb5.conf 与 /etc/hosts 三者的匹配kinit administratorEXAMPLE.LOCAL是部署后必做的一次验证失败原因里十有八九是 realm 匹配问题。provision 生成的krb5.conf会写到/var/lib/samba/private/脚本里我们把它复制到了/etc/krb5.conf复制前需要确认里面libdefaults的default_realm是大写而且realms段里 realm 名称也和 provision 参数一致。[libdefaults] default_realm EXAMPLE.LOCAL dns_lookup_kdc true dns_lookup_realm false rdns false [realms] EXAMPLE.LOCAL { kdc dc1.example.local admin_server dc1.example.local }dns_lookup_kdc true让客户端通过 DNS SRV 记录找 KDC这是 Samba 4 内部 DNS 的常规玩法。容易踩的坑在/etc/hosts机器名和 IP 的映射如果只写了短名dc1没写完整域名Samba 启动时解析自己的 FQDN 会失败。所以脚本里我在 provision 前用hostname命令把短名和 FQDN 都追加进/etc/hosts这一句看起来不起眼但属于典型的不加必翻车的系统配置。3.4 日志量与 sysvol 权限的日常维护Samba 4 的日志默认打到 journaldlog level默认是 1正常情况下日志量不大。但如果你在调试网络问题上把log level 4打开而忘了改回来journald 的/var/log/journal会在几天内吃到几个 GB。我习惯在脚本里固定追加一段覆盖配置[logging] log level 1 log file /var/log/samba/log.%m max log size 102400注意 DC 模式下服务的进程是统一的samba进程log.%m按客户端机器名拆分会生成大量小文件所以max log size一定要设。另外 sysvol 目录一旦被手动 chown 或者权限被改到 777Samba 会在每个 smbd 子进程访问时刷access denied错误而且不会影响进程启动只会在日志里反复出现排查手段是检查/var/lib/samba/sysvol的属主和权限正常应该是 root:root 且目录是 2775 风格的特权位配置。4. 域控备份、还原与共享迁移三套可直接改用的脚本4.1 备份脚本按在线与离线模式各写一支Samba 4 的官方备份工具是samba-tool domain backup它有两种模式online模式不停服务直接备份适合工作日跑offline模式要求 Samba 停下来适合计划维护窗口。两种模式的产物都是一个 tar 包里面包含sam.ldb、sysvol、secrets.ldb等完整数据。#!/usr/bin/env bash set -euo pipefail BACKUP_DIR/srv/backup/samba KEEP_DAYS7 DC_HOSTNAMEdc1 # 确认备份目录存在并且可写 mkdir -p $BACKUP_DIR if ! touch $BACKUP_DIR/.write_test; then echo 备份目录不可写 exit 1 fi rm -f $BACKUP_DIR/.write_test # 离线模式需要先停服务 systemctl stop samba-ad-dc samba-tool domain backup offline \ --targetdir$BACKUP_DIR \ --server$DC_HOSTNAME /dev/null systemctl start samba-ad-dc # 清理过期备份 find $BACKUP_DIR -name *.tar.bz2 -mtime $KEEP_DAYS -delete离线模式的坑在于备份窗口内域控完全不可用如果你只有一台 DC备份期间 DHCP 客户端加域、改密码都会失败。所以我的习惯是工作日用 online 模式每天一次周末维护窗口再跑一次 offline 全量。online 模式的命令只需要把offline换成online不需要停服务。备份目录的剩余空间也要提前检查缺个几百 MB 在备份执行到一半时才会暴露问题。我通常会在脚本里加一行df -P $BACKUP_DIR | awk NR2 { if ($4 1048576) exit 1 }把剩余空间低于 1 GB 作为提前退出的条件。4.2 还原流程先停服务、再解包、最后医生检查备份的后悔药比备份本身更重要。还原流程我固定写成下面几步#!/usr/bin/env bash set -euo pipefail BACKUP_FILE$1 # 停服务防止数据库被写 systemctl stop samba-ad-dc # 保留现场不直接删除旧数据 if [[ -d /var/lib/samba.bak ]]; then rm -rf /var/lib/samba.bak fi mv /var/lib/samba /var/lib/samba.bak # 解包备份 tar -xjf $BACKUP_FILE -C /var/lib/samba # 修复基本权限属性细节保持包内原样 chown -R root:root /var/lib/samba/sysvol systemctl start samba-ad-dc还原之后必须做验证我一般跑三条命令smbclient //127.0.0.1/netlogon -U administrator -c ls验证共享可用samba-tool domain info 127.0.0.1验证域控制器角色识别kinit administratorEXAMPLE.LOCAL验证 Kerberos 票据能发出来然后立刻kdestroy清掉。这里有一个特别注意的地方还原后旧日志和旧 secrets 都会被替换原来那些机器的机器账号信任关系是依赖域内数据库的所以备份前加域的新机器在还原到旧备份后可能失效需要重新加入域。这是 Samba 4 备份还原的固有边界不是脚本能绕开的。4.3 共享目录迁移rsync 保留 xattrACL 单独导出恢复域控上的文件共享迁移最常见的场景是把某台 DC 上的业务共享从一块旧盘挪到新盘或者换到独立存储。Samba 的 POSIX ACL 存储在文件系统扩展属性里所以 rsync 必须带-X此外迁移时 SMB 打开的文件不能硬拷要错峰。#!/usr/bin/env bash set -euo pipefail SRC/srv/shares/business DST/data/shares/business # 第一轮全量复制 rsync -aX --partial --delete \ $SRC/ $DST/ # 停写窗口确认没有 SMB 锁 smbstatus -L | grep -v No locked files || true # 第二轮增量复制把第一轮期间变化的少量文件同步过去 rsync -aX --partial --delete \ $SRC/ $DST/-a保留权限和时间戳-X保留扩展属性--partial让中断的大文件可继续。如果没有-X迁移后共享在 Windows 上打开文件会提示权限错误因为 Samba 的 ACL 信息丢了。smbstatus -L用来确认没有用户还开着文件如果输出里有锁就要通知用户退出否则第二轮增量后仍可能有文件不一致。迁移完成后改smb.conf里对应共享的path然后重启 samba 服务。ACL 层面如果之前用samba-tool ntacl做过 domain 级 ACL 导出迁移后用samba-tool ntacl sysvolreset重置 sysvol 的 ACL 即可业务共享的 ACL 已经随 xattr 走了一般不需要额外处理。5. Debian Jessie 与 Stretch 跑 Samba 4 脚本的避坑与排查记录5.1 Provision 提示找不到合适的 base DN现象执行samba-tool domain provision时直接报错类似Unable to find suitable base DN整个脚本中断。原因provision 会尝试从系统的 DNS 配置解析域后缀如果/etc/hosts里没有完整域名记录或者resolv.conf的search段没有带 realm 后缀provision 无法拼出 base DN。解决在跑脚本前先把dc1.example.local和短名写进/etc/hosts并且确认hostname -f返回的是完整域名。我在 2.2 的脚本里已经把追加 hosts 放在 provision 之前顺序不能颠倒。5.2 重启后 DC 起不来journalctl 报 Kerberos 错误现象重启后samba-ad-dc反复重启journal 里出现类似kerberos_kdc: kdc startup failed的记录。原因最常见的是/etc/krb5.conf缺失或与 provision 参数不一致其次是/var/lib/samba/private目录权限被改成非 root 属主Samba 启动时读不到密钥文件。解决先确认krb5.conf是否由 provision 生成并复制到了/etc/krb5.conf再检查 private 目录属主。这里最大的教训是不要手动 chown private 目录Debian 包安装后默认 root 属主直接保持即可。5.3 samba 服务一直卡在 activating现象systemctl status samba-ad-dc显示 activating过很久才变成 failed但手动执行/usr/sbin/samba -D又能起来。原因Jessie 上直接把老的samba.serviceenable 了而它内部不包含network-online.target的依赖也不会等待 DNS 就绪或者 Type 设置与实际进程行为不符。解决按 3.1 的方式手写单元文件并 deferdaemon-reload后再 enable。如果已经在用samba-ad-dc.service就用 3.2 的ExecStartPre加一段 DNS 等待这是我在某测试环境里踩过的坑症状一模一样。5.4 Jessie 里找不到 samba-tool domain backup 子命令现象脚本里调用samba-tool domain backup online时提示未知子命令命令帮助里也看不到 backup 项。原因domain backup子命令加入的时间点晚于 Debian Jessie 默认的 samba 4.2 系版本我在 Jessie 上遇到过直接用官方源里的 samba 包没有这个子命令的情况。解决把系统源切到对应的 backports 仓库升级 samba或者干脆改用离线备份方案停服后直接打包/var/lib/samba和/etc/samba。注意混合版本时不要只升级 samba-tool 而不升级 samba 本体两者要一起升。5.5 Stretch 升级后 SID 映射丢失共享 ACL 像消失了一样现象从 Jessie 升级到 Stretch 后原有共享在 Windows 上访问时所有权限提示拒绝看起来像 ACL 全部丢失。原因升级过程中/var/lib/samba/private/里的域 SID 与用户映射记录没有被正确迁移或者smb.conf里idmap config段被覆盖写导致映射错乱。解决先不要重新 provision恢复升级前备份的private目录对比smb.conf里idmap config *的 backend 配置是否与旧环境一致。最稳妥的路径是升级前先跑一次 4.1 的离线备份升级后用 tar 包还原数据库而不是让升级脚本自动处理这些文件。6. 用 samba-tool 持续验证给 DC 跑一次全身体检6.1 一键体检脚本与执行顺序我把部署、备份之外的经验沉淀成了一个check_dc.sh每次改完配置都跑一遍。它按顺序检查五件事DNS 解析、Kerberos 票据、域控制器信息、DRS 复制状态、时间偏移。顺序不能乱因为后面的检查依赖前面的成功。#!/usr/bin/env bash set -euo pipefail REALMEXAMPLE.LOCAL echo DNS 检查 getent hosts dc1.example.local echo Kerberos 票据检查 echo $ADMIN_PASS | kinit administrator$REALM klist echo 域控制器信息 samba-tool domain info 127.0.0.1 echo DRS 复制状态 samba-tool drs showrepl echo 时间同步检查 samba-tool time 127.0.0.1 echo 清理票据 kdestroy这套脚本的价值在于域控环境故障往往不会直接体现在「服务挂了」上而是「某台机器突然不能加域了」「某个用户改密码失败」这种间接症状。这时候按顺序跑一遍第一处报错就是排查入口DNS 挂了先修解析Kerberos 报了就先看 krb5.confDRS 复制滞后就看网络和站点配置。我这个习惯是被一次事故逼出来的。某次帮客户变更 DC 的主机名我改完/etc/hosts后忘了检查 DRS 复制第二天第二台 DC 的账号数据全部不同步花了整个上午对比数据库状态。后来我就把上面的体检脚本固定为每次变更后的第一件事跑完再继续下一步操作。脚本里几乎所有命令都能在十分钟内出结果而它们覆盖的恰恰是 Samba 4 运作的核心链路。希望这篇笔记能把你在 Debian Jessie 与 Stretch 上把玩 Samba 4 脚本时最容易踩的那些坑提前排掉让脚本化和可验证成为你做域控相关配置时的默认习惯。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站