拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Ubuntu下Samba文件共享配置全攻略:从原理到排错

Ubuntu下Samba文件共享配置全攻略:从原理到排错

搞过Linux间文件共享的朋友应该都有体会,明明最常用的需求,反而最容易在细节上翻车。两台Ubuntu之间通过Samba共享文件夹,听起来就是装个包、改个配置、重启服务的事,但真操作起来,权限对不上、挂载失败、中文乱码、速度上不去……各种问题能折腾一晚上。这篇文章把我实际配置过程中的完整思路、操作步骤和踩过的坑都整理出来,从原理到命令、从参数到排错,一次说清楚。不管你是刚接触Linux的新手,还是已经配过几次但总有小毛病的老手,这篇应该都能帮你少走弯路。

1. 项目整体设计与思路拆解

1.1 为什么是Samba而不是其他方案

两台Ubuntu之间传文件,方案其实不少。scp、rsync、NFS、FTP、Samba都能干这事,但每个方案的适用场景差别很大。

scp和rsync适合一次性传输或定时同步,不是"共享"的形态。你不可能让另一台机器像访问本地目录一样随时读写远程文件。NFS(Network File System)在Linux之间确实高效,但配置起来对新手不太友好,而且客户端挂载时需要额外装nfs-common,跨发行版偶尔有兼容问题。FTP更不用说了,明文传输、权限模型和Linux系统权限脱节,现在基本只在特定场景用。

Samba的核心优势在于它实现的是SMB/CIFS协议,这是Windows网络共享的标准协议,Linux、macOS、路由器、NAS、电视盒子全都支持。虽然这里是两台Ubuntu之间共享,但配好之后,将来如果局域网里加了一台Windows电脑或者手机,只要权限开好,一样能访问这台Samba服务器。一次配置,全家通用,这是NFS做不到的灵活性。

另一个关键点是权限模型。Samba的权限和Linux系统权限是两套体系,但又互相映射。Samba建立在Linux用户体系之上,通过smbpasswd设置独立的Samba密码,再配合配置文件里的权限规则,可以做到"这个用户只能读、那个用户能写、匿名用户干脆拒绝",权限粒度比FTP细腻得多,比NFS的root_squash逻辑也更好理解。

1.2 组网结构与共享模型设计

开始动手之前,先理清网络拓扑。我在实践中的标准配置是两台Ubuntu处于同一个局域网,一台做服务端(Server),一台做客户端(Client)。服务端IP假设是192.168.1.100,客户端IP假设是192.168.1.101。用静态IP最好,因为后面客户端挂载需要写服务端地址,DHCP分配的IP变了就要重新配置。

实际项目里,这个架构还可以扩展出几种常见场景:一台服务端对多台客户端、双机互为服务端、服务端带RAID磁盘阵列做家庭NAS等等。但不管怎么变,核心配置逻辑都一样:服务端负责共享目录和账号权限,客户端负责挂载访问。

在设计共享模型时,最重要的问题是:共享给谁、允许做什么操作。我习惯在设计阶段就把用户分三类:

  • 管理员用户:能读写共享目录里的所有内容,负责日常维护、增删文件。
  • 普通用户:只能读写自己被授权的子目录,不能越权访问别人的目录。
  • 只读用户:只能查看和执行,不能写入。

这个设计思路直接影响配置文件的写法。很多教程只写一个最简单的共享段落,人人都能访问,那不是共享,是裸奔。正确做法是在smb.conf里对每个共享目录单独定义允许的用户列表,用valid users、write list等参数把权限管起来。

1.3 Samba工作原理:为什么配置起来这么"绕"

Samba这套配置之所以让新手困惑,核心在于它有两层认证、两层路径。先理解原理,后面配置就不难了。

Samba的通信过程可以简化成三步:客户端发起连接请求,Samba服务端通过smbd进程响应,要求客户端提供账号密码;smbd收到凭证后,先交给系统验证账号是否存在,再交给Samba的TDB数据库验证Samba密码是否正确;验证通过后,smbd以该Linux用户的身份操作共享目录,最后的读写权限仍然受Linux文件系统权限约束。

