前言
NFS 好用,但Windows 访问 NFS 极其麻烦(要装客户端、要配身份映射、中文还容易乱码)。如果共享目录需要 Windows 同事直接双击打开,那就得上Samba。
Samba 是 SMB/CIFS 协议的开源实现,Windows 资源管理器原生支持,Linux 和 macOS 也能挂载。本文讲清楚怎么搭、怎么配权限,以及最容易卡住人的 SELinux 问题。
环境:Rocky Linux 8 / CentOS 7 服务端(Ubuntu 差异已标注),Windows 10 和 Linux 客户端验证。
一、安装
# Rocky / CentOS dnf install -y samba samba-client # Ubuntu / Debian # apt install -y samba # 确认版本 smbd -V二、先搞定用户和目录
Samba 的账号体系和 Linux 系统账号是两套,这点必须先理解,否则后面一定踩坑。
2.1 创建系统用户
# -M 不创建家目录,-s 指定不可登录的 shell useradd -M -s /sbin/nologin smbuser # 也可以直接在创建时同时加入 samba # useradd -M -s /sbin/nologin smbuser为什么要建系统用户?Samba 需要一个系统账号来映射文件属主。用户本身不需要能登录系统,所以 shell 设成
/sbin/nologin更安全。
2.2 设置 Samba 密码
smbpasswd -a smbuser # 输入两次密码这是最关键的一步:useradd建的密码 Samba不认,必须在 Samba 自己的密码库(/var/lib/samba/private/passdb.tdb)里单独设一次。
pdbedit -L # 查看已添加的 Samba 用户2.3 准备共享目录
mkdir -p /data/samba_share chown -R smbuser:smbuser /data/samba_share chmod 775 /data/samba_share三、配置 smb.conf
先备份(这个习惯很重要,很多发行版有默认配置):
cp /etc/samba/smb.conf /etc/samba/smb.conf.bak/etc/samba/smb.conf内容如下 —— 我直接给一份精简可用的完整配置,比在默认的几百行里找地方插入清晰得多:
[global] workgroup = WORKGROUP server string = Samba Server %v netbios name = fileserver security = user map to guest = bad user # ---- 中文文件名不乱码的关键 ---- unix charset = UTF-8 dos charset = CP936 display charset = UTF-8 # ---- 日志 ---- log file = /var/log/samba/log.%m max log size = 1000 [share] comment = Public Share path = /data/samba_share browseable = yes writable = yes valid users = smbuser create mask = 0664 directory mask = 0775参数说明
| 参数 | 作用 |
|---|---|
security = user | 用 Samba 自己的用户库认证(最常用) |
map to guest = bad user | 用户名不存在时当访客处理,配合guest ok = yes做匿名共享 |
valid users | 白名单,只有这里列出的用户能访问。强烈建议写 |
browseable | 是否在网络邻居里可见 |
writable | 是否可写(等价于read only = no) |
create mask/directory mask | 新建文件的权限掩码 |
unix charset = UTF-8 | 中文乱码的根源就在这行,务必设成 UTF-8 |
校验配置
改完一定要用testparm校验,能提前发现语法错误:
testparm -s它会打印最终生效的配置,如果有语法问题会直接报错。
四、SELinux 配置(90% 的人栽在这里)
如果你确认共享目录死活访问不了,先看这里。
即使smb.conf写对了、目录权限 777 了,SELinux 依然会拦。因为 SELinux 看的是安全上下文,不是传统权限位。
getenforce # 先看状态 # ① 允许 Samba 读写共享目录 setsebool -P samba_export_all_rw on # ② 给共享目录打上正确的 SELinux 标签 semanage fcontext -a -t samba_share_t "/data/samba_share(/.*)?" restorecon -Rv /data/samba_share # ③ 验证 ls -Z /data/samba_share # 输出里应该是 samba_share_t,比如: # unconfined_u:object_r:samba_share_t:s0 file.txt
semanage命令来自policycoreutils-python-utils包,没有的话先装:dnf install -y policycoreutils-python-utils
注意顺序:semanage fcontext只是写入规则,必须再执行restorecon才会真正应用到文件上。这两步缺一不可。
五、启动服务与防火墙
systemctl enable --now smb nmb # Ubuntu 上服务名是 smbd / nmbd # systemctl enable --now smbd nmbdsmb和nmb的区别:smb提供文件共享服务,nmb负责 NetBIOS 名称解析(就是让 Windows 的"网络邻居"能看到你的机器名)。只启 smb 不影响访问,但网络邻居里可能看不见,建议两个都启。
放行防火墙:
firewall-cmd --permanent --add-service=samba firewall-cmd --reload # samba 这个 service 已经包含了 137/138/139/445,不用单独加端口六、客户端访问
6.1 Windows
资源管理器地址栏输入:
\\192.168.1.10\share或者用命令行映射网络驱动器:
net use Z: \\192.168.1.10\share /user:smbuser踩坑:Windows 会缓存凭据。如果第一次密码输错了,后面怎么改都不对。清缓存:
net use * /delete /y然后到「控制面板 → 凭据管理器 → Windows 凭据」里把对应条目删掉。
6.2 Linux 客户端
dnf install -y cifs-utils mkdir -p /mnt/smb mount -t cifs //192.168.1.10/share /mnt/smb \ -o username=smbuser,password=你的密码,vers=3.0,iocharset=utf8几个参数别漏:
vers=3.0:Windows 10 1709 之后默认禁用了 SMBv1,不指定版本可能协商失败。老设备用vers=2.0,很老的 NAS 才需要vers=1.0。iocharset=utf8:中文文件名正常显示。
开机自动挂载,建议把密码放独立文件而不是写在 fstab 里(fstab 是全局可读的):
cat > /etc/samba/cred <<'EOF' username=smbuser password=你的密码 EOF chmod 600 /etc/samba/credfstab 加一行:
//192.168.1.10/share /mnt/smb cifs credentials=/etc/samba/cred,vers=3.0,iocharset=utf8,_netdev 0 0验证:
mount -a && df -h | grep smb七、常见问题排查
7.1 输入密码后提示"拒绝访问"或反复弹认证框
排查顺序:
# ① Samba 用户真的加了吗? pdbedit -L # ② valid users 里有这个用户吗? testparm -s | grep -A5 '\[share\]' # ③ 看日志,日志是最直接的线索 tail -f /var/log/samba/log.smbuser7.2 能连上但提示"没有权限访问"
按顺序查:
ls -ld /data/samba_share # 文件系统权限 ls -Z /data/samba_share # SELinux 上下文,应为 samba_share_t getsebool samba_export_all_rw # 应为 on如果ls -Z显示default_t或user_home_t,那就是 SELinux 没配对,回到第四节重做。
7.3 中文文件名乱码
服务端确认unix charset = UTF-8,客户端挂载加iocharset=utf8。
Windows 那边如果还有问题,通常是老系统的编码问题,dos charset = CP936是为兼容老客户端准备的。
7.4 网络邻居里看不到服务器
systemctl status nmb # nmb 起了吗如果是跨网段(Windows 和 Samba 不在同一广播域),NetBIOS 广播过不去,这是正常现象,直接用\\IP\share访问即可。
7.5 共享目录里有软链接失效
Samba 默认禁止跟随符号链接(安全考虑)。确实需要的话在[share]段加:
follow symlinks = yes wide links = yes unix extensions = no但请注意wide links = yes有安全风险,符号链接可以指向目录外的文件,等于绕过了共享限制。只在你完全信任共享用户时开。
八、进阶:多用户隔离共享
每个人只能访问自己的目录,需要[homes]段:
[homes] comment = Home Directories browseable = no writable = yes valid users = %S create mask = 0600 directory mask = 0700%S是变量,代表当前登录的用户名。用户连上来默认看到的就是自己的家目录,互相隔离。前提是每个用户都要执行过smbpasswd -a。
| 环节 | 关键点 |
|---|---|
| 用户 | useradd后必须再smbpasswd -a |
| 配置 | /etc/samba/smb.conf,改完testparm -s校验 |
| SELinux | setsebool -P samba_export_all_rw on+semanage fcontext+restorecon |
| 服务 | smb(文件)+nmb(名称解析) |
| 防火墙 | --add-service=samba |
| Windows | 凭据缓存用net use * /delete清 |
| Linux 挂载 | vers=3.0,iocharset=utf8 |
一句话记住排查顺序:用户库(pdbedit)→ 配置白名单(valid users)→ 文件系统权限 → SELinux 上下文 → 看日志。前四个都过了还不行,日志一定会告诉你原因。
作者水平有限,文中如有错误欢迎评论区指正。觉得有用的话点个赞再走。