通过 SMB 为访问 Azure 文件存储的 Linux 客户端启用 Active Directory 身份验证

有关支持选项和注意事项的详细信息,请参阅实现 SMB 访问的 Azure 文件存储基于标识的身份验证选项概述

Azure 文件存储支持使用 Kerberos 身份验证协议,通过服务器消息块 (SMB) 通过以下方法对 Linux 虚拟机 (VM) 进行基于标识的身份验证:

  • 本地 Windows Active Directory 域服务 (AD DS)
  • Microsoft Entra 域服务

若要使用 AD DS,必须使用 Microsoft Entra Connect 将 AD DS 同步到 Microsoft Entra ID。

备注

本文使用 Ubuntu 说明示例步骤。 类似的配置适用于 RHEL 和 SLES 客户端,允许使用 Active Directory 装载 Azure 文件共享。

适用于

管理模型 计费模式 媒体层 冗余 中小型企业 (SMB) 网络文件系统(NFS)
Microsoft.Storage 预配版本 v1 SSD(高级) 本地 (LRS) 是的 否
Microsoft.Storage 预配版本 v1 SSD(高级) 区域 (ZRS) 是的 否
Microsoft.Storage 即用即付 HDD(标准) 本地 (LRS) 是的 否
Microsoft.Storage 即用即付 HDD(标准) 区域 (ZRS) 是的 否
Microsoft.Storage 即用即付 HDD(标准) 异地 (GRS) 是的 否
Microsoft.Storage 即用即付 HDD(标准) GeoZone (GZRS) 是的 否

Linux SMB 客户端限制

不能使用基于标识的身份验证在启动时使用 fstab 条目在 Linux 客户端上装载 Azure 文件共享,因为客户端无法及早获得 Kerberos 票证以在启动时装载。 可以使用条目 fstab 并指定 noauto 选项,以便在不使用所有参数的简单装载命令登录后让用户装载文件共享。 还可以使用 autofs 在访问后装载共享。

先决条件

在通过 SMB 为 Azure 文件共享启用 AD 身份验证之前,请确保已完成以下先决条件。

  • 运行 Ubuntu 18.04+ 的 Linux VM 或等效 RHEL 或 SLES VM。 如果在 Azure 上运行,则 VM 在包含 Microsoft Entra 域服务的 VNET 上必须至少具有一个网络接口。 如果使用本地 VM,则必须将 AD DS 同步到 Microsoft Entra ID。
  • 具有完全 sudo 权限的本地用户帐户的根用户或用户凭据(对于本指南,为 localadmin)。
  • Linux VM 尚未加入另一个 AD 域。 如果它已经是某个域的一部分,它必须先离开该域,然后才能加入该域。
  • 已完全配置的 Microsoft Entra 租户,其中已设置域用户。

安装 samba 包并不是绝对必要的,但它会为您提供一些有用的工具并自动引入其他包,例如 samba-commonsmbclient。 运行以下命令以进行安装。 如果在安装过程中要求你输入任何值,请将其留空。

sudo apt update -y
sudo apt install samba winbind libpam-winbind libnss-winbind krb5-config krb5-user keyutils cifs-utils

该工具 wbinfo 是 samba 套件的一部分,可用于身份验证和调试目的,例如检查域控制器是否可访问、检查计算机加入的域以及查找有关用户的信息。

确保 Linux 主机的时间与域服务器保持同步。 请参阅适用于 Linux 分发的文档。 对于某些发行版,可以使用 systemd-timesyncd 执行此操作。 使用常用文本编辑器编辑 /etc/systemd/timesyncd.conf,以包括以下内容:

[Time]
NTP=onpremaadint.com
FallbackNTP=ntp.ubuntu.com

然后重启服务:

sudo systemctl restart systemd-timesyncd.service

启用 AD Kerberos 身份验证

按照以下步骤启用 AD Kerberos 身份验证。 作为参考,此 Samba 文档可能会有所帮助。

确保域服务器可访问且可发现

  1. 请确保提供的 DNS 服务器包含域服务器 IP 地址。
