Enable Active Directory authentication over SMB for Linux clients accessing Azure Files
For more information on supported options and considerations, see Overview of Azure Files identity-based authentication options for SMB access.
Azure Files supports identity-based authentication over Server Message Block (SMB) for Linux virtual machines (VMs) using the Kerberos authentication protocol through the following methods:
- On-premises Windows Active Directory Domain Services (AD DS)
- Microsoft Entra Domain Services
In order to use AD DS, you must sync your AD DS to Microsoft Entra ID using Microsoft Entra Connect.
Note
This article uses Ubuntu for the example steps. Similar configurations will work for SLES machines, allowing you to mount Azure file shares using Active Directory.
Applies to
File share type | SMB | NFS |
---|---|---|
Standard file shares (GPv2), LRS/ZRS | ||
Standard file shares (GPv2), GRS/GZRS | ||
Premium file shares (FileStorage), LRS/ZRS |
Linux SMB client limitations
You can't use identity-based authentication to mount Azure File shares on Linux clients at boot time using fstab
entries because the client can't get the Kerberos ticket early enough to mount at boot time. However, you can use an fstab
entry and specify the noauto
option. This won't mount the share at boot time, but it will allow a user to conveniently mount the file share after they log in using a simple mount command without all the parameters. You can also use autofs
to mount the share upon access.
Prerequisites
Before you enable AD authentication over SMB for Azure file shares, make sure you've completed the following prerequisites.
- A Linux VM running Ubuntu 18.04+, or an equivalent SLES VM. If running on Azure, the VM must have at least one network interface on the VNET containing Microsoft Entra Domain Services. If using an on-premises VM, your AD DS must be synced to Microsoft Entra ID.
- Root user or user credentials to a local user account that has full sudo rights (for this guide, localadmin).
- The Linux VM must not have joined any AD domain. If it's already a part of a domain, it must first leave that domain before it can join this domain.
- A Microsoft Entra tenant fully configured, with domain user already set up.
Installing the samba package isn't strictly necessary, but it gives you some useful tools and brings in other packages automatically, such as samba-common
and smbclient
. Run the following commands to install it. If you're asked for any input values during installation, leave them blank.
sudo apt update -y
sudo apt install samba winbind libpam-winbind libnss-winbind krb5-config krb5-user keyutils cifs-utils
The wbinfo
tool is part of the samba suite. It can be useful for authentication and debugging purposes, such as checking if the domain controller is reachable, checking what domain a machine is joined to, and finding information about users.
Make sure that the Linux host keeps the time synchronized with the domain server. Refer to the documentation for your Linux distribution. For some distros, you can do this using systemd-timesyncd. Edit /etc/systemd/timesyncd.conf
with your favorite text editor to include the following:
[Time]
NTP=onpremaadint.com
FallbackNTP=ntp.ubuntu.com
Then restart the service:
sudo systemctl restart systemd-timesyncd.service
Enable AD Kerberos authentication
Follow these steps to enable AD Kerberos authentication. This Samba documentation might be helpful as a reference.
Make sure the domain server is reachable and discoverable
- Make sure that the DNS servers supplied contain the domain server IP addresses.
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
If the command worked, skip the following steps and proceed to the next section.
If it didn't work, make sure that the domain server IP addresses are pinging.
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
If the ping doesn't work, go back to prerequisites, and make sure that your VM is on a VNET that has access to the Microsoft Entra tenant.
If the IP addresses are pinging but the DNS servers aren't automatically discovered, you can add the DNS servers manually. Edit
/etc/netplan/50-cloud-init.yaml
with your favorite text editor.
# 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
Then apply the changes:
sudo netplan --debug apply
- Winbind assumes that the DHCP server keeps the domain DNS records up-to-date. However, this isn't true for Azure DHCP. In order to set up the client to make DDNS updates, use this guide to create a network script. Here's a sample script that lives at
/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
Connect to Microsoft Entra Domain Services and make sure the services are discoverable
- Make sure that you're able to ping the domain server by the domain name.
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
- Make sure you can discover the Microsoft Entra services on the network.
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.
Set up hostname and fully qualified domain name (FQDN)
- Using your text editor, update the
/etc/hosts
file with the final FQDN (after joining the domain) and the alias for the host. The IP address doesn't matter for now because this line will mainly be used to translate short hostname to FQDN. For more details, see Setting up Samba as a Domain Member.
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"
- Now, your hostname should resolve. You can ignore the IP address it resolves to for now. The short hostname should resolve to the FQDN.
getent hosts contosovm
127.0.0.1 contosovm.contosodomain.contoso.com contosovm
dnsdomainname
contosodomain.contoso.com
hostname -f
contosovm.contosodomain.contoso.com
Note
Some distros require you to run the hostnamectl
command in order for hostname -f to be updated:
hostnamectl set-hostname contosovm.contosodomain.contoso.com
Set up krb5.conf
- Configure
/etc/krb5.conf
so that the Kerberos key distribution center (KDC) with the domain server can be contacted for authentication. For more information, see MIT Kerberos Documentation. Here's a sample/etc/krb5.conf
file.
[libdefaults]
default_realm = CONTOSODOMAIN.CONTOSO.COM
dns_lookup_realm = false
dns_lookup_kdc = true
Set up smb.conf
- Identify the path to
smb.conf
.
sudo smbd -b | grep "CONFIGFILE"
CONFIGFILE: /etc/samba/smb.conf
- Change the SMB configuration to act as a domain member. For more information, see Setting up samba as a domain member. Here's a sample
smb.conf
file.
Note
This example is for Microsoft Entra Domain Services, for which we recommend setting backend = rid
when configuring idmap. On-premises AD DS users might prefer to choose a different idmap backend.
[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
- Force winbind to reload the changed config file.
sudo smbcontrol all reload-config
Join the domain
- Use the
net ads join
command to join the host to the Microsoft Entra Domain Services domain. If the command throws an error, see Troubleshooting samba domain members to resolve the issue.
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'
- Make sure that the DNS record exists for this host on the domain server.
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
If users will be actively logging into client machines or VMs and accessing the Azure file shares, you need to set up nsswitch.conf and configure PAM for winbind. If access will be limited to applications represented by a user account or computer account that need Kerberos authentication to access the file share, then you can skip these steps.
Set up nsswitch.conf
- Now that the host is joined to the domain, you need to put winbind libraries in the places to look for when looking for users and groups. Do this by updating the passwd and group entries in
nsswitch.conf
. Use your text editor to edit/etc/nsswitch.conf
and add the following entries:
passwd: compat systemd winbind
group: compat systemd winbind
- Enable the winbind service to start automatically on reboot.
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
- Then, restart the service.
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
- Make sure that the domain users and groups are discovered.
getent passwd contososmbadmin
contososmbadmin:*:12604:10513::/home/contososmbadmin:/bin/bash
getent group 'domain users'
domain users:x:10513:
If the above doesn't work, check if the domain controller is reachable using the wbinfo tool:
wbinfo --ping-dc
Configure PAM for winbind
- You need to place winbind in the authentication stack so that domain users are authenticated through winbind by configuring PAM (Pluggable Authentication Module) for winbind. The second command ensures that the homedir gets created for a domain user upon first login to this system.
sudo pam-auth-update --enable winbind
sudo pam-auth-update --enable mkhomedir
- Ensure that the PAM authentication config has the following arguments in
/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
- You should now be able to log in to this system as the domain user, either through ssh, su, or any other means of authentication.
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)
Verify configuration
To verify that the client machine is joined to the domain, look up the FQDN of the client on the domain controller and find the DNS entry listed for this particular client. In many cases, <dnsserver>
is the same as the domain name that the client is joined to.
nslookup <clientname> <dnsserver>
Next, use the klist
command to view the tickets in the Kerberos cache. There should be an entry beginning with krbtgt
that looks similar to:
krbtgt/CONTOSODOMAIN.CONTOSO.COM@CONTOSODOMAIN.CONTOSO.COM
If you didn't configure PAM for winbind, klist
might not show the ticket entry. In this case, you can manually authenticate the user to get the tickets:
wbinfo -K contososmbadmin
You can also run the command as a part of a script:
wbinfo -K 'contososmbadmin%SUPERSECRETPASSWORD'
Mount the file share
After you've enabled AD (or Microsoft Entra ID) Kerberos authentication and domain-joined your Linux VM, you can mount the file share.
For detailed mounting instructions, see Mount the Azure file share on-demand with mount.
Use the following additional mount option with all access control models to enable Kerberos security: sec=krb5
. Username and password must be omitted when sec=krb5 is in use.
Note
This feature only supports a server-enforced access control model using NT ACLs with no mode bits. Linux tools that update NT ACLs are minimal, so update ACLs through Windows. Client-enforced access control (modefromsid,idsfromsid
) and client-translated access control (cifsacl
) models aren't currently supported.
Other mount options
Single-user versus multi-user mount
In a single-user mount use case, the mount point is accessed by a single user of the AD domain and isn't shared with other users of the domain. Each file access happens in the context of the user whose krb5 credentials were used to mount the file share. Any user on the local system who accesses the mount point will impersonate that user.
In a multi-user mount use case, there's still a single mount point, but multiple AD users can access that same mount point. In scenarios where multiple users on the same client will access the same share, and the system is configured for Kerberos and mounted with sec=krb5
, consider using the multiuser
mount option.
File permissions
File permissions matter, especially if both Linux and Windows clients will access the file share. To convert file permissions to DACLs on files, use a default mount option such as file_mode=<>,dir_mode=<>. File permissions specified as file_mode and dir_mode are only enforced within the client. The server enforces access control based on the file's or directory's security descriptor.
File ownership
File ownership matters, especially if both Linux and Windows clients will access the file share. Choose one of the following mount options to convert file ownership UID/GID to owner/group SID on file DACL:
- Use a default such as uid=<>,gid=<>
- Configure UID/GID mapping via RFC2307 and Active Directory (nss_winbind or nss_sssd)
File attribute cache coherency
Performance is important, even if file attributes aren't always accurate. The default value for actimeo is 1 (second), which means that the file attributes are fetched again from the server if the cached attributes are more than 1 second old. Increasing the value to 60 means that attributes are cached for at least 1 minute. For most use cases, we recommend using a value of 30 for this option (actimeo=30).
For newer kernels, consider setting the actimeo features more granularly. You can use acdirmax for directory entry revalidation caching and acregmax for caching file metadata, for example acdirmax=60,acregmax=5.
Next step
For more information on how to mount an SMB file share on Linux, see: