本文要点
- Samba 是 SMB/CIFS 协议的开源实现,专治「Linux 服务器 + Windows/macOS 客户端」混编环境;与面向 Linux 之间的
NFS互补(NFS 已另文实测,本文实测对象是 Samba) - 一条命令装齐三件套:
apt-get install -y samba smbclient cifs-utils——服务端smbd、命令行客户端smbclient、内核挂载工具mount.cifs(实测 Ubuntu 24.04.4 上是 Samba 4.19.5、cifs-utils 2.7.0) - SMB 账号是独立体系:
useradd只建系统账号,smbpasswd -a单独设置 SMB 密码;给共享账号配/usr/sbin/nologin登录 shell 可防止其 SSH 登录服务器 - 一个共享 = 服务层 + 文件系统层双重权限:
read only/valid users/guest ok只决定 Samba 放不放行,目录的 Linux 属主权限不放开,写入照样报Permission denied(本文实测踩中:共享目录属主是 root,SMB 用户写入被拒,chown给共享用户后立即成功) - 匿名访客默认映射
map to guest = Bad User:guest 只读共享用smbclient //主机/共享 -N一条命令即可验证,写入会被服务端以NT_STATUS_ACCESS_DENIED拒绝 - Linux 客户端挂载用
mount -t cifs //127.0.0.1/docs /mnt/smb -o username=...,password=...,vers=3.0;vers显式指定协议版本是因为 SMB1 因安全原因默认关闭,务必用 SMB3+;服务器侧真实属主与客户端看到的不一致是 uid 映射所致,属正常现象 - 全部命令在 Ubuntu 24.04.4 云服务器(Samba 4.19.5)上真实执行,截图即真实输出;演示账号、共享目录与挂载点在演示结束后已清理
Samba 文件共享:从 smb.conf 配置到 SMB 客户端挂载
前一篇《NFS 网络文件共享》解决的场景是 Linux 与 Linux 之间共享目录。但真实办公室里往往是一台 Linux 服务器 + 一堆 Windows / macOS 桌面——要让它们像访问网上邻居一样读写服务器目录,标准答案是 Samba:SMB/CIFS 协议的开源实现,Linux 上服务端的事实标准,Windows 甚至自带同名内核客户端,零额外软件就能直连。
本文在一台 Ubuntu 24.04.4 云服务器(2 vCPU / 1.8G 内存,内核 6.8.0-136-generic)上完整走一遍 Samba 日常主线:安装 → 建共享目录与 SMB 账号 → 编写 smb.conf → 匿名只读与账号读写双向验证 → Linux 内核挂载并真实踩一次权限坑。全部命令实测执行,截图即真实输出。
安装:服务端与客户端工具一次装齐
Ubuntu 官方源里把三件套打成了一个安装命令:服务端 smbd、命令行客户端 smbclient、内核挂载工具 cifs-utils。以下命令需要 root 权限(本文演示环境以 root 操作,普通用户自行加 sudo):
apt-get install -y samba smbclient cifs-utils
输出很长,上图截取了「配置阶段」的结尾部分。三条关键信息值得注意:
- 装上的实际版本是 Samba 4.19.5(
2:4.19.5+dfsg-4ubuntu9.7)与 cifs-utils 2.7.0; - 安装过程自动创建了 systemd 符号链接:
smbd.service、nmbd.service都被链接到multi-user.target.wants——也就是说 Samba 安装完即注册为开机自启服务; - Ubuntu 的 samba 包默认把服务拆成
smbd(文件共享)与nmbd(NetBIOS 名称服务)。现代 SMB 客户端已不依赖 NetBIOS,本文只关心smbd,需要时单独操作它即可。
确认版本:
smbd --versionVersion 4.19.5-Ubuntu准备共享目录与 SMB 账号
先建一个共享目录并放入两个演示文件——模拟「团队文档」场景:
mkdir -p /srv/share/docsprintf '季度销售报表 v1.2\n' > /srv/share/docs/sales-2026-q3.md && printf '产品路线图讨论纪要\n' > /srv/share/docs/roadmap-notes.mdls -l /srv/share/docstotal 8
-rw-r--r-- 1 root root 28 Sep 7 05:07 roadmap-notes.md
-rw-r--r-- 1 root root 24 Sep 7 05:07 sales-2026-q3.md接下来创建 SMB 账号。这里要强调一个新手最容易绕晕的点:SMB 密码与系统登录密码是两套独立体系。useradd 只是让系统里存在这个用户(Samba 要求账号先存在于系统),smbpasswd -a 才设置 Samba 自己的密码。给共享账号配上 /usr/sbin/nologin 登录 shell,还能顺手杜绝它 SSH 登录服务器:
useradd -M -s /usr/sbin/nologin smbusersmbpasswd -a smbuser -sAdded user smbuser.-s 表示从标准输入读取密码(可脚本化);交互执行时去掉它即可,会提示输入两次。演示环境用的密码是 Demo#Smb2026——仅限演示,真实环境请用强密码并定期轮换。
编写 smb.conf:只读公共 + 账号读写两个共享
Ubuntu 自带的 /etc/samba/smb.conf 是完整模板,先备份再往末尾追加我们的共享定义,是最稳妥的改法:
cp /etc/samba/smb.conf /etc/samba/smb.conf.bakcat >> /etc/samba/smb.conf <<'SMBCONF'
[docs]
comment = 团队共享目录
path = /srv/share/docs
browseable = yes
read only = no
valid users = smbuser
create mask = 0644
directory mask = 0755
[public]
comment = 只读公共目录
path = /srv/share/docs
browseable = yes
read only = yes
guest ok = yes
SMBCONF这里刻意写了两个共享指向同一目录,用来对比 Samba 的三种访问控制手段:
[docs]:账号读写共享。read only = no放行写入,但valid users = smbuser把访问者限定为指定账号,其余人连登录都过不了;[public]:访客只读共享。guest ok = yes允许匿名访问,read only = yes禁止写入;create mask/directory mask:新文件/新目录在服务器端落地时的权限掩码,对服务层放行之外做第二道约束(下文会看到真正的第二道约束其实是文件系统权限)。
配置写完后先用 testparm 校验语法。它会重新加载配置并输出解析结果,是排查共享问题的第一步:
testparm -s
注意几个输出细节:
- 全局段里
map to guest = Bad User——Ubuntu 默认值,含义是「用户名对不上时映射为匿名访客」,这正是guest ok能工作的前提; [docs]解析出read only = No、valid users = smbuser,[public]解析出guest ok = Yes,与我们写的一致;- 结尾的
Load smb config files ...+Loaded services file OK.就是「配置无错」的官方宣告。
校验通过后重启服务让配置生效,并顺手确认状态:
systemctl restart smbd && systemctl is-active smbdactive验证一:匿名访客只能读
先用 smbclient 扮演「匿名访客」访问 [public]。-N 表示不发账号密码,直接以 guest 身份尝试:
smbclient //127.0.0.1/public -N -c 'ls' . D 0 Mon Sep 7 05:07:12 2026
.. D 0 Mon Sep 7 05:07:12 2026
roadmap-notes.md N 28 Mon Sep 7 05:07:12 2026
sales-2026-q3.md N 24 Mon Sep 7 05:07:12 2026
40972748 blocks of size 1024. 18731608 blocks available目录列表拿到了,两个文件都可见。那 guest 能写吗?试试往共享里传一个文件(put 的语法是 put 本地文件 远端文件名):
smbclient //127.0.0.1/public -N -c 'put /etc/hostname hostname.txt'NT_STATUS_ACCESS_DENIED opening remote file \hostname.txtNT_STATUS_ACCESS_DENIED——被服务端明确拒绝。read only = yes 在 Samba 层就把写操作拦死了,这正是「公共只读」该有的行为。
验证二:账号挂载与写入(一次真实的权限坑)
客服用 smbclient 适合临时操作;要像本地目录一样持续使用,得用 Linux 内核自带的 CIFS 客户端挂载。先建挂载点,再用 smbuser 的凭据挂载 [docs]:
mkdir -p /mnt/smbmount -t cifs //127.0.0.1/docs /mnt/smb -o 'username=smbuser,password=Demo#Smb2026,vers=3.0'几点说明:
vers=3.0显式要求 SMB 3.0 协议。SMB1(vers=1.0)因勒索软件风波被现代 Samba 默认禁用,老教程里不带vers的写法在 4.19 上会协商失败;显式声明也能避免将来静默降级到弱协议;- 演示环境用
127.0.0.1回环地址,因此不需要开防火墙;真实跨机器访问时,除本机防火墙外,还要记得在云厂商安全组放行 TCP 445(本文的服务器由安全组隔离,445 未对公网开放); - 凭据明文出现在命令行里只适合演示与脚本初排,生产建议改用
credentials文件或 Kerberos。
挂载本身没有输出——成功就是静默的。往里写个文件试试:
echo '由 CIFS 客户端写入的行' > /mnt/smb/from-cifs.txtbash: line 1: /mnt/smb/from-cifs.txt: Permission denied写入被拒了!read only = no、valid users = smbuser 都配对了,为什么还报 Permission denied?回头看第一步的 ls -l:目录属主是 root,权限 drwxr-xr-x——root 之外的用户对这个目录只有读和执行的份。Samba 的 read only 只是服务层的放行开关,最终能否写入还要过文件系统层:SMB 会话里的 smbuser,映射到服务器上就是 smbuser 这个系统用户,它对 root 拥有的目录没有写权限。
修复方法就是把目录及其内容交给共享用户:
chown -R smbuser:smbuser /srv/share/docs再执行刚才失败的写入,这次换成「写入 + 读回」一条链,一次验证读写两个方向:
echo '由 CIFS 客户端写入的行' > /mnt/smb/from-cifs.txt && cat /mnt/smb/from-cifs.txt
写入成功且内容读回一致。到服务器侧看真实属主,文件已经归 smbuser 所有:
ls -l /srv/share/docstotal 12
-rw-r--r-- 1 smbuser smbuser 31 Sep 7 05:07 from-cifs.txt
-rw-r--r-- 1 smbuser smbuser 28 Sep 7 05:07 roadmap-notes.md
-rw-r--r-- 1 smbuser smbuser 24 Sep 7 05:07 sales-2026-q3.md而从挂载点看,同样的文件显示属主却是 root、权限 rwxr-xr-x:
ls -l /mnt/smbtotal 9
-rwxr-xr-x 1 root root 31 Sep 7 05:07 from-cifs.txt
-rwxr-xr-x 1 root root 28 Sep 7 05:07 roadmap-notes.md
-rwxr-xr-x 1 root root 24 Sep 7 05:07 sales-2026-q3.md两边不一致不是错误,而是 CIFS 客户端的 uid/gid 映射行为:挂载时没指定 uid/gid,客户端就把远程文件都映射成本地挂载者(root);file_mode/dir_mode 未指定时默认按 0755 呈现。想让客户端侧也显示真实属主,挂载时加上 uid=1001,gid=1001(视 smbuser 在客户机上的 uid 而定)即可。排查共享权限问题时务必记住:服务器侧 ls 才是权威。
Windows 与 macOS 客户端怎么连
同一套服务端,桌面端几乎零配置:
- Windows:资源管理器地址栏直接输入
\\服务器IP\docs,弹窗时填smbuser和 SMB 密码;或命令行net use Z: \\服务器IP\docs /user:smbuser映射成盘符(会提示输入密码)。Windows 自带 SMB 客户端,无需安装任何东西; - macOS:访达 →「前往」→「连接服务器」,输入
smb://服务器IP/docs,同样用smbuser登录即可挂载成卷。
桌面端能读不能写时,优先检查的仍是本文踩过的那条链:共享层 read only → valid users/guest ok → 文件系统属主权限。
小结
回顾整条链路,Samba 的日常运维其实就三件事:装对包、写对配置、记住双重权限。配置语法用 testparm 兜底,服务状态用 systemctl 确认,行为验证用 smbclient(guest 只读场景)或 mount -t cifs(账号读写场景)分别打一遍,基本不会有大问题。需要把 CIFS 挂载固化成开机自动挂载时,可参考《Linux 磁盘挂载》的 fstab 写法,并把密码挪进权限 600 的 credentials 文件。本文演示用的账号、共享目录与挂载点,在验证结束后已全部清理,服务器保持干净状态。
评论 (0)
暂无评论,快来抢沙发吧!