ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Ubuntu 20.04 Samba 启动失败 status=255 排查修复

Ubuntu 20.04 Samba 启动失败 status=255 排查修复 装完 Samba 敲下systemctl start smbd终端里直接甩出一行Job for smbd.service failed because the control process exited with error code再systemctl status smbd一看末尾赫然写着status255/n/a——这个画面我在 Ubuntu 20.04 上见过太多次了。它跟一般的“配置写错了”完全不是一个性质testparm可能一句报错都没有共享目录权限看着也没问题但服务就是起不来。很多人第一反应是重装 Sambaapt purge三遍结果一样。其实 error255 是 smbd 进程自己给自己判了“死刑”代码里明确exit(255)才会出现这个退出码它背后通常藏着路径缺失、状态目录权限被改动、接口绑定不匹配、TDB 数据库损坏这几类硬伤。这篇内容我就按 Ubuntu 20.04 Samba 4.11 这套最典型的组合把 error255 从“为什么”到“怎么修”整条链路拆开讲顺带把我这些年踩过的坑全摊开。不管你是第一次在虚拟机上搭文件共享还是给公司的内网机器配共享盘只要你遇到 255基本都能在这里找到对应分支。1. 先搞清楚 error255 到底在说什么1.1 退出码 255 的真实含义站在 systemd 视角看问题很多人把 255 当成“Samba 的某个报错编号”这个理解方向就偏了。在 Linux 里进程退出码 0 代表正常结束1 到 125 是程序自定义的业务错误码126 和 127 与“命令不可执行 / 找不到命令”相关128 到 254 通常跟信号量挂钩而255 是一个“兜底值”——当程序内部判定自己处于一种“无法继续、也不属于任何已知错误分类”的状态时最省事的做法就是直接exit(255)。Samba 源码里大量存在这种写法初始化阶段一旦发现某个必须存在的目录拿不到、某个文件打不开、某个配置文件无法解析代码不走恢复逻辑直接返回 255 收场。systemd 的角色只是“记录者”。Ubuntu 20.04 上smbd.service是Typenotify类型意思是 systemd 启动 smbd 之后会等它通过 sd_notify 发一个READY1的信号才认为服务启动成功。如果 smbd 在发信号之前就退出了systemd 就会把它的退出码原样报出来于是你看到的日志长这样smbd.service: Main process exited, codeexited, status255/n/a smbd.service: Failed with result exit-code. Failed to start Samba SMB Daemon.注意最后那行Failed with result exit-code它跟result timeout超时未就绪和result signal被信号杀掉是两个不同的分支。看到exit-code就说明进程是主动退的不是被 OOM 干掉也不是卡死。这一点很关键它直接决定了排查方向你要找的是“smbd 在启动过程中主动放弃”的原因而不是“端口被占”或者“内存不够”这类外部因素——虽然端口冲突有时也会以 255 的形式表现但那是少数派。另外提醒一句status255后面那个/n/a表示 systemd 没能拿到更细的信号信息这是正常的别被它误导。真正有用的信息在它上面的几行以及journalctl -xeu smbd展开后的上下文里。1.2 三类最典型的触发场景与我的分类法踩坑多了以后我把 Samba 的 error255 归结成三大类按出现频率从高到低排路径与权限类、配置与接口类、数据与状态残留类。路径与权限类占了我遇到案例的一半以上。典型的比如/var/run/samba这个运行时目录被清掉或者权限被改成了 0755 以下/var/lib/samba/private的属主从 root 变成了别的用户/var/log/samba不存在导致log file写不进去。这类问题的共同特点是testparm -s会告诉你语法全对但smbd -i前台运行时会立刻抛出一行Unable to create directory ...或者Could not open ...然后就退出了。配置与接口类相对隐蔽一些。interfaces和bind interfaces only这两个参数组合是经典陷阱有人从别的机器上抄了一份 smb.conf里面写着interfaces lo eth0、bind interfaces only yes而 Ubuntu 20.04 的网卡叫ens33或enp0s3结果 smbd 绑定不到任何有效接口直接退出。还有一个隐藏更深的变体是netbios name字段——它默认为主机名但 NetBIOS 名字长度上限是 15 个字符且不允许空格和下划线之外的怪符号主机名一旦超标或者带特殊字符nmbd 那侧就会出问题有些发行版会把错误合并报给 smbd最终表现为 255。数据与状态残留类最难查也最容易让人怀疑人生。典型代表是passdb.tdb、secrets.tdb这类 TDB 数据库在断电或强制关机后损坏smbd读它时直接失败。另一个变体是系统里同时存在两套 Samba一个是 apt 装的/usr/sbin/smbd另一个是手工编译装在/usr/local/samba的PATH或者 systemd unit 指向了错误的那个两边状态目录对不上也会 255。提示判断属于哪一类有一个 30 秒的快速方法——直接sudo smbd -i -d 3前台、调试级别 3跑一次看它在退出前最后打印的那几行。所有 255 场景里日志的最后 5 行几乎都直指根因。2. 从零复现Ubuntu 20.04 上 Samba 安装与最小可用配置2.1 安装包选型与 apt 源确认先把环境说清楚。Ubuntu 20.04 官方源里的 Samba 版本是 4.11.x这一代的配置语法和 4.0 之前的差异非常大网上大量老教程里的security share早就被移除了照抄必翻车。安装本身很简单sudo apt update sudo apt install -y samba samba-common-bin smbd --versionsmbd --version应该输出类似Version 4.11.6-Ubuntu。如果这条命令报找不到多半是samba和samba-common-bin只装了一个或者PATH被人改过——这也算是一种“伪 255”服务能起但客户端连不上容易被误判。关于源我个人的习惯是保持官方源不动。见过不少人为了让下载快点把源换成一堆乱七八糟的镜像结果samba-common-bin和samba版本不一致运行期库函数对不上启动阶段直接崩。真遇到源慢换一个国内主流的镜像站就够不要混用多个源。安装完成后先别急着改配置先确认几个关键目录的状态ls -ld /etc/samba /var/log/samba /var/lib/samba /var/lib/samba/private /run/samba正常输出的属主组装应该全是root:root权限大致是/var/log/samba为 0755、/var/lib/samba/private为 0700、/run/samba为 0755。这里任何一项不对后面都可能演化成 255。我习惯在改配置之前先把这四行输出存到笔记里出问题时有对比基线。2.2 一份经过验证的最小 smb.conf与其在 Ubuntu 默认那 300 行带注释的smb.conf上改来改去不如直接换成一份干净的最小配置。默认文件先备份sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.orig sudo tee /etc/samba/smb.conf /dev/null EOF [global] workgroup WORKGROUP server string Ubuntu 20.04 File Server netbios name UBSRV server role standalone server security user map to guest never log file /var/log/samba/log.%m max log size 5000 logging file log level 1 obey pam restrictions yes unix password sync yes passwd program /usr/bin/passwd %u pam password change yes usershare allow guests no idmap config * : backend tdb [share] path /srv/share browseable yes read only no valid users smbuser create mask 0664 directory mask 2775 force group smbgroup EOF这份配置里每一行都有理由。server role standalone server明确告诉 Samba 这是一台独立服务器不是域控很多 255 案例就是因为从域控配置里抄了server role active directory domain controller但环境里根本没有 Kerberossmbd 启动初始化阶段就会放弃。logging file是 4.11 推荐的新写法替代老旧的syslog only之类。idmap config * : backend tdb单独列出来是因为 Ubuntu 上如果这个参数缺失且系统又装过 winbindidmap 初始化可能失败。create mask 0664和directory mask 2775这两个值值得展开算一下。0664 拆成二进制是rw-rw-r--意思是新建文件时属主和属组都有读写权限其他人只读。2775 里的首位 2 是setgid 位它让目录里新建的子目录和文件自动继承父目录的属组——这正是团队共享盘最需要的特性。775 部分即rwxrwxr-x。这两个 mask 和后面要设置的目录权限必须互相匹配否则会出现“能连上但写不进去”的二级故障。注意绝对不要在[share]段里写path /或者path /home。共享根目录会把自己 open 到 AppArmor 和权限系统最容易出问题的区域我见过因为共享/home导致 smbd 启动时尝试遍历目录撞上某个用户的 0700 家目录而退出的案例。2.3 用户与目录权限的建立顺序顺序错了就出 255顺序非常重要先建系统组和系统用户再建共享目录并设权限最后才加 Samba 密码。颠倒这个顺序是新手最容易制造 255 的方式之一。sudo groupadd -r smbgroup sudo useradd -r -M -s /usr/sbin/nologin -G smbgroup smbuser sudo mkdir -p /srv/share sudo chown -R root:smbgroup /srv/share sudo chmod 2775 /srv/share sudo smbpasswd -a smbuser sudo pdbedit -Luseradd那几个参数不是随便写的。-r建的是系统用户UID 落在 1000 以下的区间不会在登录界面出现-M表示不建家目录因为 Samba 用户不需要登录 shell-s /usr/sbin/nologin明确禁止交互登录这是安全上的基本要求。smbpasswd -a才是真正往passdb.tdb里写 Samba 独立密码的动作它和 Linux 系统密码是分开的两套这一点务必记住——很多人改完passwd发现 SMB 登录密码没变原因就在这里。pdbedit -L应该输出smbuser:1001:这样的行冒号后面那一串是 SID 尾部数字。如果这条命令报Unable to open passdb database或者干脆没输出说明密码库这一步就出问题了此时去systemctl start smbd大概率拿到 255。所以我的做法是在启动服务之前先用testparm和pdbedit -L各验一遍两个都通过再去起服务能省掉大量来回。最后合起来验证testparm -s sudo systemctl restart smbd nmbd systemctl status smbd --no-pager -l到这里如果 status 显示active (running)那就一切正常。如果显示 255进入下一章的排查链路。3. 定位 error255 的完整排查链路3.1 第一现场journalctl 与 /var/log/samba 日志怎么读排 255第一件事永远是看 journal而不是去网上搜“samba error255 解决方法”然后一条条试。systemctl status smbd --no-pager -l journalctl -u smbd -b --no-pager | tail -60-b限定本次启动周期--no-pager避免分页器挡住输出tail -60是因为关键信息通常就在末尾几十行里。如果你想让 journal 把每条日志的说明和可能的建议都展开用journalctl -xeu smbd这里的-x会附带解释文本-e跳到末尾。读完 journal 还不够/var/log/samba/下的文件才是 smbd 自己的日志尤其是log.smbdls -l /var/log/samba/ sudo tail -80 /var/log/samba/log.smbd这里有个常见现象/var/log/samba/里可能只有一个空的log.smbd什么内容都没有而 journal 里也只有那两行 systemd 的报错。这说明 smbd 在人还没来得及写日志的时候就已经退出了属于“极早期失败”。这种情况十有八九是路径问题——log file指定的目录不可写或者smbd -b里的LOGFILEBASE指向了别的地方。smbd -b | grep -E CONFIGFILE|LOCKDIR|STATEDIR|PRIVATE_DIR|LOGFILEBASE|PIDDIR这条命令会把编译期固化进去的路径全列出来。把输出和ls -ld的实际目录状态逐一对照谁不存在、谁权限不对一眼就能看出来。我遇到过最离谱的一个案例PIDDIR指向/var/run/samba而/var/run是个 tmpfs重启后被清空开机自启的 smbd 因为建不了 PID 目录直接 255手动systemctl start却能起来——因为手动启动时目录已经被上一次的某个操作创建过了。这种“开机自启失败、手动启动成功”的时序型 255用journalctl -b对照两次的日志差异就能锁定。3.2 第二现场testparm 与前台调试模式testparm -s是最基础的语法校验但很多人只看它有没有报错忽略了一个细节它输出的内容里如果有Unknown parameter警告未必是致命问题但如果有ERROR字样就必须处理。testparm -s testparm -v | grep -iE error|unknown|ignored-v会输出所有参数的当前取值包括默认值。我曾经靠这条命令发现有人把server min protocol设成了NT1同时又在另一处写了冲突的client min protocol两者在 4.11 里会触发初始化逻辑异常。这类冲突-s是不报的只有-v展开才看得见。真正定位极早期 255 的杀器是前台调试模式sudo systemctl stop smbd sudo smbd -i -d 3 -s /etc/samba/smb.conf-i表示前台运行、不 fork 到后台-d 3是调试级别 3。区别在于通过 systemd 启动时错误只留个退出码给你前台跑的时候错误信息直接打在终端上包括它试图打开哪个文件失败、errno 是多少。我的经验是把-d调到 3 就够调到 10 会刷屏反而难找重点。实测下来90% 的 255 在前台模式下会在 10 秒内打出根因。如果前台模式输出的信息仍然很含糊比如只显示smbd version 4.11.6 started然后直接退那就上 stracesudo strace -f -tt -o /tmp/smbd.strace smbd -i -d 1 grep -nE EACCES|ENOENT|EPERM|ENOTDIR /tmp/smbd.strace | head -40strace会把所有系统调用记录下来EACCES是权限不足ENOENT是路径不存在EPERM是操作被禁止。这三个只要出现基本就是答案。这个方法有点重但在“日志什么都不说”的极端情况下是唯一能挖到底的手段。3.3 第三现场接口绑定、端口占用与 AppArmor前两现场都排查完还没结果就要往系统和网络层面看。ss -lntp | grep -E :445|:139 ip -brief addr show第一条看 445 和 139 端口有没有被别的进程占着。正常情况下这两个端口应该空闲如果显示被某个陌生的 smbd、或者 Docker 的容器进程占着那新起的 smbd 绑定失败会退出。我见过在虚拟化环境里宿主机也跑了 SambaNAT 模式下端口映射混乱导致的绑定失败。第二条看本机实际的接口名。Ubuntu 20.04 的网卡名几乎不可能是eth0桌面版通常是ens33、enp0s3笔记本上还可能是wlp3s0。如果你的smb.conf里写了interfaces lo eth0 bind interfaces only yes那 smbd 会找不到eth0绑定不上任何接口。修复方式有两种把这行改成实际接口名或者干脆删掉这两个参数。我通常建议内网环境直接删掉因为默认行为就是监听所有接口除非你有明确的多网卡隔离需求否则这两个参数带来的只有麻烦。AppArmor 是 Ubuntu 特有的一层Samba 自带策略文件/etc/apparmor.d/usr.sbin.smbd。如果策略加载异常smbd 访问某些路径时会被内核拦掉表现就是 255 或者能启动但读不到文件。aa-status | grep -i smbd sudo journalctl -k | grep -i apparmor | tail -20aa-status会列出当前处于 enforce 状态的 profile。如果在journalctl -k里看到类似apparmorDENIED operationopen profile/usr/sbin/smbd的记录那问题就在这。处理方法是重新加载策略sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.smbd sudo systemctl restart smbd如果重新加载还是被拦说明你的共享目录不在策略允许的路径列表里。我个人更推荐的做法是把共享目录放在/srv下因为 Ubuntu 默认策略里/srv/**是允许的而放/data、/mnt/xxx这类自定义路径就常常要额外改策略。这是我在被 AppArmor 坑了两次之后固定下来的习惯。4. 五类真实案例的逐条复现与修复4.1 配置语法与废弃参数导致的启动即退这类案例的特征是改完配置立刻起不来之前是好的。有一次同事在[global]里加了一行security share因为他照着 2013 年的一篇博客配游客共享。这条参数在 Samba 4.0 之后就被移除了,4.11 里 Samba 的处理方式比较特殊——它在解析阶段把它当成未知参数记一条警告但在某些组合条件下会触发参数校验失败直接返回 255。复现很简单在那个最小配置的[global]段里加一行security share然后sudo smbd -i -d 3你会看到类似lp_load_ex: Ignoring unknown parameter security的提示接着进程退出。修复就是删掉它用现代写法实现游客访问[public] path /srv/public guest ok yes read only yes force user nobody另一个高频踩坑是netbios name超长。比如把主机名改成了ubuntu-dev-server-01一共 19 个字符超过 15 字符上限。此时默认继承主机名的 netbios name 就不合法了。hostname hostname | wc -c修复办法是显式指定一个短名netbios name UBSRV同时值得一并检查的是workgroup。如果它设成了一个含空格或者非 ASCII 字符的名字也可能在名称解析阶段出问题。我自己定下的规矩是workgroup 和 netbios name 只用大写字母、数字和短横线长度都控制在 15 以内。还有一类比较隐蔽的是include指令指向不存在的文件include /etc/samba/conf.d/custom.conf如果这个目录不存在或者文件被删了部分场景下 smbd 会直接放弃启动。排查时用grep -rn include /etc/samba/smb.conf把所有 include 找出来逐个确认文件存在。4.2 目录、权限与服务账户不一致这类是我遇到最多的。典型故事是这样的为了图方便把共享目录设在用户家目录下或者用chmod -R 777一把梭然后过几天发现问题。先看权限不对的版本sudo chown -R someuser:someuser /var/lib/samba/private一旦这个目录的属主不是 root/var/lib/samba/private下存放的secrets.tdb、passdb.tdb就可能读不了smbd 启动时打不开密码库直接 255。修复sudo chown -R root:root /var/lib/samba/private sudo chmod 0700 /var/lib/samba/private sudo systemctl restart smbd这里 0700 是有讲究的不是随手的值。/var/lib/samba/private里存放的是密码数据库的鉴权信息权限必须严格限制为 root 独占读写执行其他任何位都不能开放。同理/var/lib/samba/winbindd_privileged通常要求是 0750 且属组为winbindd_priv。这些值在 Ubuntu 的包安装脚本里本来会设好一旦你手工动过目录或者用chmod -R覆盖过就会被破坏。第二个变体是共享目录的路径根本不存在。配置文件里写了path /srv/share但/srv/share没建。Samba 在启动时是否检查这个路径取决于版本和具体配置项但 4.11 在[share]段被实际加载时有概率直接失败。所以共享目录一定要先建好sudo mkdir -p /srv/share ls -ld /srv/share第三个变体更绕目录存在、权限也放开了但SELinux 或者文件系统层面的 ACL拦住了。Ubuntu 默认不用 SELinux但如果你从 CentOS 那边迁移过来习惯性装了selinux-utils就可能有策略残留。用getenforce确认一下是Disabled或Permissive就不会有影响。至于 ACL用getfacl /srv/share看一眼如果输出里有一大堆# file:开头的细粒度规则也要留意是不是有mask::---这种把所有权限都掐掉的设置。关于共享目录放哪里我的选择顺序是/srv优先其次/home/samba坚决不放/media、/mnt下的挂载点。原因很实在挂载点在开机早期可能还没挂上而 smbd 又设了开机自启两者抢时间就会周期性出 255。4.3 网络接口与 netbios name 冲突前面提过interfacesbind interfaces only的组合这里给一个完整的复现和修复过程。假设你的机器接口是ens33配置里写的是interfaces lo eth0 bind interfaces only yes前台调试会看到类似Unable to find interface eth0然后退出。修复有两个方向。方向一是改成实际接口名ip -brief addr show | awk {print $1}拿到真实名字后改成interfaces lo ens33。方向二是直接删掉这两行。我强烈建议后者除非你明确需要 Samba 只在一个接口上提供服务——比如一台机器同时接内网和外网只允许内网访问共享。这种情况下正确写法还得配合hosts allowinterfaces lo ens33 bind interfaces only yes hosts allow 192.168.1.0/24 127.0.0.1 hosts deny 0.0.0.0/0注意hosts deny 0.0.0.0/0作为兜底这样即使接口绑定出问题也不会意外把共享暴露出去。这个组合我在多网卡服务器上用过多次逻辑上是“先只监听指定接口再在指定接口上只放行指定网段”两层过滤。另一个偶发场景是虚拟机克隆。用 VMware 或者 VirtualBox 克隆出来的 Ubuntu主机名和网卡 MAC 都变了但smb.conf里还留着旧机器的netbios name和interfaces开机后 nmbd 尝试注册一个已经被别的机器占用的名字冲突之下可能连带影响 smbd 的启动流程。判断方法是看 nmbd 的日志sudo tail -50 /var/log/samba/log.nmbd如果看到name conflict或者registering name ... failed就改掉netbios name。这一步在克隆环境里我几乎是必做的。4.4 TDB 数据库损坏与状态残留这一类的触发条件通常是断电、强制关机、或者容器里直接kill -9掉 smbd。TDB 是 Samba 自己实现的一种键值数据库格式它不像 MySQL 那样有完善的事务日志写入过程中被打断就有概率留下损坏文件。表现是sudo smbd -i -d 3输出里出现tdb(/var/lib/samba/private/passdb.tdb): tdb_open failed或者Corrupt database。确认损坏可以用 tdb 工具sudo tdbbackup -v /var/lib/samba/private/passdb.tdb sudo tdbdump /var/lib/samba/private/passdb.tdb | headtdbbackup会尝试做一个备份并校验如果它报错基本就是坏了。修复思路是“先备份再重建最后恢复用户”sudo systemctl stop smbd nmbd winbind sudo mv /var/lib/samba/private/passdb.tdb /root/passdb.tdb.broken sudo systemctl start smbd sudo smbpasswd -a smbuser sudo pdbedit -L把损坏文件移走之后smbd 会在启动时自动创建一个全新的空passdb.tdb。代价是之前的所有 Samba 用户都要重新smbpasswd -a加一遍。所以如果你手里有用户清单重建工作就是几条命令的事。这也是我为什么坚持在笔记里记录所有 Samba 用户名——真到重建那天能省半小时。secrets.tdb损坏的修复方式类似但要注意它里面存的是机器账户密钥、域信任等信息独立服务器场景下重建影响不大域环境里就要谨慎最好先从好的备份恢复。registry.tdb相对独立删掉重建一般也不影响共享功能。还有一个容易被忽视的状态残留是 PID 文件。如果 smbd 被强杀/run/samba/smbd.pid可能残留新进程启动时看到 PID 存在会尝试检查旧进程是否活着逻辑出错也会退。清理方式sudo rm -f /run/samba/*.pid sudo systemctl restart smbd注意执行任何删除 TDB 或 PID 的操作前一定先 stop 掉 smbd、nmbd、winbind 三个服务否则运行中的进程会持有文件句柄删了也不生效甚至让状态更乱。4.5 打印服务、容器与无关依赖的连带失败Samba 默认会加载打印相关模块如果你机器上没装 CUPS 或者cups服务状态异常某些配置组合下 smbd 启动阶段会因为打印子系统初始化失败而退出。表现是日志里出现cups关键字。systemctl status cups --no-pager dpkg -l | grep -i cups如果你的共享里根本不需要打印功能最干净的做法是在[global]里显式关掉load printers no printing bsd printcap name /dev/null disable spoolss yes这四行我几乎加在每一份不需要打印的配置里能省掉一大堆无谓的系统依赖检查。实测下来服务启动速度也快了一点。容器环境是另一个高发区。在 Docker 里跑 Samba常见的 255 原因是/run/samba目录在容器重建后没被创建以及容器的网络命名空间让interfaces参数失效。我的处理方式是在 entrypoint 或者 systemd 前置脚本里固定加一段mkdir -p /run/samba /var/log/samba /var/lib/samba/private chown root:root /var/lib/samba/private chmod 0700 /var/lib/samba/private顺序是先建目录、再设属主、最后设权限。这里顺序错了比如先 chmod 后 chown权限位有可能被 chown 重置掉一部分尤其是在挂载了宿主机目录的场景里。顺便说一下和虚拟化相关的网络VMware 的 NAT 模式下虚拟机的地址是 192.168.x.x 的私有段主机访问虚拟机的 Samba 需要做端口转发或者用桥接模式。这跟 255 本身没关系但会让你在“服务已经起来”的情况下误以为是启动失败。判断方法很简单systemctl status smbd如果是绿色 active就别再折腾服务了去看网络。5. 常见问题速查表与避坑心得5.1 error255 排查速查表把上面所有分支整理成一张表遇到问题按行匹配能省掉大量翻日志的时间。症状线索关键判据命令大概率根因修复动作journal 只有两行log.smbd 为空smbd -b | grep LOGFILEBASE日志目录不存在或不可写建目录并 chown root:root前台模式报Unable to find interfaceip -brief addr showinterfaces 参数写了 eth0改实际网卡名或删该参数报tdb_open failed/Corrupttdbbackup -v fileTDB 数据库损坏移走损坏文件后重建用户开机自启失败、手动启动成功journalctl -b -u smbd/run/samba 时序或 tmpfs 清空加 ExecStartPre 建目录报Ignoring unknown parameter后退出testparm -s用了已废弃参数删除并按新语法改写有apparmorDENIED内核日志journalctl -k | grep apparmorAppArmor 拦路径重载策略或改到 /srv端口绑定失败ss -lntp | grep :445445 被占用找出占用进程并停掉pdbedit -L 报错或空输出pdbedit -L密码库不可用重建 passdb.tdb克隆虚拟机后必现hostname长度netbios name 冲突或超长显式设为短名这张表我贴在自己服务器的备忘里两年下来覆盖了绝大部分情况。剩下的少数派就靠strace或者干脆把配置降级到最小可用版本再逐步加回去定位。5.2 我踩过的坑与固化下来的操作习惯第一条习惯改配置之前永远先备份改完之后永远先testparm -s再重启服务。这条听起来像废话但我至少三次因为跳过testparm直接systemctl restart把一台好机器弄成了 255 状态然后花更多时间去回滚。testparm花 1 秒重启加排查花 20 分钟账很好算。第二条习惯共享目录放/srv下不用中文路径不用带空格的目录名。我遇到过共享目录名带空格导致path解析异常的情况虽然理论上引号能兜住但没必要给自己找麻烦。AppArmor 那边也是/srv最省事。第三条习惯给每个共享配独立的系统组用 setgid 目录而不是 777。chmod 777是新手最容易犯的错它意味着机器上任何用户都能读写共享内容而且新建文件的属主不受控后续排查权限问题时完全没有规律可循。用2775force group的组合权限模型清晰出问题也容易定位。第四条习惯先看 journal再看 smbd 自己的日志最后才看配置文件。顺序反过来就会出现“改了十遍配置问题依旧”的情况因为你根本没确认问题在配置层。日志是唯一权威的事实来源。第五条习惯在克隆或者迁移虚拟机之前先systemctl stop smbd nmbd让服务正常退出避免状态文件写入一半被打断。这个动作花 2 秒能避免前面说的 TDB 损坏那一整类问题。最后再分享一个特别实用的调试技巧当你不确定某个参数是不是罪魁祸首时把smb.conf临时替换成只有[global]加一个简单共享的最小版本跑一次smbd -i -d 3。如果最小版本能起来就说明问题在你自己加的参数里如果最小版本也起不来那就是环境层面的问题直接跳到第 3 章的环境排查。这个“二分法”能帮你把问题域一刀切开比逐行注释掉配置要快得多。还有一点关于密码同步的如果你希望 Samba 密码和 Linux 系统密码保持一致unix password sync yes配合pam password change yes这条链路是必要的但它要求passwd program里的路径必须是真实的/usr/bin/passwd。我见过有人把这行改成了一个自定义脚本脚本退出码非 0结果smbpasswd操作失败进而引发密码库写入异常最终演变成 255。所以这类联动配置在没搞懂之前不要动它。整套流程走下来error255 其实并没有想象中那么玄。它的本质是一个“初始化未完成就退出”的信号而 Ubuntu 20.04 上能让 smbd 初始化失败的因素就那么几类路径没了、权限被改了、接口找不到、数据库坏了、参数废弃了。把这五条对应到具体的检查和修复命令上剩下的就是耐心地按顺序排一遍。我自己现在的习惯是遇到 255 先跑一遍速查表的前三行八成问题在五分钟内就能收工。
返回列表