用生活化的例子理解:Samba服务器相当于一个小区物业,共享目录就是小区里的公共仓库。Linux系统用户列表是"小区业主名册",Samba密码是"仓库钥匙"。你拿着钥匙进了仓库,能搬走多少东西(读写权限),还要看仓库门口的保安(Linux文件权限)让不让你动。

这就解释了一个最常见的坑:为什么Samba账号加好了、smbpasswd也设置了,可还是权限不足。因为Samba以Linux用户身份工作,如果该用户对共享目录没有Linux层面的写权限,Samba配置里写得再好也没用。两层权限必须同时通过。

2. 环境准备与Samba服务端配置

2.1 系统环境与软件安装

先交代一下我的实验环境:服务端和客户端都是Ubuntu 22.04 LTS,内核版本5.15,Samba版本4.15.x。这个版本组合很稳,网上遇到的绝大多数问题都能对应上。

安装Samba只需要一条命令:

sudo apt update sudo apt install -y samba

安装完成后,先别急着改配置。用下面的命令确认服务状态:

systemctl status smbd --no-pager -l sudo systemctl enable smbd --now

这里有个细节:很多人只盯着smbd(文件共享服务),但Samba套件里还有个nmbd(NetBIOS名称服务)。如果只做IP访问,nmbd可以不管;但如果希望客户端能用主机名直接访问(比如\samba-server\share),nmbd就得开着。Ubuntu里nmbd的systemd服务名是nmbd或smbd,取决于版本。22.04上直接两个都enable最省心:

sudo systemctl enable smbd nmbd --now

提示:Ubuntu自带的ufw防火墙默认可能阻挡Samba端口。如果你启用了ufw,别忘了放行。这个放到后面安全加固部分专门说。

2.2 创建共享目录与系统用户

安装完软件,接下来是准备共享的目录和授权用户。先说目录。我建了一个专门的共享根目录,下面按用途分子目录,这样权限规划更清晰:

sudo mkdir -p /srv/samba/share sudo mkdir -p /srv/samba/backup sudo mkdir -p /srv/samba/project

为什么放在/srv/samba而不是直接放/home?两个原因。第一,/srv专门用来放服务数据,语义清晰;第二,直接把/home共享出去非常危险,容易把整个用户目录暴露给局域网。隔离是第一原则。

目录建好之后,创建系统用户。这一步容易搞混:Samba用户必须首先是系统用户,但不需要登录Shell。用如下命令创建:

sudo useradd -M -s /usr/sbin/nologin smbuser

参数解释:-M表示不创建home目录,-s指定无法登录Shell,因为Samba用户只需要通过SMB协议访问共享,不需要也不能SSH登录系统。这是安全基线,能减少账户被滥用的面。

如果需要多个用户,重复执行即可。然后设置Samba密码:

sudo smbpasswd -a smbuser

smbpasswd会提示输入两次密码,这个密码可以跟系统密码不一样,是Samba独立的凭据。

设置好之后,把共享目录的所有权交给这个用户,并设置合适的Linux权限:

sudo chown -R smbuser:smbuser /srv/samba sudo chmod -R 770 /srv/samba

权限770表示用户和同组用户可读写执行,其他用户完全无权限。这是较为安全的起始配置,后续可以在配置里细调。

2.3 修改smb.conf核心配置

Samba的主配置文件是/etc/samba/smb.conf。改之前一定先备份:

sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

然后用编辑器打开,在文件末尾追加自定义共享段落。先看我最常用的一组基础配置:

[global] workgroup = WORKGROUP server string = Ubuntu Samba Server security = user map to guest = never log file = /var/log/samba/log.%m max log size = 1000 server role = standalone server disable netbios = no socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072 read raw = yes write raw = yes use sendfile = yes min receivefile size = 16384 strict locking = no unix extensions = off allow insecure wide links = yes wide links = yes follow symlinks = yes [share] comment = Public Shared Folder path = /srv/samba/share browseable = yes read only = no valid users = smbuser write list = smbuser create mask = 0664 directory mask = 0775 force user = smbuser force group = smbuser