systemd-resolve --status
Global 
          DNSSEC NTA: 10.in-addr.arpa
                      16.172.in-addr.arpa
                      168.192.in-addr.arpa
                      17.172.in-addr.arpa
                      18.172.in-addr.arpa
                      19.172.in-addr.arpa
                      20.172.in-addr.arpa
                      21.172.in-addr.arpa
                      22.172.in-addr.arpa
                      23.172.in-addr.arpa
                      24.172.in-addr.arpa
                      25.172.in-addr.arpa
                      26.172.in-addr.arpa
                      27.172.in-addr.arpa
                      28.172.in-addr.arpa
                      29.172.in-addr.arpa
                      30.172.in-addr.arpa
                      31.172.in-addr.arpa
                      corp
                      d.f.ip6.arpa
                      home
                      internal
                      intranet
                      lan
                      local
                      private
                      test 

Link 2 (eth0) 
      Current Scopes: DNS 
       LLMNR setting: yes 
MulticastDNS setting: no 
      DNSSEC setting: no 
    DNSSEC supported: no 
         DNS Servers: 10.0.2.5 
                      10.0.2.4 
                      10.0.0.41
          DNS Domain: domain1.contoso.com 
  1. 如果命令有效,请跳过以下步骤,然后转到下一部分。

  2. 如果无效,请确保域服务器 IP 地址正在执行 ping 操作。

ping 10.0.2.5
PING 10.0.2.5 (10.0.2.5) 56(84) bytes of data.
64 bytes from 10.0.2.5: icmp_seq=1 ttl=128 time=0.898 ms
64 bytes from 10.0.2.5: icmp_seq=2 ttl=128 time=0.946 ms

^C 

--- 10.0.2.5 ping statistics --- 
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.898/0.922/0.946/0.024 ms
  1. 如果 ping 操作不起作用,请返回到先决条件,并确保 VM 位于有权访问 Microsoft Entra 租户的 VNET 上。

  2. 如果 IP 地址正在执行 ping 操作,但未自动发现 DNS 服务器,则可以手动添加 DNS 服务器。 使用常用文本编辑器编辑 /etc/netplan/50-cloud-init.yaml

# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        eth0:
            dhcp4: true
            dhcp4-overrides:
                route-metric: 100
            dhcp6: false
            match:
                macaddress: 00:22:48:03:6b:c5
            set-name: eth0
            nameservers:
                addresses: [10.0.2.5, 10.0.2.4]
    version: 2

然后应用更改:

sudo netplan --debug apply 
  1. Winbind 假定 DHCP 服务器使域 DNS 记录保持最新。 但是,这并不适用于 Azure DHCP。 若要将客户端设置为进行 DDNS 更新,请使用本指南创建网络脚本。 下面是位于 /etc/dhcp/dhclient-exit-hooks.d/ddns-update 的示例脚本。
#!/bin/sh 

# only execute on the primary nic
if [ "$interface" != "eth0" ]
then
    return
fi 

# When you have a new IP, perform nsupdate
if [ "$reason" = BOUND ] || [ "$reason" = RENEW ] ||
   [ "$reason" = REBIND ] || [ "$reason" = REBOOT ]
then
   host=`hostname -f`
   nsupdatecmds=/var/tmp/nsupdatecmds
     echo "update delete $host a" > $nsupdatecmds
     echo "update add $host 3600 a $new_ip_address" >> $nsupdatecmds
     echo "send" >> $nsupdatecmds

     nsupdate $nsupdatecmds
fi 

连接到 Microsoft Entra 域服务并确保服务可发现

  1. 确保能够按域名对域服务器执行 ping 操作。
ping contosodomain.contoso.com
PING contosodomain.contoso.com (10.0.2.4) 56(84) bytes of data.
64 bytes from pwe-oqarc11l568.internal.chinacloudapp.cn (10.0.2.4): icmp_seq=1 ttl=128 time=1.41 ms
64 bytes from pwe-oqarc11l568.internal.chinacloudapp.cn (10.0.2.4): icmp_seq=2 ttl=128 time=1.02 ms
64 bytes from pwe-oqarc11l568.internal.chinacloudapp.cn (10.0.2.4): icmp_seq=3 ttl=128 time=0.740 ms
64 bytes from pwe-oqarc11l568.internal.chinacloudapp.cn (10.0.2.4): icmp_seq=4 ttl=128 time=0.925 ms 

