Samba多用户共享权限隔离实战:从配置到排错
发布时间:2026/10/23 8:10:50 锦皓数字建站

简介这份资源面向Linux运维人员与需要搭建跨平台文件共享环境的技术人员聚焦Samba共享目录的多用户权限控制这一常见难点。内容围绕用户与组的创建、smb.conf全局与共享段配置、valid users访问限制、目录属主与770权限设置以及服务重启与Windows客户端访问测试等环节展开帮助读者理清不同角色用户按需访问特定目录的实现思路。资源包为1个doc文档压缩包约5.03MB内容以配置示例与命令说明为主便于对照实践。目前已有4517人学习下载说明该主题在实际运维场景中关注度较高。读者可从中获得一套可参考的多用户权限配置案例理解共享目录隔离、权限掩码与安全优化等关键点适合作为Samba权限设置的实操参考与排错思路补充。1. 从一次“权限串门”事故说起Samba 多用户共享到底难在哪很多人第一次配 Samba 共享都是这么干的建一个公共目录writable yesvalid users users重启服务Windows 那边一映射能读能写收工。结果过两天同事跑来说A 的文件被 B 删了B 的目录里冒出来一堆不属于他的东西。你去翻smb.conf配置看着没毛病权限也给了问题出在哪问题在于 Samba 的权限是两层叠加的一层是 Samba 自己的用户认证和共享级权限另一层是 Linux 文件系统本身的属主、属组和 mode 位。只配上面那层下面那层是 777 或者属主全错等于门锁装了但墙是纸糊的。这份《Samba 共享目录的多用户权限设置案例个人精华版》整理的正是这条链路上最容易翻车的地方——从用户和组的映射、valid users与write list的配合到create mask、force user、force group这些参数怎么组合才能让每个用户只在自己的地盘里活动。它适合已经能把 Samba 跑起来、但被多用户隔离和权限继承折腾过的运维和开发也适合刚接手一台文件服务器、需要快速理清权限模型的新手。下面按“先立模型、再动手、最后排错”的顺序拆开讲。2. 先把权限模型立住Samba 用户、Linux 用户与共享级控制的三层关系2.1 为什么 Samba 需要单独一套密码Samba 用的是 SMB/CIFS 协议Windows 客户端发过来的认证请求走的是 NTLM 或 Kerberos跟 Linux 本地的/etc/shadow不是一回事。所以你在 Linux 上useradd建了用户还得用smbpasswd -a把这个用户加进 Samba 自己的密码库通常是passdb.tdb或 tdbsam 后端。这两套密码可以不一样但用户名必须对得上。常见做法是先建 Linux 用户不给他 shell 登录权限-s /sbin/nologin再用smbpasswd设 Samba 密码。这样用户只能通过 Samba 访问共享不能 SSH 登进来攻击面小一圈。# 建组作为共享访问的白名单组 sudo groupadd smbusers # 建用户-M 不建家目录-s 禁止 shell 登录 sudo useradd -M -s /sbin/nologin -G smbusers user1 sudo useradd -M -s /sbin/nologin -G smbusers user2 # 设置 Samba 密码这一步会写入 Samba 独立的密码库 sudo smbpasswd -a user1 sudo smbpasswd -a user2 # 启用账户有些发行版默认建完是 disabled 状态 sudo smbpasswd -e user1 sudo smbpasswd -e user2这里-G smbusers把用户加进附加组后面valid users smbusers就是靠这个组来放行。smbpasswd -a之后一定要-e启用否则认证会直接失败而且日志里不一定写得清楚这是新手最容易卡住的一步。2.2 共享级权限和文件系统权限怎么叠加Samba 处理一次写请求的顺序大致是先看共享定义里valid users、read only、write list这些参数放不放行放行之后再以某个 Linux 身份去操作文件这时候就看目标目录的属主、属组和 mode 位了。关键就在于“以哪个身份去操作”。默认情况下Samba 是以登录用户的身份去读写文件的。也就是说 user1 连上来写文件时文件属主就是 user1。如果你希望所有用户写进去的文件都归某个组、并且组内可读写就得用force group和create mask来兜底。下面这张表把几个核心参数的作用理清楚参数作用位置典型值说明valid users共享级smbusers只有这个组的人能连这个共享write list共享级smbusers组内可写配合read only yes用read only共享级yes默认只读靠 write list 开口子create mask文件系统0660新建文件的权限位directory mask文件系统0770新建目录的权限位force group文件系统smbusers新建文件强制属这个组force user文件系统一般不设设了之后所有操作都以该用户身份执行force user要特别小心。设成某个用户后所有客户端写进来的文件属主都变成那个人用户之间的隔离就没了。只有在做“公共上传目录”且不需要区分属主时才用。多用户隔离场景下我一般只设force group不碰force user。2.3 目录结构怎么规划才不打架多用户共享最稳的结构是“一个公共父目录 每人一个子目录 一个公共交换区”。父目录本身不给写权限只给进入权限子目录属主是各人组是共享组mode 设 770公共交换区用 SGID 保证新建文件继承组。# 共享根目录属主 root组 smbusers权限 2770 # 2 是 SGID保证子目录和文件继承 smbusers 组 sudo mkdir -p /srv/samba/shared sudo chown root:smbusers /srv/samba/shared sudo chmod 2770 /srv/samba/shared # 每人一个子目录 sudo mkdir -p /srv/samba/shared/user1 /srv/samba/shared/user2 sudo chown user1:smbusers /srv/samba/shared/user1 sudo chown user2:smbusers /srv/samba/shared/user2 sudo chmod 2770 /srv/samba/shared/user1 /srv/samba/shared/user2 # 公共交换区所有人可写SGID 保证组继承 sudo mkdir -p /srv/samba/shared/public sudo chown root:smbusers /srv/samba/shared/public sudo chmod 2770 /srv/samba/shared/public注意父目录/srv/samba/shared的 mode 是 2770user1 和 user2 都能进入但能不能进对方的子目录取决于子目录的 mode。子目录是 2770 且属主是各自那么 user1 进不了 user2 的目录other 位是 0这就是隔离生效的地方。SGID 位那个 2保证在目录里新建的文件和子目录自动继承smbusers组省得后面手动chgrp。3. 把 smb.conf 写对从全局段到共享段的完整配置与参数解释3.1 全局段里必须确认的几项全局段决定了 Samba 的整体行为多用户场景下重点看认证后端、日志和协议版本。下面是一份可以直接抄的全局段逐项说明。[global] workgroup WORKGROUP server string Samba File Server %v netbios name FILESRV security user passdb backend tdbsam map to guest Bad User guest ok no obey pam restrictions yes unix password sync no log file /var/log/samba/log.%m max log size 5000 log level 1 server min protocol SMB2 server max protocol SMB3 idmap config * : backend tdb idmap config * : range 3000-7999security user表示用 Samba 自己的用户库认证这是多用户场景的标准选择。passdb backend tdbsam是默认的本地密码库smbpasswd写的就是它。map to guest Bad User的意思是如果用户名不存在就当访客处理而不是直接拒绝。配合guest ok no访客也进不来等于把无效用户挡在门外。server min protocol SMB2是必须的SMB1 早就该淘汰了很多新版本 Samba 默认已经禁用显式写上避免客户端协商到老协议。log level 1是日常够用的级别排错时可以临时调到 3 或 5但别长期开着日志会涨得很快。3.2 共享段valid users、write list 与 force group 的组合共享段是权限控制的主战场。下面这个共享定义实现了“组内用户可读写但各自只能动自己的子目录”的效果。[shared] comment Multi-user shared folder path /srv/samba/shared browseable yes read only yes valid users smbusers write list smbusers create mask 0660 directory mask 2770 force group smbusers inherit permissions yes inherit acls yes veto files /.bash*/ delete veto files noread only yes加write list smbusers是一个常用组合默认只读只有白名单组可写。这样即使有人误加了别的组进来也不会默认拿到写权限。create mask 0660保证新建文件属主和组可读写其他人没权限。directory mask 2770里的 2 是 SGID保证新建子目录继承组。force group smbusers是兜底防止某些客户端操作导致组不对。inherit permissions yes让子目录继承父目录的权限位减少手动 chmod 的次数。veto files用来屏蔽隐藏文件delete veto files no防止误删。注意directory mask写成 2770 时前面的 2 是 SGID 位不是权限位的一部分。有些老版本 Samba 对四位 mask 的解析不一致如果发现 SGID 没生效改成directory mask 0770再配合父目录的 SGID 也能达到类似效果。3.3 用 include 拆分多共享配置当共享数量多起来全塞在一个smb.conf里会很难维护。常见做法是把每个共享拆成独立文件用include引进来。# 在 smb.conf 末尾加一行 include /etc/samba/conf.d/%U.conf%U是登录用户名这样每个用户可以有自己的共享定义文件。比如/etc/samba/conf.d/user1.conf里只写 user1 专属的共享。这个做法的好处是权限边界清晰改一个人的配置不影响别人。缺点是文件多了之后要记得统一备份别漏了conf.d目录。# 建目录并放一个示例 sudo mkdir -p /etc/samba/conf.d sudo tee /etc/samba/conf.d/user1.conf /dev/null EOF [user1_private] path /srv/samba/shared/user1 valid users user1 read only no browseable no create mask 0600 directory mask 0700 EOFbrowseable no让这个共享在网络邻居里不显示但知道路径的人可以直接访问。create mask 0600和directory mask 0700是私有目录的典型配置只有属主能读写组和其他人全无权限。4. 验证与排错从 testparm 到 smbclient 的完整检查链4.1 改完配置先跑 testparmtestparm是 Samba 自带的配置语法检查工具改完smb.conf第一件事就是跑它。它会告诉你哪些参数写错了、哪些段有问题还会把最终生效的配置打印出来。# 检查语法-s 静默模式只报错 sudo testparm -s # 想看某个共享的最终生效参数可以这样过滤 sudo testparm -s 2/dev/null | sed -n /\[shared\]/,/^$/p如果testparm报Unknown parameter说明参数名拼错了或者当前版本不支持。报WARNING: The xxx option is deprecated的虽然还能用但建议换成新参数名免得下次升级直接失效。4.2 用 smbclient 在本地验证认证和读写不用等 Windows 客户端在服务器本机就能用smbclient验证。这是排错最快的手段能区分是认证问题还是权限问题。# 列出共享-U 指定用户-L 列出目标主机的共享 smbclient -L localhost -U user1 # 连上共享进交互模式 smbclient //localhost/shared -U user1 # 进交互模式后可以执行这些命令 # smb: \ ls 查看目录 # smb: \ mkdir test 建目录 # smb: \ put /etc/hostname test.txt 上传文件 # smb: \ rm test.txt 删除文件如果smbclient -L能列出共享但连不上多半是valid users没放行。如果能连上但写不进去看write list和文件系统权限。如果写进去的文件属主或组不对检查force group和 SGID 位。这套流程走一遍大部分问题都能定位到具体哪一层。4.3 看日志定位认证失败Samba 的日志按客户端 IP 或主机名分开默认在/var/log/samba/下。认证失败、权限拒绝这些都会记进去。# 实时看日志按客户端主机名过滤 sudo tail -f /var/log/samba/log.client_hostname # 如果不知道主机名直接看最新的日志文件 sudo ls -lt /var/log/samba/ | head -5 sudo tail -50 /var/log/samba/log.$(sudo ls -t /var/log/samba/ | head -1)日志里常见的错误码NT_STATUS_LOGON_FAILURE是密码或用户名不对NT_STATUS_ACCESS_DENIED是权限不够NT_STATUS_BAD_NETWORK_NAME是共享名写错或共享没定义。把log level临时调到 3能看到更详细的认证过程包括用了哪个后端、匹配到哪个用户。4.4 权限继承的验证方法SGID 和inherit permissions是否生效不能靠猜得实际建文件看结果。# 以 user1 身份通过 smbclient 建一个目录和文件 smbclient //localhost/shared -U user1 -c mkdir user1/testdir; put /etc/hostname user1/testdir/test.txt # 在服务器上看实际权限 ls -ld /srv/samba/shared/user1/testdir ls -l /srv/samba/shared/user1/testdir/test.txt期望结果是testdir的组是smbusersmode 是drwxrws---那个 s 就是 SGID 生效的标志test.txt的组也是smbusersmode 是-rw-rw----。如果组不对检查force group和父目录的 SGID如果 mode 不对检查create mask和directory mask。5. 多用户权限的避坑清单五条血泪经验5.1 现象用户能登录但看不到任何共享原因browseable no或者valid users里没包含该用户也可能是map to guest把有效用户误判成了访客。解决先用smbclient -L localhost -U 用户名确认能看到哪些共享。如果列表为空检查全局段的map to guest设置确认security user且passdb backend指向正确的库。再用pdbedit -L列出 Samba 用户库确认用户确实在里面。# 列出 Samba 用户库里的所有用户 sudo pdbedit -L -v # 查看某个用户的详细信息 sudo pdbedit -L -v -u user15.2 现象能读不能写或者写进去的文件别人改不了原因read only yes但write list没配对或者create mask太严导致组内其他人没写权限。解决确认write list里的组名和valid users一致。检查create mask是不是 0640 这种组内只读的值多用户协作场景应该用 0660。如果文件已经存在且权限不对用chmod -R gw批量补组写权限但要注意这不会改变已有文件的属主。5.3 现象新建文件的组不对导致同组用户访问不了原因父目录没有 SGID 位或者force group没设Samba 用了用户的主组而不是共享组。解决给共享根目录和所有子目录加 SGIDchmod gs并在共享段设force group 共享组名。两个一起用最稳。验证方法是建个新文件看组别靠猜。# 批量给目录加 SGID sudo find /srv/samba/shared -type d -exec chmod gs {} \; # 批量修正已有文件的组 sudo chgrp -R smbusers /srv/samba/shared5.4 现象Windows 客户端提示“多重连接到一个服务器或共享资源”错误原因Windows 不允许同一客户端用不同凭据同时连同一台服务器的多个共享。用户先用自己的账号连了一个共享又想用另一个账号连另一个共享就会报这个错。解决让用户先断开所有到该服务器的连接net use * /delete再用正确凭据重新连。或者在服务器端用不同的 netbios name 或 IP 来区分但这属于绕路。根本办法是规划好共享结构让一个用户一次只用一套凭据。5.5 现象改了 smb.conf 重启服务后配置没生效原因systemctl restart smbd在某些发行版上不会重读配置或者 nmbd 没一起重启导致浏览列表没更新。解决用smbcontrol smbd reload-config让 smbd 重读配置不用完全重启。如果改了共享定义最好systemctl restart smbd nmbd两个都重启。改完一定跑testparm确认语法再看systemctl status smbd确认服务真的起来了。# 不中断连接重载配置 sudo smbcontrol smbd reload-config # 完全重启改了共享段或全局段后建议这样做 sudo systemctl restart smbd nmbd # 确认服务状态 sudo systemctl status smbd --no-pager6. 进阶技巧用 ACL 做更细的权限控制与一键验证脚本基础权限位只有属主、属组、其他人三档遇到“user1 的目录要让 user2 只读、user3 完全不能看”这种需求就不够用了。这时候得上 POSIX ACL。Samba 支持 ACL 透传前提是文件系统挂载时带了acl选项并且smb.conf里设了inherit acls yes。先确认文件系统支持 ACL# 查看挂载选项确认有 acl mount | grep -E /srv| /$ # 如果没有 acl在 /etc/fstab 里对应行加上 acl 选项再重新挂载 # 临时生效可以用 mount -o remount,acl /srv然后给 user2 单独开一个只读 ACL# 给 user2 在 user1 的目录上设只读 ACL sudo setfacl -R -m u:user2:rx /srv/samba/shared/user1 sudo setfacl -R -d -m u:user2:rx /srv/samba/shared/user1 # 查看 ACL getfacl /srv/samba/shared/user1-m是修改现有 ACL-d是设默认 ACL让新建的文件和目录自动继承。u:user2:rx表示给 user2 读和执行权限目录需要 x 才能进入。这样 user2 能进 user1 的目录、能读文件但不能写、不能删。比改属组灵活得多而且不影响其他用户。配合inherit acls yesSamba 在创建新文件时会保留父目录的默认 ACL不用每次手动设。但要注意ACL 和传统 mode 位会互相影响设了 ACL 之后ls -l看到的组权限位可能显示为实际权限要看getfacl。最后给一个一键验证脚本改完配置跑一遍把认证、读写、权限继承都过一遍#!/bin/bash # samba_check.sh - 多用户共享权限快速验证 SHARE//localhost/shared USERS(user1 user2) PASS临时密码 for u in ${USERS[]}; do echo 测试用户: $u # 测试认证和列目录 smbclient $SHARE -U $u%$PASS -c ls 21 | head -5 # 测试建目录 smbclient $SHARE -U $u%$PASS -c mkdir ${u}_testdir 21 # 测试上传 smbclient $SHARE -U $u%$PASS -c put /etc/hostname ${u}_testdir/test.txt 21 # 测试删除应该成功因为是自己的目录 smbclient $SHARE -U $u%$PASS -c rm ${u}_testdir/test.txt 21 echo done echo 文件系统权限检查 for u in ${USERS[]}; do ls -ld /srv/samba/shared/${u}_testdir 2/dev/null done这个脚本把每个用户的认证、建目录、上传、删除都跑一遍最后看文件系统上的实际权限。密码写在脚本里只是测试用生产环境别这么干用credentials文件或者交互输入。我一般改完smb.conf和目录权限后都会把这个脚本跑一遍确认每个用户的边界都符合预期再交给同事用。从那以后我每次动 Samba 配置都强制走一遍testparm加这个验证脚本省得后面被“权限串门”的事故找上门。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。