一、迁移RHEL后Samba共享访问失败的核心排查方向

不少朋友把业务系统从旧服务器(比如CentOS 6/7、Ubuntu这类兼容性更宽松的系统)迁移到RHEL(红帽企业Linux)后,都会碰到一个头疼的问题:之前好好用的Samba共享文件夹,要么是Windows客户端连不上、要么是Linux客户端读不了写不了,甚至连输入账号密码的弹窗都弹不出来。我之前帮三家不同规模的企业排查过这类问题,总结下来90%以上的故障都集中在三个地方:SELinux的安全规则没跟上、firewalld防火墙拦了流量、Kerberos认证没配通。接下来就从这三个角度一步步拆,每个部分都配完整的操作示例,不管你是刚接触Linux的新手还是有几年经验的运维,都能跟着做。

二、第一个排查方向:SELinux安全上下文错配

2.1 什么是SELinux安全上下文(通俗解释)

很多人一听到SELinux就头大,觉得是个麻烦的安全机制,其实它的作用很简单:RHEL为了防止黑客入侵后篡改系统文件,给每个文件、文件夹、进程都贴了个“身份标签”,这个标签就是安全上下文。比如普通用户的家文件夹标签是unconfined_u:object_r:user_home_t:s0,系统配置文件夹是system_u:object_r:etc_t:s0,只有标签匹配的进程才能访问对应的资源。Samba服务要访问共享文件夹,那共享文件夹的标签必须符合Samba的要求,否则就算你权限设成777,SELinux也会直接拦下来。

2.2 错配的典型场景与排查步骤

举个最常见的例子:迁移的时候你把共享文件夹从旧服务器拷到新RHEL服务器的/opt/share路径下,或者直接把Samba的共享路径改成了自己建的/data/smb_share,而不是用系统默认的共享路径(比如/var/samba/share),这时候就很容易出现标签不匹配。 第一步先查共享文件夹的标签对不对,技术栈用Shell(RHEL自带的bash环境),执行命令:

# 查看指定文件夹的SELinux安全上下文,-Z参数就是显示标签的意思
ls -Zd /opt/share

正常情况下Samba共享文件夹的标签应该是unconfined_u:object_r:samba_share_t:s0或者system_u:object_r:samba_share_t:s0,如果你看到的是unconfined_u:object_r:user_home_t:s0(用户家目录标签)或者unconfined_u:object_r:default_t:s0(默认未分类标签),那就是标签错配了。

2.3 修复示例与注意事项

修复的方法有两种,一种是临时改标签,测试用;一种是永久改标签,适合正式环境。 第一种临时修复(重启服务器后会失效):

# 临时修改指定文件夹的SELinux标签为Samba专用标签,-R参数是递归修改子文件
chcon -R -t samba_share_t /opt/share

改完之后可以再用ls -Zd /opt/share查一遍,确认标签已经变成samba_share_t,这时候再试访问Samba共享,大概率就能通了。但临时修改的缺点是重启后系统会把标签还原成原来的,所以正式环境要用第二种永久修复:

# 永久设置指定文件夹的SELinux标签,-a参数是添加规则,-t指定目标标签
semanage fcontext -a -t samba_share_t "/opt/share(/.*)?"
# 执行restorecon命令让规则生效,-R递归处理子文件
restorecon -Rv /opt/share

这里要注意两个点:一是/opt/share(/.*)?这个格式是正则表达式,代表/opt/share下的所有文件和子文件夹,不能直接写/opt/share,否则只会改文件夹本身的标签,子文件还是错的;二是如果你的共享文件夹是用来做只读共享的,其实还有个更安全的标签public_content_t,这个标签允许所有服务(包括Samba、FTP、HTTP)访问,适合公开的只读共享场景,但如果要做读写共享,必须用samba_share_t

三、第二个排查方向:firewalld规则拦截

3.1 firewalld和Samba的关系(通俗解释)