^C 

--- contosodomain.contoso.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3016ms
rtt min/avg/max/mdev = 0.740/1.026/1.419/0.248 ms 
  1. 确保可以在网络上发现 Microsoft Entra 服务。
nslookup
> set type=SRV
> _ldap._tcp.contosodomain.contoso.com.
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer: 

_ldap._tcp.contosodomain.contoso.com service = 0 100 389 pwe-oqarc11l568.contosodomain.contoso.com.
_ldap._tcp.contosodomain.contoso.com service = 0 100 389 hxt4yo--jb9q529.contosodomain.contoso.com. 

设置主机名和完全限定的域名 (FQDN)

  1. 使用文本编辑器,使用最终的 FQDN(加入域后)和主机别名更新 /etc/hosts 文件。 IP 地址目前并不重要,因为此行主要用于将短主机名转换为 FQDN。 有关详细信息,请参阅 将 Samba 设置为域成员
127.0.0.1       contosovm.contosodomain.contoso.com contosovm
#cmd=sudo vim /etc/hosts   
#then enter this value instead of localhost "ubuntvm.contosodomain.contoso.com UbuntuVM" 
  1. 现在,主机名应解析。 暂时可以忽略它解析到的 IP 地址。 短主机名应解析为 FQDN。
getent hosts contosovm
127.0.0.1       contosovm.contosodomain.contoso.com contosovm
dnsdomainname
contosodomain.contoso.com
hostname -f
contosovm.contosodomain.contoso.com 

备注

某些发行版要求你运行 hostnamectl 命令以更新主机名 -f:

hostnamectl set-hostname contosovm.contosodomain.contoso.com

设置 krb5.conf

  1. 配置 /etc/krb5.conf,以便联系具有域服务器的 Kerberos 密钥分发中心 (KDC) 进行身份验证。 有关详细信息,请参阅 MIT Kerberos 文档。 下面是一个示例 /etc/krb5.conf 文件。
[libdefaults]
        default_realm = CONTOSODOMAIN.CONTOSO.COM
        dns_lookup_realm = false
        dns_lookup_kdc = true

设置 smb.conf

  1. 标识 smb.conf 的路径。
sudo smbd -b | grep "CONFIGFILE"
   CONFIGFILE: /etc/samba/smb.conf
  1. 更改 SMB 配置以充当域成员。 有关详细信息,请参阅将 samba 设置为域成员。 下面是一个示例 smb.conf 文件。

备注

此示例适用于 Microsoft Entra 域服务,我们建议在配置 idmap 时设置 backend = rid。 本地 AD DS 用户可能更愿意选择不同的 idmap 后端

[global]
   workgroup = CONTOSODOMAIN
   security = ADS
   realm = CONTOSODOMAIN.CONTOSO.COM

   winbind refresh tickets = Yes
   vfs objects = acl_xattr
   map acl inherit = Yes
   store dos attributes = Yes

   dedicated keytab file = /etc/krb5.keytab
   kerberos method = secrets and keytab

   winbind use default domain = Yes 

   load printers = No
   printing = bsd
   printcap name = /dev/null
   disable spoolss = Yes

   log file = /var/log/samba/log.%m
   log level = 1

   idmap config * : backend = tdb
   idmap config * : range = 3000-7999

   idmap config CONTOSODOMAIN : backend = rid
   idmap config CONTOSODOMAIN : range = 10000-999999

   template shell = /bin/bash
   template homedir = /home/%U 
  1. 强制 winbind 重新加载更改后的配置文件。
sudo smbcontrol all reload-config

加入域

  1. 使用 net ads join 命令将主机加入 Microsoft Entra 域服务的域。 如果该命令引发错误,请参阅 Samba 域成员疑难解答以解决问题。
