简介这份资源是一份面向运维工程师与Linux初学者的Centos7 Samba服务器配置实战讲解内容以PDF格式呈现全包共1个文件大小约392KB。资料从Samba服务的基本概念入手重点演示了匿名共享访问与基于用户的身份验证两种典型配置流程覆盖yum安装、smb.conf配置优化、创建共享目录、关闭防火墙与SELinux、创建smb用户、权限划分及重启服务等关键步骤并配有命令示例和验证方法便于读者照步骤复现也能帮助理解SMB协议在局域网文件共享中的实际应用。当前已有1166人学习浏览适合想在真实环境中快速部署Samba服务并掌握常见排错思路的读者参考学习。1. 从一次共享失败说起CentOS 7 的 Samba 实战到底解决什么在 CentOS 7 上把 Samba 服务器配到能被 Windows 客户端直接认出来不是写一段 smb.conf 就完事。我见过不少团队在这个共享面前卡住文件路径没错、账号也建了可 Windows 那边要么弹 NT_STATUS_ACCESS_DENIED要么干脆找不到这台机器——问题往往不是 Samba 本身而是 CentOS 7 的防火墙和 SELinux 没配对。这篇文章用实战配置的方式讲清楚 Samba 服务从安装、共享、用户认证到排错的全过程适合内网里需要把 Linux 目录共享给 Windows 的运维和开发也适合刚接手 CentOS 7 文件服务器的人照着手敲。所有命令都基于 CentOS 7 默认环境没有图形界面依赖。2. 安装与最小可用的 SambaCentOS 7 的包选择和第一条 smb.conf2.1 为什么选 Samba三个替代方案与选型理由先回答一个最基本的问题CentOS 7 上做文件共享为什么不直接用 NFS 或 FTPNFS 在 Linux 到 Linux 的场景下表现很好透明挂载、权限跟随登录用户但 Windows 客户端的 NFS 支持要装额外组件而且 v4 的 Kerberos 配置在域环境里又是一层复杂度。FTP 能传文件但不能提供共享目录锁和类似本地盘的操作体验网页上传、断点续传都需要额外开发权限模型也跟 POSIX 不匹配。HTTP 只能读为主不能写。Samba 使用 SMB 协议是 Windows 原生的协议Windows、Mac、Linux 都能识别还支持文件锁、打印机共享、AD 域认证所以当你的共享对象里有 Windows 客户端Samba 几乎是少不掉的。这个选择也有代价Samba 封装了一层权限转换大文件传输场景可能有额外开销配置不好时还会遇到 SELinux 和防火墙的双重拦截。因此我的经验是纯 Linux 内部用 NFS给 Windows 用 Samba两边都需要的场景才单独起一台 Samba 服务器。如果你是开发团队要共享一份代码目录给不同系统的 CI 机用 Samba 的 guest 只读共享就够别上域认证。2.2 安装 Samba 及相关工具yum 安装和验证CentOS 7 官方源里自带 Samba 4.x 系列包不要手动编译除非你有特殊补丁需求。用 yum 装最省事# 安装服务端、客户端和公共工具 yum install -y samba samba-client samba-common # 确认安装后的版本 rpm -q samba samba-client samba-common三个包分开说samba 是服务端主程序提供 smbd 和 nmbdsamba-client 提供 smbclient、smbstatus 等命令后期排错离不开它samba-common 提供 testparm、/etc/samba/smb.conf 模板等公共配置。实际安装时 samba 包会把 samba-common 作为依赖拉进来但显式写出来可以避免某些最小化系统缺工具。如果你在内网环境装不上先检查 yum 源是否可用同步 CentOS 7 的 Base 和 Updates 源再执行 update。网络不通时不要急着换源先看 DNS 能不能解析域名——CentOS 7 新装系统经常是网卡没拿到 DNS导致 yum 直接报 cannot resolve host。2.3 写一个最小可用的 smb.conf匿名共享配置找一台测试机先把原始配置备份再清空重写cp -a /etc/samba/smb.conf /etc/samba/smb.conf.bak mkdir -p /srv/share chmod 777 /srv/share然后用 vim 编辑 /etc/samba/smb.conf写入下面这段[global] workgroup WORKGROUP server string CentOS 7 Samba Server security user map to guest Bad User guest account nobody [public] path /srv/share browseable yes writable yes guest ok yes create mask 0664 directory mask 0775说明几个关键参数security user 是 CentOS 7 默认的安全模式要求每个连接先做用户认证即使 guest 也要先经过 guest 账号映射。map to guest Bad User 的含义是如果客户端提交的用户名不存在就把这个连接降级成 guest这样匿名访问才能落进 guest account nobody 的上下文。public 段里 path 指定实际目录browseable yes 让客户端在网络邻居里能看到此共享writable yes 允许写入guest ok yes 放行匿名访问。create mask 和 directory mask 是新建文件/目录时对系统权限按位取反掩码这里让文件有 0664、目录有 0775保证用户组可写。启动两个服务并设置开机自启systemctl start smb nmb systemctl enable smb systemctl enable nmb注意 CentOS 7 要用 systemctl不要再用 service smb start 这种 SysV 命令。smb 服务对应 smbd端口 445/139nmb 服务对应 nmbdUDP 137负责 NetBIOS 名称广播解析Windows 客户端靠它看到主机名。虽然很多教程说只开 smb 就行但如果你想让 Windows 网络邻居里能列出主机nmb 最好一起开。之后用 testparm 验证配置语法它会解析 smb.conf 并显示实际生效的参数testparm -s如果输出里出现了你写的 [public] 段说明配置至少没有语法错误。注意 testparm 只检查语法不保证服务能通真正的网络验证要等防火墙和 SELinux 配好否则就算配置正确也会被拒之门外。在配置继续之前也可以先用 smbclient -L 127.0.0.1 -U guest -N 看看本机是否能看到这个共享如果这一步就失败多半是服务没起来或配置写错了别急着往后走。3. 从匿名到认证共享把 CentOS 7 目录安全地开放给同事3.1 用户共享的设置流程系统用户与 Samba 密码匿名共享虽然方便但任何能访问该网络的人都能下载甚至写入文件稍一松懈就会变成“裸奔”。生产上给团队开目录我会首选带用户认证的共享。Samba 的认证有个容易混淆的点它要求客户端访问时提交的账号必须同时满足两个条件——账号存在于系统 /etc/passwd 中并且在 Samba 的密码数据库中有记录。这两者不是一回事系统密码是用户登录 Linux 用的而 Samba 密码由 pdbedit 或 smbpasswd 管理。创建用户的典型命令# 创建系统用户不建家目录禁止 SSH 登录 useradd -M -s /sbin/nologin shareuser # 添加该用户到 Samba 密码库并设置 Samba 密码 pdbedit -a -u shareuserpdbedit 是推荐做法因为 CentOS 7 默认的 passdb backend 是 tdbsampdbedit 专门管理 tdbsam 数据库。执行后会交互式要求输入密码这个密码和 /etc/shadow 里的系统密码无关。如果你出于习惯用 smbpasswd -a shareuser它也可以但 pdbedit 更统一。如果你希望一组人访问建议创建同名系统组比如 groupadd projectgroup然后 useradd -G projectgroup user1。需要提醒的是-s /sbin/nologin 不影响 Samba 登录因为 Samba 的认证不经过 shell关掉 SSH 登录反而减少了攻击面。3.2 配置认证共享valid users、write list 与权限位接下来在 smb.conf 里新增一个带认证的共享。我一般按业务建一个独立的段例如 project[project] comment Project Shared Files path /srv/project browseable yes read only no valid users projectgroup, shareuser write list projectgroup create mask 0660 directory mask 0770 force group projectgroup这段配置比匿名共享多了三个关键项。valid users 限定能访问这个共享的用户或组projectgroup 代表项目组其他人一律被拒write list 指定额外可写成员这表示即使用户能被读取不在 write list 里也只能读不能写——我这里让整个项目组可写所以 write list 和 valid users 很接近但如果你想让某个人只读比如经理就不把他加进 write list。force group projectgroup 很实用它让所有在共享里创建的文件组属性强制为 projectgroup避免用户各自的主组不一致导致同组其他人无法写文件。光改配置不够系统目录本身要有正确的属主和权限mkdir -p /srv/project chown root:projectgroup /srv/project chmod 2770 /srv/projectchmod 的 2 是 setgid 位它的作用是让该目录下新创建的文件自动继承 projectgroup 组。否则即使 Samba 做了 force group新建的文件也可能因为用户的 umask 变成其他组其他成员仍写不动。这一步是很多人配完 Samba 写不进文件的常见原因之一后面避坑章节再展开。改完配置后重启服务systemctl restart smb nmb为什么用 restart 而不是 reload因为新增共享段时smbd 的主进程如果还持有旧配置reload 也可能生效但为了确保进程直接以新配置工作特别是你改了 force group、create mask 这类会影响文件创建的参数重启最稳妥。生产环境若怕中断连接也可以 systemctl reload smb测试机建议重启。3.3 Windows 和 Linux 客户端分别怎么连接Windows 客户端最直接的方式是按 WinR 输入\\192.168.10.20\project输入刚才创建的 shareuser 和 Samba 密码即可。如果 Windows 始终弹出“找不到网络路径”先用 IP不要依赖主机名因为 NetBIOS 名称解析在跨 VLAN 时经常失效。要主机名可见需要确保 nmb 服务开了且 Windows 的 SMB 客户端功能正常。Windows 10/11 默认支持 SMB2/3CentOS 7 的 Samba 4.x 也支持两边默认协议能协商成功不需要额外去“启用 SMB 1.0/CIFS 文件共享支持”。如果你是在 Windows 上测试的反直觉结论是往往越旧的方法越不管用。Linux 客户端用 smbclient 验证最直接smbclient //192.168.10.20/project -U shareuser -W WORKGROUP进去之后可以 ls、get 测试。也可以直接挂载成目录mkdir -p /mnt/project mount -t cifs //192.168.10.20/project /mnt/project \ -o usernameshareuser,vers3.0,uid1001,gid1001,iocharsetutf8这里的 -o 参数里vers3.0 强制使用 SMB3 协议避免某些旧内核模块回退到 SMB1 引发安全问题uid/gid 指定挂载后的文件归属到本地账号否则会显示成 root 占用普通用户读不了iocharsetutf8 处理中文文件名防止乱码。如果你需要每次开机自动挂载可以写进 /etc/fstab但要用 credentials 文件存放密码避免把密码明文写进 fstab。4. 打通防火墙和 SELinux让 CentOS 7 的 Samba 真正可访问4.1 防火墙放行 Sambafirewalld 三条命令CentOS 7 默认开了 firewalld它对网络接口按 zone 过滤。Samba 用了 TCP 139、445 和 UDP 137、138firewalld 已经内置了 samba 服务别名直接放行它就行firewall-cmd --permanent --add-servicesamba firewall-cmd --reload firewall-cmd --list-services第一条 --permanent 表示写入运行时配置并同时保存到磁盘第二条 reload 让配置立即生效第三条列出当前放行的服务确认里面有没有 samba。注意 --reload 和 --complete-reload 的区别前者保留运行时的手动规则后者清空重新加载日常用前者就够了。如果你图省事也有很多人用 firewall-cmd --add-servicesamba 不带 --permanent结果机器一重启又失效——这种坑我踩过。如果你的服务器是历史遗留用了 iptables 而不是 firewalld可以这样放行iptables -I INPUT -p tcp --dport 445 -j ACCEPT iptables -I INPUT -p tcp --dport 139 -j ACCEPT iptables -I INPUT -p udp --dport 137 -j ACCEPT iptables -I INPUT -p udp --dport 138 -j ACCEPT但 CentOS 7 官方路径还是 firewalld除非你明确停用了 firewalld否则别混用混用可能出现“一条 iptables 规则覆盖了 firewalld”的诡异情况。4.2 SELinux 布尔值与上下文两个 setsebool 一种做法防火墙都通了本机 smbclient -L 都能列共享Windows 还是连不上这时候十有八九是 SELinux。SELinux 对 Samba 的限制主要体现在两部分布尔值和文件上下文。CentOS 7 默认开启 enforcingsmbd 程序域是 smbd_t它要读取共享目录共享目录必须被标记为 samba_share_t 类型或者放开对应的布尔值。最省事的做法是开全局写布尔值setsebool -P samba_export_all_rw on这个布尔值让 smbd 可以读写所有被标记为 samba_share_t 或其他可导出类型的主机文件系统。但这相当于一把大门钥匙粒度粗。更推荐按目录设置上下文semanage fcontext -a -t samba_share_t /srv/project(/.*)? restorecon -Rv /srv/project第一条命令是向 SELinux 策略库注册一条规则说明 /srv/project 目录及其子目录都应该用 samba_share_t 类型第二条命令按当前策略重新给目录打标签这样标签在重启或 restorecon 后依然有效。如果系统提示 semanage 命令不存在安装 policycoreutils-python 包即可。还有一种快速却临时的办法就是 chcon -Rt samba_share_t /srv/project它直接改目录的上下文但不写入策略库一旦磁盘重新标记或执行 restorecon 会恢复成原来的类型。我建议实验时可先用 chcon确认问题后立刻补上 semanage restorecon 让配置固化。如果不确定当前是什么上下文用 ls -Zd /srv/project 查看。显示 default_t 或 user_home_t 时Samba 访问大概率会被拒。4.3 验证服务监听与连接ss、smbclient 的组合配完防火墙和 SELinux不要急着去 Windows 上点先用服务器本机验证一条龙# 1. 检查端口监听 ss -tlnp | grep smbd ss -ulnp | grep nmbd # 2. 本机列出共享 smbclient -L //127.0.0.1 -U shareuser -W WORKGROUP如果 ss 没有输出说明 smbd/nmbd 进程没起来或者被系统限制了用 systemctl status smb nmb 查看原因。如果端口正常但 smbclient -L 报 NT_STATUS_ACCESS_DENIED排查认证和权限如果报 connection refused则大概率是防火墙或服务没起来而不是 Samba 本身。本机测试通过后再找另一台 Windows 或 Linux 客户端连接。如果远程失败检查远程到服务器的端口连通性比如在另一台 Linux 上执行 nmap -p445 192.168.10.20或 telnet 192.168.10.20 445。这时候出现的坑往往是跨网段、防火墙默认 drop端口看起来通不了就要回到 4.1 节去看 zone 配置了。另外如果本机能看共享但远程死活连不上而且端口测试显示不通先不要怀疑 Samba直接看 firewalld 的 active zonesfirewall-cmd --get-active-zones确定你的网卡挂在哪一个 zone。很多时候服务器有内网和外网网卡内网网卡挂在 internal zone你在 public zone 放行了 samba等于白做。这是配置防火墙时最容易漏掉的细节。5. 实战中的 5 个翻车点Samba 配置避坑排查指南5.1 NT_STATUS_ACCESS_DENIED目录权限还是 SELinux 的锅现象smbclient 连上了共享但执行 mkdir 或 put 时报 NT_STATUS_ACCESS_DENIED。原因分两层。第一层是系统权限Samba 在认证通过后以该系统用户的身份去访问共享目录如果目录不可写即使 Samba 里 writableyes 也无济于事。第二层是 SELinuxsmbd_t 域被 SELinux 拒绝访问目标目录文件。这两者的现象完全一样导致新手经常在 chmod 上折腾半天也没效果。解决先看目录属主、权限和上下文。一次做三件事ls -ld /srv/project ls -Zd /srv/project getsebool samba_export_all_rw权限位建议目录至少 2770属主组和 valid users 对应。上下文若不是 samba_share_t按 4.2 节修复。如果是布尔值处于 offsetsebool -P samba_export_all_rw on。大部分情况下前者是根因。注意顺序先确认系统权限再动 SELinux因为 SELinux 的日志在 /var/log/messages 里会显示 avc: denied更容易定位。5.2 连接超时或拒绝防火墙只开了 ssh 却忘了 samba现象Windows 双击服务器共享时一直转圈最终报“找不到网络路径”或“错误 53”Linux 客户端挂载时报 mount error(112) Connection refused。原因firewalld 只放行了 sshSamba 的 139/445 被默认 drop。Samba 服务名在 firewalld 里定义为 samba不是 smb新手容易敲 --add-servicesmb报错说服务不存在。解决按 4.1 节操作。如果自定义了非标准端口生产不建议要用 --add-port1445/tcp 并改 smb.conf 里的 smb ports 参数。另有一种情况是客户端访问时走了 IPv6但服务器 IPv6 防火墙不放行可以在客户端用 -d 参数强制指定 IPv4例如 mount -t cifs //192.168.10.20/share /mnt -o addr192.168.10.20。5.3 修改配置没有生效restart 与 reload 的取舍现象在 smb.conf 里新增了共享客户端用 smbclient -L 却看不到或者改了 path访问的还是老路径。原因smbd/nmbd 是常驻进程启动时已经读入旧配置很多教程只说“改完配置重启服务”但有人在 testparm 看到新配置就以为生效了testparm 只是静态解析不代表运行中的进程已经切换。解决修改配置后执行 systemctl restart smb nmb 让进程完全重启。如果只是改了权限相关参数而没有改共享结构可以 systemctl reload smb但对及时性没把握我建议在维护窗口内统一 restart。重启后马上用 smbclient -L //127.0.0.1 -U shareuser 确认新的共享名出现。这里还要补一个习惯改配置前用 cp 备份改完用 testparm 检查语法再重启避免一个语法错误让 Samba 起不来客户端全部断开。5.4 协议协商失败老客户端连不上日志提示 PROTOCOL_NEGOTIATION_FAILED现象老设备例如生产仪器、老打印机或 Windows XP连接时提示“无法连接”服务器日志中出现 NT_STATUS_NOT_SUPPORTED 或 PROTOCOL_NEGOTIATION_FAILED。原因CentOS 7 自带的 Samba 4.10 默认 server min protocol SMB2_10这意味着低于 SMB2.1 的协议不会被接受。旧设备往往只支持 SMB1而现代操作系统出于安全默认关闭 SMB1两边无法协商。解决如果确认必须支持该设备可在 [global] 设置 server min protocol SMB1并明确承担安全风险。SMB1 存在蠕虫和中间人攻击面我不建议在公网或不可信环境这样做如果是内网隔离且设备无法升级可以用一个独立共享只给该设备使用同时在防火墙里限制来源 IP。现代客户端不受影响因为 server max protocol 默认为 SMB3两者取交集。多数情况我会劝阻用户开启 SMB1劝他用支持 SMB2 的新设备替代不要让遗留设备拖累整台服务器的安全基线。5.5 中文文件名乱码客户端和挂载参数不对现象Windows 看共享文件的中文名变成“é”或问号Linux 客户端用 CIFS 挂载后中文文件名无法操作。原因Samba 服务端默认内部编码是 UTF-8传输层走 unicode大多数现代客户端没问题。乱码常见于挂载时未指定 iocharset或者一些嵌入式客户端用本地编码但本地编码不是 UTF-8。解决在 smb.conf 的 [global] 显式声明unix charset UTF-8 display charset UTF-8 dos charset CP936unix charset 和 display charset 保持 UTF-8dos charset 让 Windows 侧传统代码页的客户端能正确解释。Linux 挂载时加 iocharsetutf8例如 mount -t cifs //server/share /mnt -o usernameuser,iocharsetutf8。这里注意别把 dos charset 换成 GBK否则本身用 UTF-8 的客户端反而乱。如果文件已经乱码不要想在挂载层面挽救那是当初写入时的编码不统一造成的回头在源头整理并约定全链路用 UTF-8。6. 一条命令巡检 Samba 共享验证连通性与写权限的更稳妥做法前面的配置和排错都是基于手动测试但生产环境需要一条可重复执行的命令便于放进定时任务或根因排查。我最常用的是基于 smbclient 的写入探活它不仅验证共享是否可见还验证账户能不能真正写文件。分享一个可以直接套用的 bash 函数check_samba_share() { local srv$1 local share$2 local user$3 local pass$4 # 探活列共享和目录 smbclient //${srv}/${share} -U ${user}%${pass} \ -c mkdir .healthcheck; rmdir .healthcheck /dev/null 21 if [ $? -eq 0 ]; then echo [OK] ${srv} ${share} 可读写 else echo [FAIL] ${srv} ${share} 连接或写入失败 fi } # 用法示例 check_samba_share 127.0.0.1 project shareuser s3cret函数里的-c参数传给 smbclient 一条命令字符串先创建再删除隐藏目录模拟真实写入路径不仅测网络连通也测认证、SELinux、目录权限一下子就暴露 5.1 节提到的 NT_STATUS_ACCESS_DENIED。如果只想测读可以换成 ls。每次巡检后记住把退出码存下来才算闭环。我一般还会追加一个 smbclient -L 看共享是否存在但核心是写入探活因为很多故障只影响写入而不影响读取。如果你不想把密码明文放在命令行可以搭配 --authentication-file 或填入 credentials 文件避免 shell 历史泄露。这个 shell 函数可以放入 /usr/local/bin/samba_health.sh再交给 cron 每小时跑一次输出追加到日志文件。我在早期运维生涯中吃过亏平时共享能读、能列目录就以为没事直到月底别人汇报写不进文件才发现磁盘变成了只读正是因为我没有做写入探活。从那以后巡检统一要测 mkdir/rmdir这个习惯帮我提前处理了好几次磁盘满或权限漂移的问题。希望帮到你。本文还有配套的精品资源点击获取