这段配置里的每一个全局参数我都是踩过坑之后才确定的,后面性能调优部分会详细讲。现在先把共享段落的重点说明一下。

  • path:共享目录的绝对路径,必须跟实际创建的目录一致。
  • read only = no:允许写入。如果只想让用户只读,改成yes。
  • valid users:允许访问的用户列表。这个一旦设置,匿名用户直接拒绝,推荐始终设置。
  • write list:在read only的基础上,明确列出能写入的用户。这里两层都写了smbuser,逻辑更清晰。
  • create mask / directory mask:新文件/新目录在共享中创建时的权限位。0664和0775是实践中最常用的组合,既能保证同组协作,又不给其他用户写权限。
  • force user / force group:强制所有Samba操作以smbuser身份执行。这解决了一个经典问题:不同Samba用户写入的文件归属混乱,导致互相覆盖不了。全部统一到smbuser名下,省心很多。

2.4 配置校验与重启生效

改完配置不要直接重启服务,先自检。Samba自带一个非常有用的检查工具testparm,它会校验语法并显示最终生效的配置:

testparm -s /etc/samba/smb.conf

看到Load smb config files from /etc/samba/smb.conf和Loaded services file OK就说明语法没问题。我遇到过一次因为缩进用了Tab导致解析错误,testparm直接报错,省得重启服务后才发现问题。

自检通过后,重启smbd和nmbd让配置生效:

sudo systemctl restart smbd nmbd

重启后可以用smbstatus检查服务是否正常监听:

sudo smbstatus

如果看到Samba version和Server Uptime信息,说明服务端已经就绪。这个命令非常有用,后面排查连接状态也要靠它。

3. 服务端进阶配置:多用户权限与安全加固

3.1 多用户共享:不同用户不同权限的写法

前面基础配置里只有一个用户。真实场景往往需要多个人用,权限还得有区分。我常用的做法是加一个[backup]共享段,只允许特定用户访问,或者根据不同用户开放不同目录:

[backup] comment = Backup Directory path = /srv/samba/backup browseable = no read only = no valid users = smbuser, adminuser write list = adminuser create mask = 0660 directory mask = 0770

这段配置里有两个实用技巧。第一是browseable = no,表示共享目录对全网隐藏。知道共享名的人可以直接用//192.168.1.100/backup访问,但浏览列表里看不到它——隐蔽不等于安全,但少暴露一个入口总归是好的。第二是write list = adminuser,意思是adminuser可以写,smbuser只能读。这就在同一个共享里实现了"一个只读一个读写"的差异权限。

如果想让不同用户拥有各自独立的私有目录,那更简单:每个用户建一个目录,在share段里用%U变量:

[home] comment = Home Directories path = /srv/samba/home/%U valid users = %S read only = no browseable = no

%U会自动替换成客户端连接时使用的用户名,%S会自动替换成共享名(这里就是home)。也就是说smbuser连上来会自动映射到/srv/samba/home/smbuser,adminuser连上来映射到/srv/samba/home/adminuser。自动隔离,互不干扰。

3.2 网络安全加固:防火墙、hosts allow与端口收敛

Samba服务一旦暴露到网络里,就相当于开放了一批端口。默认情况下Samba使用以下端口:

  • 137/UDP和138/UDP:NetBIOS名称服务,nmbd用。
  • 139/TCP:NetBIOS会话服务(SMB over NetBIOS)。
  • 445/TCP:SMB协议直接端口,现代客户端主要走它。

如果只做Ubuntu到Ubuntu的共享,理论上只需要445/TCP就够了。但考虑到兼容性,以及Windows下老版本的SMB1可能走139端口,我还是建议把139也开着。配置防火墙时有几个选择。

如果你用的是ufw,Ubuntu自带一个配置文件可以快速放行Samba:

sudo ufw allow samba

这个规则会同时放行上面提到的四个端口。但更推荐的做法是只针对局域网网段限制:

sudo ufw allow from 192.168.1.0/24 to any port 139,445 proto tcp sudo ufw allow from 192.168.1.0/24 to any port 137,138 proto udp

这样就只有192.168.1.0/24这个网段的机器能访问Samba,外网直接拒之门外。

除了防火墙,Samba本身就支持hosts allow参数来做IP白名单,效果比防火墙更早生效——它在Samba进行任何认证之前就把连接拒绝了:

[global] hosts allow = 192.168.1.0/255.255.255.0 127.0.0.1 hosts deny = 0.0.0.0/0

注意hosts allow写在[global]段里,作用于所有共享。如果服务端本身有多块网卡或有其他网络需求,小心不要把合法来源挡在外面。

3.3 访问控制清单速查

为了让你配置时不用来回翻文档,我把权限相关的关键参数和推荐值整理成了一张表:

参数作用推荐值
valid users能被认证访问共享的用户列表明确列出,禁止空
invalid users明确禁止访问的用户列表按需设置
read only是否只读no(需要写时)
write list可写用户列表与valid users配合
browseable共享是否在列表中可见no(隐藏敏感目录)
create mask新文件创建权限位0664
directory mask新目录创建权限位0775
force user强制操作身份专用samba用户
force group强制操作组与force user同组
hosts allow来源IP白名单限定局域网

重要提醒:valid users和write list不是同一个东西。valid users决定"谁能进来",write list决定"谁能写"。一个用户可能在valid users里但不在write list里,那就是只能看不能写。这两层必须同时考虑清楚。

4. 客户端挂载与自动化配置

4.1 命令行挂载:cifs-utils安装与mount参数解读

服务端配好了,现在轮到客户端。客户端需要安装cifs-utils,这是Linux用来挂载SMB/CIFS共享的用户空间工具包:

sudo apt update sudo apt install -y cifs-utils

挂载的基本命令是:

sudo mkdir -p /mnt/samba_share sudo mount -t cifs //192.168.1.100/share /mnt/samba_share -o username=smbuser,password=你的密码,uid=1000,gid=1000

解释一下-o参数里的关键项:

  • username/password:Samba账号密码,来自服务端smbpasswd设置的那个。
  • uid/gid:挂载后,客户端上所有文件显示的所有者和组。这里我设为1000,是Ubuntu第一个创建的用户ID。如果不设置,文件在客户端看起来是root所有,普通用户访问会尴尬。
  • iocharset=utf8:处理中文文件名。如果你或协作方会创建中文文件名,建议加上这个参数,避免乱码。
  • vers=3.0:指定SMB协议版本。现代Linux默认协商到SMB 3.0或更高,但如果遇到连接失败或性能异常,可以显式指定。Samba 4.15默认最高支持SMB 3.1.1,双向兼容性都很好。
  • noserverino:某些内核和Samba版本的组合下,如果不加这个参数可能会出现File exists的诡异错误。遇到再说,没遇到别加。

一个完整且我实测稳定的挂载命令:

sudo mount -t cifs //192.168.1.100/share /mnt/samba_share -o username=smbuser,password=你的密码,uid=1000,gid=1000,iocharset=utf8,vers=3.0,file_mode=0664,dir_mode=0775

file_mode和dir_mode是客户端视角的权限覆盖,相当于在客户端侧把刚挂载的文件强制赋予0664/0775,与服务端smb.conf里的create mask/directory mask呼应,两头都统一。

4.2 开机自动挂载:fstab配置与重连机制

命令行挂载只能管当次开机。如果客户端重启了,还得手动mount一遍,太烦。要开机自动挂载,就写进/etc/fstab。这是系统启动时自动挂载文件系统的配置文件。

用你最喜欢的编辑器打开/etc/fstab,追加一行:

//192.168.1.100/share /mnt/samba_share cifs username=smbuser,password=你的密码,uid=1000,gid=1000,iocharset=utf8,vers=3.0,_netdev,x-systemd.automount,noatime 0 0

字段解释:第一列是远程共享地址,第二列是本地挂载点,第三列是文件系统类型cifs,第四列是挂载选项(逗号分隔),第五列和第六列是dump和fsck标志,网络文件系统都填0 0。

这几个挂载选项的讲究值得单独说:

  • _netdev:告诉系统这个挂载依赖网络,必须等网络就绪后再挂载。没有这个参数,开机时网络还没起来,挂载必然失败。
  • x-systemd.automount:这是Ubuntu 22.04上最关键的参数。它启用systemd的自动挂载机制——不是开机就强行挂载,而是第一次访问这个挂载点时才执行挂载。好处是只要客户端还在运行,网络恢复后就能自动重连,不会因为开机时服务端暂时没上线而挂载失败。
  • noatime:不更新访问时间戳,减少不必要的网络I/O,对性能有好处。

写完后不能直接重启验证,而是用systemd重新加载配置并测试挂载:

sudo systemctl daemon-reload sudo mount -a

mount -a会读取fstab并尝试挂载所有未挂载的条目。如果配置有误,这时就会报错。

4.3 自动挂载失败时的排查命令

fstab挂载失败有个迷惑点:开机时可能看到"Failed to mount /mnt/samba_share"的错误,但不一定是配置错误,可能是网络没就绪或服务端没起来。排查命令和执行顺序如下:

# 1. 检查网络是否能通 ping -c 3 192.168.1.100 # 2. 检查服务端445端口是否开放 nc -zv 192.168.1.100 445 # 3. 手动挂载,看具体报错 sudo mount -t cifs //192.168.1.100/share /mnt/samba_share -o username=smbuser,password=你的密码 # 4. 查看内核消息里的具体错误 dmesg | tail -20

我在实际操作中遇到最多的情况就是某次改动后fstab里密码写错了或服务端IP变了,导致开机挂载失败。建议所有配置改动用git管理或至少留一份备份,方便对比排查。

5. 性能优化与实测调优记录

5.1 影响Samba传输速度的核心瓶颈

Samba性能受几个因素影响,很多人在共享配置好了之后觉得"能用",但没注意到文件传输速度远低于局域网应有水平。SMB协议本身有开销,但真正决定吞吐量的是这几项:网卡协商速率、单包负载大小、TCP缓冲区、SMB协议版本、磁盘I/O。

千兆局域网的理论上限是125MB/s,Samba实测能跑满80-110MB/s就算正常。如果速度在50MB/s以下,一定有问题。我从实际测试中发现,最容易被忽略的瓶颈是smb.conf里的socket options、read raw/write raw和use sendfile这三组参数。

5.2 实测参数调整与结果对比

我在同一台机器上做了三轮对比测试。硬件是Intel千兆网卡、SSD存储、Ubuntu 22.04,测试方法是拷贝一个2GB的文件(用dd生成),记录耗时。

第一轮:默认配置未优化

传输速度稳定在60-70MB/s。这个速度说慢不慢,但明显没吃满带宽。查看smb.conf默认参数,发现socket options为空,sendfile没启用。

第二轮:开启基础性能参数

在[global]段加入:

socket options = TCP_NODELAY IPTOS_LOWDELAY read raw = yes write raw = yes use sendfile = yes

测速提升到85-95MB/s。TCP_NODELAY禁用Nagle算法,让小包不被延迟合并,对交互式操作提升明显。read raw和write raw允许一次请求传输更大的数据块,减少客户端与服务端的往返次数。use sendfile让sendfile系统调用直接在内核态完成文件发送,绕过用户空间拷贝,这是性能提升的大头。

第三轮:增加缓冲区并精细调整

socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072 min receivefile size = 16384 strict locking = no

速度提升到100-110MB/s,基本吃满千兆网卡。SO_RCVBUF和SO_SNDBUF把TCP缓冲区从默认的64KB提高到128KB,在大文件传输时明显减少丢包重传。min receivefile size设置16KB以上的请求走内核接收路径。strict locking = no关闭了SMB字节范围锁的严格检查,对单用户写入场景没影响,但能减少锁相关的网络往返。

注意:strict locking = no对多用户并发编辑同一个文件的场景有风险。如果是多人同时对同一文件高频率读写,建议保持默认的yes,别为了性能牺牲一致性。

5.3 Windows客户端访问时的额外优化

虽然本文讲的是两台Ubuntu,但Samba场景八成绕不开Windows。Windows 10/11默认启用了SMB 3.1.1,跟Samba 4.15兼容性良好。如果Windows访问Samba速度慢,先检查SMB协议协商结果:

Get-SmbConnection

这个命令会显示客户端和服务端协商使用的SMB版本。如果显示3.0.2或以上,属于正常。如果显示1.0就麻烦了——现代Samba默认都禁用了SMB1,Windows客户端也需要在"启用或关闭Windows功能"里手动开启SMB 1.0/CIFS文件共享支持,但这不推荐,SMB1安全性太差,别开。

Windows下还有一个优化点:关闭客户端的"远程差分压缩"功能。在"程序和功能" -> "启用或关闭Windows功能"里找到"远程差分压缩"并取消勾选,对SMB共享的读取速度有可感知的提升。原理是RDC会在文件传输前做差分对比,在纯局域网环境反而成为负担。

6. 常见问题排查与避坑指南

6.1 连接与权限类问题速查表

我把自己实操中遇到过的Samba问题全部整理在下面这张表里,每个问题都给出了定位思路和解决方案:

错误现象根本原因解决方法
NT_STATUS_ACCESS_DENIED账号密码错、用户不在valid users里、或Linux权限不足按顺序检查smbpasswd、valid users、目录属主和权限
NT_STATUS_HOST_UNREACHABLE防火墙拦截、服务未启动、IP不可达ufw放行端口、systemctl status smbd、ping测试
NT_STATUS_CONNECTION_REFUSED服务端没监听端口或Samba没装成功ss -tlnp | grep 445确认监听状态
NT_STATUS_BAD_NETWORK_NAME共享名拼写错误或共享没定义用smbclient -L //服务器IP检查可用共享列表
write error / 只读文件系统Linux权限没放开或read only=yeschmod/chown调整目录权限,检查smb.conf
中文文件名乱码字符集不一致客户端挂载加iocharset=utf8,服务端unix charset=utf8
新文件权限太宽或太窄create mask/directory mask设置不当按需调整0664/0775,避免给other写权限
挂载时提示mount error(112)版本协商失败或网络不通显式指定vers=3.0,先ping确认网络

6.2 权限配置混乱:最典型的翻车现场

权限问题是Samba新手的第一大坑,我见过太多人反复折腾配置但就是访问不了。典型现象:Samba服务正常、账号存在、密码没错、网络通,但客户端登录时报NT_STATUS_ACCESS_DENIED。

这个问题的排查顺序很重要,很多人一上来就盯着smb.conf改,其实问题往往在Linux文件权限。我的排查路径:

# 1. 先看目录属主和权限 ls -la /srv/samba/share # 2. 看Samba用户的uid和组 id smbuser # 3. 在服务端本地测试认证 sudo smbclient //localhost/share -U smbuser

第三步最关键。smbclient是Samba自带的客户端工具,直接在服务端测最准:如果本地都登录不了,肯定不是网络问题;如果本地可以但远程不行,检查防火墙。这个工具还能用来列出共享、查看服务端认账情况,排查效率非常高。

6.3 忘记Samba密码或需要改密码

Samba密码忘了比系统密码好处理,不需要重置系统。直接重新设置:

sudo smbpasswd -a smbuser

这条命令会重设Samba密码。注意-a参数表示添加用户,已存在的用户会提示重新输入密码并更新。如果只想改密码可以去掉-a。另外,如果你之前设置了密码过期策略,用chage命令检查一下:

sudo chage -l smbuser

看到Password expires为never才是安全的。如果显示有到期时间,用sudo chage -M -1 smbuser设为永不过期。

6.4 Samba端口被防火墙拦截但ufw没开

很多人在云服务器或公司内网环境部署时,明明ufw是inactive状态,但客户端还是连不上。这时候要查的不只是ufw,还有iptables底层的规则。Ubuntu默认的ufw inactive不代表没有任何防火墙规则。更隐蔽的情况是,你在安装某些软件时,安装脚本可能往iptables里加了规则。

排查命令:

sudo iptables -L -n | grep 445 sudo iptables -L -n | grep 139

如果有规则匹配,要么放行对应端口,要么如果你对iptables不熟,最干净的做法是把ufw打开再重新配置规则(ufw本质上也是管理iptables,但规则更清晰)。如果完全不需要防火墙,可以清空iptables里的自定义规则,但生产环境不建议这么干。

6.5 挂载后文件不同步或显示异常

这个问题很隐蔽。现象是:两台Ubuntu之间共享的文件,在服务端改了,客户端过了一阵才看到变化,或者文件名显示成一堆乱码。这通常不是Samba的问题,而是SMB缓存和字符集的问题。

SMB协议本身有读缓存,客户端会缓存已打开文件的元数据。如果你经常在服务端改文件然后跑到客户端去读,可能看到的是缓存内容。解决方法是挂载时加上参数:

-o cache=none,dir_cache=none

这两个参数禁用Samba客户端的内核缓存,每次读取都直接访问服务端。代价是性能略有下降,适合文件频繁变更的场景。

字符集问题则要统一两端。在smb.conf的[global]段显式声明:

unix charset = UTF-8 dos charset = CP936

dos charset = CP936是为兼容Windows下GBK编码的中文文件名。如果纯Linux环境,其实UTF-8就够了,但加上这行能在将来出现Windows客户端时避免中文乱码。

6.6 频繁断连和"文件被占用"错误

局域网不太稳定或服务端有休眠设置时,客户端挂载的共享会断连。服务端方面,检查是否有电源管理导致网卡休眠:

sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

这行命令把系统休眠全部禁用,适合家庭NAS这种需要7x24在线的场景。客户端方面,可以在fstab里配置一个自动重连尝试:

-o x-systemd.automount,timeout=30

配合_netdev参数,systemd会在网络恢复后自动重挂载。文件被占用错误多半是Samba的锁机制在起作用。如果确认没有多人真的在写同一个文件,可以临时让某一端的打开文件行为不占锁:

[global] strict locking = no posix locking = no

再次强调,这个操作只适合单人长期使用的共享,多用户协作必须保留锁机制,否则文件写坏了好歹有锁保护。生产环境安全第一。

7. 从能用走向好用:我的几点运维心得

Samba这玩意儿,配通不难,配好也不难,但要用得长久顺手,有几个习惯值得养成。

第一,smb.conf每次改动前备份,改完必须testparm校验。这俩习惯能让你少踩80%的坑。我见过太多人改了配置文件直接重启服务,结果服务起不来,还找不到是哪行的错。testparm会明确告诉你第几行有什么问题,根本不需要自己瞪眼找。

第二,用smbstatus监控连接状态。这个命令能看到当前有哪些客户端连接、连的是哪个共享、正在做什么操作。性能出问题时第一反应就看它,比跑到客户端瞎猜强多了。

第三,版本升级要谨慎。Ubuntu大版本升级会顺带升级Samba,升级后有些配置参数可能会废弃。我的做法是升级前备份整个/etc/samba目录,升级后跑testparm对比差异,确认无异常再开放使用。

第四,有条件的话做好日志拉取。在smb.conf里我配了log file = /var/log/samba/log.%m,这样每个客户端的日志单独存放。有人连不上时直接看对应日志文件,比在/var/log/syslog里大海捞针高效得多。

最后分享一个我后来一直在用的小技巧:为了省去客户端每次输入密码的麻烦,同时也不在fstab里明文写密码,可以用credentials文件:

sudo mkdir -p /etc/samba sudo tee /etc/samba/credentials > /dev/null <<EOF username=smbuser password=你的密码 EOF sudo chmod 600 /etc/samba/credentials

然后fstab里这样写:

//192.168.1.100/share /mnt/samba_share cifs credentials=/etc/samba/credentials,uid=1000,gid=1000,iocharset=utf8,vers=3.0,_netdev,x-systemd.automount,noatime 0 0

权限600表示只有root能读写这个文件,比直接写在fstab里安全得多。这个细节虽小,但在多用户共用的机器上,能避免很多因为密码泄露引发的尴尬。

Samba配置是一个典型的"入门容易精通难"的活儿。按这篇文章的步骤走下来,两台Ubuntu之间共享文件夹基本不会有问题。真正把它用好,靠的是对权限模型的理解、对网络细节的把控,以及一套自己顺手的问题排查流程。上面这些参数和方法都是我在实际环境中验证过的,换个版本、换个环境大概率也能用,但务必在你自己的机器上测过再推广到生产环境。希望这些经验能帮你少走弯路。

返回列表