RHEL默认用firewalld做防火墙,它比旧版的iptables更灵活,可以按区域(比如public、internal、trusted)设置规则。Samba服务需要用到两个端口:139端口(NetBIOS over TCP/IP,用来做旧版Windows的主机名解析和共享访问)和445端口(SMB协议的主要端口,新版Windows和Linux客户端都用这个)。如果firewalld没开这两个端口,或者开了但没允许来自客户端IP的访问,就会出现“连接超时”或者“找不到网络路径”的错误。

3.2 拦截的典型场景与排查步骤

最常见的场景是:迁移的时候你只开了Samba服务,没改防火墙规则,或者之前用的是iptables,现在换成firewalld后规则没迁移过来。第一步先查firewalld的状态和已开放的服务:

# 查看firewalld是否运行,running就是正常运行
systemctl status firewalld
# 查看当前默认区域已开放的服务,这里会显示哪些服务被允许通过防火墙
firewall-cmd --list-services

如果输出里没有smb这个服务,那就是防火墙没开Samba的端口。另外还要注意,firewalld的规则分临时和永久,临时规则重启后会失效,永久规则需要加--permanent参数。

3.3 修复示例与注意事项

修复的步骤分两种情况:一种是给整个区域开Samba服务,适合客户端IP比较分散的场景;一种是只允许特定IP访问,适合只给内部特定网段用的场景。 第一种全区域开放(适合公开的共享服务):

# 临时开放smb服务,当前生效,重启后失效
firewall-cmd --add-service=smb
# 永久开放smb服务,需要加--permanent参数
firewall-cmd --permanent --add-service=smb
# 永久规则需要重载才能生效
firewall-cmd --reload

改完之后可以用firewall-cmd --list-services确认smb已经在列表里。第二种特定IP开放(适合内部专用共享),比如只允许192.168.1.0/24这个网段的客户端访问:

# 永久允许指定网段访问smb服务
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="smb" accept'
# 重载规则生效
firewall-cmd --reload

这里要注意两个点:一是如果你的Samba服务用了自定义端口(不是默认的139和445),那不能用--add-service=smb,得手动开端口,比如用50013和50045端口的话,命令是firewall-cmd --permanent --add-port=50013/tcp --add-port=50045/tcp;二是如果客户端是Linux系统,还要确认客户端的防火墙有没有开相关端口,比如CentOS客户端要开smb-client服务,否则也连不上。

四、第三个排查方向:Kerberos认证集成问题

4.1 Kerberos认证和Samba的关系(通俗解释)

如果你的Samba共享是和AD(活动目录)或者LDAP集成的,用来做域账号登录,那就要用到Kerberos认证。Kerberos相当于一个“电子门禁”,客户端要先从Kerberos服务器拿到一张“门票”(TGT,票据授权票据),再用门票换访问Samba服务的“子门票”(服务票据),才能访问共享。如果Kerberos的配置错了,比如服务器的时间不对、域名解析错了、票据过期了,就会出现“账号密码错误”或者“拒绝访问”的提示。

4.2 集成问题的典型场景与排查步骤

最常见的场景是:迁移的时候把Samba服务器的IP改了,或者AD服务器的IP改了,导致Kerberos的配置和实际不符。第一步先查Kerberos的配置文件/etc/krb5.conf,确认里面的内容是对的:

# 查看Kerberos配置文件,默认路径是/etc/krb5.conf
cat /etc/krb5.conf

正常的配置应该包含三个部分:[libdefaults](默认配置,比如默认域、DNS解析规则)、[realms](域的信息,比如Kerberos服务器的地址)、[domain_realm](域名和域的映射)。比如AD域是EXAMPLE.COM,AD服务器的IP是192.168.1.100,那配置应该是这样的:

[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_kdc = true
    dns_lookup_realm = true

[realms]
    EXAMPLE.COM = {
        kdc = 192.168.1.100
        admin_server = 192.168.1.100
    }

[domain_realm]
    .example.com = EXAMPLE.COM
    example.com = EXAMPLE.COM

第二步查服务器的时间,因为Kerberos要求服务器和AD服务器的时间差不能超过5分钟,否则会认为票据无效:

# 查看服务器的当前时间
timedatectl status

如果时间不对,要改成和AD服务器一致的时间,命令是:

# 手动设置时间,比如改成2024-05-20 12:00:00
timedatectl set-time "2024-05-20 12:00:00"

第三步查Kerberos的票据是否有效,用kinit命令测试能不能拿到票据:

# 用域账号test_user登录Kerberos,会提示输入密码
kinit test_user@EXAMPLE.COM
# 查看当前拿到的票据,确认是否有有效票据
klist

如果kinit命令报错,比如“找不到KDC”,那要么是/etc/krb5.conf里的KDC地址错了,要么是服务器连不上AD服务器;如果kinit成功但klist显示票据过期,那就是时间差的问题。

4.3 修复示例与注意事项

修复的步骤分几种情况:如果是配置文件错了,先改/etc/krb5.conf,然后重启Samba服务:

# 重启Samba服务,让配置生效
systemctl restart smb nmb

如果是时间差的问题,除了手动改时间,最好配置NTP服务同步AD服务器的时间,比如AD服务器的NTP地址是192.168.1.100,那配置/etc/chrony.conf(RHEL7及以上用chrony做时间同步):

# 编辑chrony配置文件
vi /etc/chrony.conf
# 把默认的pool改成AD服务器的地址
server 192.168.1.100 iburst
# 重启chrony服务并设置开机自启
systemctl restart chronyd
systemctl enable chronyd
# 查看时间同步状态
chronyc sources

如果是票据过期的问题,除了改时间,还可以在/etc/krb5.conf[libdefaults]里加ticket_lifetime = 24h,把票据的有效期改成24小时,避免频繁过期。这里要注意两个点:一是Samba服务器的主机名必须能被AD服务器解析,比如在AD服务器里加一条DNS记录,把Samba服务器的主机名smb-server指向它的IP 192.168.1.200;二是如果用的是LDAP集成,还要确认/etc/samba/smb.conf里的security = ads(AD集成)或者security = ldap(LDAP集成)是对的,不能设成security = user

五、应用场景、技术优缺点与注意事项

5.1 应用场景

这三个排查方向几乎覆盖了RHEL环境下Samba共享访问失败的所有常见场景,不管是中小公司的内部文件共享、企业级的域账号共享,还是迁移后的测试环境,都能用这些方法定位问题。比如刚把旧的文件服务器换成RHEL的、把Samba服务从CentOS迁移到RHEL的、给RHEL服务器配置Samba共享的,都可以按这三个步骤排查。

5.2 技术优缺点

先说说这三个排查方法的优点:一是都是基于RHEL默认配置的,不需要额外装软件,比如SELinux是默认开的、firewalld是默认装的、Kerberos是默认支持的;二是步骤清晰,每个步骤都有明确的命令和输出,新手也能跟着做;三是覆盖了90%以上的故障,不用到处找零散的解决方案。 再说说缺点:一是SELinux的标签规则比较复杂,不同的共享场景要对应不同的标签,容易搞混;二是firewalld的永久规则和临时规则容易搞混,重载的步骤容易忘;三是Kerberos的配置涉及到AD和DNS,对不熟悉域环境的人来说有点难。

5.3 注意事项

一是排查的时候要按顺序来,先查SELinux,再查firewalld,最后查Kerberos,因为SELinux是最常见的问题,排在前面能节省时间;二是改配置之前要备份,比如改/etc/krb5.conf之前先复制一份备份,改/etc/samba/smb.conf之前也备份;三是改完配置之后要重启对应的服务,比如改完SELinux标签不用重启服务,改完firewalld规则要重载,改完Kerberos配置要重启Samba服务;四是如果是生产环境,最好在非业务高峰的时候改配置,避免影响用户访问。

六、文章总结

把业务迁移到RHEL后Samba共享访问失败,本质上是RHEL的安全机制和旧系统的差异导致的:SELinux的安全上下文比旧系统严格、firewalld的规则比旧系统复杂、Kerberos的集成要求比旧系统高。只要按SELinux、firewalld、Kerberos的顺序排查,每个步骤都按示例操作,就能快速定位并解决问题。另外,在迁移之前最好先在测试环境里配置好Samba共享,确认所有规则都正常,再迁移到生产环境,能避免很多不必要的故障。