sudo net ads join -U contososmbadmin    # user  - garead

Enter contososmbadmin's password:
Using short domain name -- CONTOSODOMAIN
Joined 'CONTOSOVM' to dns domain 'contosodomain.contoso.com' 
  1. 确保域服务器上存在此主机的 DNS 记录。
nslookup contosovm.contosodomain.contoso.com 10.0.2.5
Server:         10.0.2.5
Address:        10.0.2.5#53

Name:   contosovm.contosodomain.contoso.com
Address: 10.0.0.8

如果计划用户主动登录到客户端计算机并访问 Azure 文件共享,则需要 设置 nsswitch.conf 并为 winbind 配置 PAM。 如果计划内访问仅限于需要 Kerberos 身份验证才能访问文件共享的用户帐户或计算机帐户表示的应用程序,则可以跳过这些步骤。

设置 nsswitch.conf

  1. 现在主机已加入域,你需要将 winbind 库置于查找用户和组时要查找的位置。 使用文本编辑器编辑 /etc/nsswitch.conf 并添加以下条目:
passwd:         compat systemd winbind
group:          compat systemd winbind
  1. 使 winbind 服务在重启时自动启动。
sudo systemctl enable winbind
Synchronizing state of winbind.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable winbind
  1. 然后重启该服务。
sudo systemctl restart winbind
sudo systemctl status winbind
winbind.service - Samba Winbind Daemon
   Loaded: loaded (/lib/systemd/system/winbind.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-04-24 09:34:31 UTC; 10s ago
     Docs: man:winbindd(8)
           man:samba(7)
           man:smb.conf(5)
 Main PID: 27349 (winbindd)
   Status: "winbindd: ready to serve connections..."
    Tasks: 2 (limit: 4915)
   CGroup: /system.slice/winbind.service
           ├─27349 /usr/sbin/winbindd --foreground --no-process-group
           └─27351 /usr/sbin/winbindd --foreground --no-process-group

Apr 24 09:34:31 contosovm systemd[1]: Starting Samba Winbind Daemon...
Apr 24 09:34:31 contosovm winbindd[27349]: [2020/04/24 09:34:31.724211,  0] ../source3/winbindd/winbindd_cache.c:3170(initialize_winbindd_cache)
Apr 24 09:34:31 contosovm winbindd[27349]:   initialize_winbindd_cache: clearing cache and re-creating with version number 2
Apr 24 09:34:31 contosovm winbindd[27349]: [2020/04/24 09:34:31.725486,  0] ../lib/util/become_daemon.c:124(daemon_ready)
Apr 24 09:34:31 contosovm systemd[1]: Started Samba Winbind Daemon.
Apr 24 09:34:31 contosovm winbindd[27349]:   STATUS=daemon 'winbindd' finished starting up and ready to serve connections 
  1. 确保已发现域用户和组。
getent passwd contososmbadmin
contososmbadmin:*:12604:10513::/home/contososmbadmin:/bin/bash
getent group 'domain users'
domain users:x:10513: 

如果上述操作不起作用,请检查是否可以使用 wbinfo 工具访问域控制器:

wbinfo --ping-dc

为 winbind 配置 PAM

  1. 需要将 winbind 置于在身份验证堆栈中,以便通过为 winbind 配置 PAM(可插入身份验证模块),通过 winbind 对域用户进行身份验证。 第二个命令确保在首次登录该系统时为域用户创建 homedir。
sudo pam-auth-update --enable winbind
sudo pam-auth-update --enable mkhomedir 
  1. 确保 PAM 身份验证配置在 /etc/pam.d/common-auth 中具有以下参数:
grep pam_winbind.so /etc/pam.d/common-auth
auth    [success=1 default=ignore]      pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass 
  1. 你现在应该能够通过 ssh、su 或任何其他身份验证方式,以域用户身份登录到该系统。
su - contososmbadmin
Password:
Creating directory '/home/contososmbadmin'.
contososmbadmin@contosovm:~$ pwd
/home/contososmbadmin
contososmbadmin@contosovm:~$ id
uid=12604(contososmbadmin) gid=10513(domain users) groups=10513(domain users),10520(group policy creator owners),10572(denied rodc password replication group),11102(dnsadmins),11104(aad dc administrators),11164(group-readwrite),11165(fileshareallaccess),12604(contososmbadmin) 

验证配置

若要验证客户端计算机是否已加入域,请在域控制器上查找客户端的 FQDN,并找到为此特定客户端列出的 DNS 条目。 在许多情况下,<dnsserver> 与客户端加入的域名相同。

nslookup <clientname> <dnsserver>

接下来,使用 klist 命令查看 Kerberos 缓存中的票证。 应该有一个以 krbtgt 开头的条目,如下所示:

krbtgt/CONTOSODOMAIN.CONTOSO.COM@CONTOSODOMAIN.CONTOSO.COM

如果未为 winbind 配置 PAM,则 klist 可能不会显示票证条目。 在这种情况下,可以手动对用户进行身份验证以获取票证:

wbinfo -K contososmbadmin

还可以将命令作为脚本的一部分运行:

wbinfo -K 'contososmbadmin%SUPERSECRETPASSWORD'

装载文件共享

启用 AD(或 Microsoft Entra ID)Kerberos 身份验证并将 Linux VM 加入域后,可以装载文件共享。

将以下装载选项用于所有访问控制模型以启用 Kerberos 安全性: sec=krb5 在使用 sec=krb5 时,必须省略用户名和密码。 例如:

sudo mount -t cifs $SMB_PATH $MNT_PATH -o sec=krb5,cruid=$UID,serverino,nosharesock,actimeo=30,mfsymlinks

备注

此功能仅支持使用不带模式位的 NT ACL 的服务器强制访问控制模型。 更新 NT ACL 的 Linux 工具很少,因此通过 Windows 更新 ACL。 目前不支持客户端强制访问控制 (modefromsid,idsfromsid) 和客户端转换访问控制 (cifsacl) 模型。

其他装载选项

单用户装载与多用户装载

在单用户装载用例中,装载点由 AD 域的单个用户访问,不与域的其他用户共享。 每次文件访问都发生在其 krb5 凭据用于装载文件共享的用户的上下文中。 在本地系统中访问挂载点的任何用户都会冒充该用户。

在多用户装载用例中,仍有单个装载点,但多个 AD 用户可以访问同一装载点。 如果同一客户端上的多个用户访问同一共享,并且系统针对 Kerberos 配置并使用 sec=krb5 装载,请考虑使用 multiuser 装载选项。

文件权限

文件权限很重要,尤其是在 Linux 和 Windows 客户端都访问文件共享时。 若要将文件权限转换为文件的 DACL,请使用默认装载选项,例如 file_mode=<>,dir_mode=<>。 指定为 file_modedir_mode 的文件权限仅在客户端中强制执行。 服务器根据文件或目录的安全描述符强制实施访问控制。

“文件所有权”

文件所有权很重要,尤其是在 Linux 和 Windows 客户端都访问文件共享时。 选择以下装载选项之一,将文件所有权 UID/GID 转换为文件 DACL 上的所有者/组 SID:

  • 使用默认值,例如 uid=<>,gid=<>
  • 通过 RFC2307 和 Active Directory(nss_winbindnss_sssd)配置 UID/GID 映射

文件属性缓存一致性

性能非常重要,即使文件属性并不总是准确的。 actimeo 的默认值为 1(秒),这意味着如果缓存的属性超过 1 秒,则会再次从服务器获取文件属性。 将值增加到 60 意味着属性至少缓存 1 分钟。 对于大多数用例,建议对此选项使用值 30 (actimeo=30)。

对于较新的内核,请考虑更精细地设置 actimeo 功能。 可以将 acdirmax 用于目录条目重新验证高速缓存,将 acregmax 用于缓存文件元数据,例如 acdirmax=60,acregmax=5

下一步

有关如何在 Linux 上装载 SMB 文件共享的详细信息,请参阅: