Use Azure Files with Linux
Azure Files is Microsoft's easy to use cloud file system. Azure file shares can be mounted in Linux distributions using the SMB kernel client. This article shows two ways to mount an Azure file share: on-demand with the mount
command and on-boot by creating an entry in /etc/fstab
.
The recommended way to mount an Azure file share on Linux is using SMB 3.0. By default, Azure Files requires encryption in transit, which is only supported by SMB 3.0. Azure Files also supports SMB 2.1, which does not support encryption in transit, but you may not mount Azure file shares with SMB 2.1 from another Azure region or on-premises for security reasons. Unless your application specifically requires SMB 2.1, there is little reason to use it since most popular, recently released Linux distributions support SMB 3.0:
Linux distribution | SMB 2.1 (Mounts on VMs within same Azure region) |
SMB 3.0 (Mounts from on premises and cross-region) |
---|---|---|
Ubuntu | 14.04+ | 16.04+ |
Red Hat Enterprise Linux (RHEL) | 7+ | 7.5+ |
CentOS | 7+ | 7.5+ |
Debian | 8+ | 10+ |
openSUSE | 13.2+ | 42.3+ |
SUSE Linux Enterprise Server | 12+ | 12 SP2+ |
If you're using a Linux distribution not listed in the above table, you can check to see if your Linux distribution supports SMB 3.0 with encryption by checking the Linux kernel version. SMB 3.0 with encryption was added to Linux kernel version 4.11. The uname
command will return the version of the Linux kernel in use:
uname -r
Prerequisites
Ensure the cifs-utils package is installed.
The cifs-utils package can be installed using the package manager on the Linux distribution of your choice.On Ubuntu and Debian-based distributions, use the
apt
package manager:sudo apt update sudo apt install cifs-utils
On Fedora, Red Hat Enterprise Linux 8+, and CentOS 8 +, use the
dnf
package manager:sudo dnf install cifs-utils
On older versions of Red Hat Enterprise Linux and CentOS, use the
yum
package manager:sudo yum install cifs-utils
On openSUSE, use the
zypper
package manager:sudo zypper install cifs-utils
On other distributions, use the appropriate package manager or compile from source
The most recent version of the Azure Command Line Interface (CLI). For more information on how to install the Azure CLI, see Install the Azure CLI and select your operating system. If you prefer to use the Azure PowerShell module in PowerShell 6+, you may, however the instructions below are presented for the Azure CLI.
Ensure port 445 is open: SMB communicates over TCP port 445 - check to see if your firewall is not blocking TCP ports 445 from client machine. Replace
<your-resource-group>
and<your-storage-account>
then run the following script:resourceGroupName="<your-resource-group>" storageAccountName="<your-storage-account>" # This command assumes you have logged in with az login httpEndpoint=$(az storage account show \ --resource-group $resourceGroupName \ --name $storageAccountName \ --query "primaryEndpoints.file" | tr -d '"') smbPath=$(echo $httpEndpoint | cut -c7-$(expr length $httpEndpoint)) fileHost=$(echo $smbPath | tr -d "/") nc -zvw3 $fileHost 445
If the connection was successful, you should see something similar to the following output:
Connection to <your-storage-account> 445 port [tcp/microsoft-ds] succeeded!
If you are unable to open up port 445 on your corporate network or are blocked from doing so by an ISP, you may use a VPN connection or ExpressRoute to work around port 445. For more information, see Networking considerations for direct Azure file share access..
Mounting Azure file share
To use an Azure file share with your Linux distribution, you must create a directory to serve as the mount point for the Azure file share. A mount point can be created anywhere on your Linux system, but it's common convention to create this under /mnt. After the mount point, you use the mount
command to access the Azure file share.
You can mount the same Azure file share to multiple mount points if desired.
Mount the Azure file share on-demand with mount
Create a folder for the mount point: Replace
<your-resource-group>
,<your-storage-account>
, and<your-file-share>
with the appropriate information for your environment:resourceGroupName="<your-resource-group>" storageAccountName="<your-storage-account>" fileShareName="<your-file-share>" mntPath="/mnt/$storageAccountName/$fileShareName" sudo mkdir -p $mntPath
Use the mount command to mount the Azure file share. In the example below, the local Linux file and folder permissions default 0755, which means read, write, and execute for the owner (based on the file/directory Linux owner), read and execute for users in owner group, and read and execute for others on the system. You can use the
uid
andgid
mount options to set the user ID and group ID for the mount. You can also usedir_mode
andfile_mode
to set custom permissions as desired. For more information on how to set permissions, see UNIX numeric notation on Wikipedia.# This command assumes you have logged in with az login httpEndpoint=$(az storage account show \ --resource-group $resourceGroupName \ --name $storageAccountName \ --query "primaryEndpoints.file" | tr -d '"') smbPath=$(echo $httpEndpoint | cut -c7-$(expr length $httpEndpoint))$fileShareName storageAccountKey=$(az storage account keys list \ --resource-group $resourceGroupName \ --account-name $storageAccountName \ --query "[0].value" | tr -d '"') sudo mount -t cifs $smbPath $mntPath -o vers=3.0,username=$storageAccountName,password=$storageAccountKey,serverino
Note
The above mount command mounts with SMB 3.0. If your Linux distribution does not support SMB 3.0 with encryption or if it only supports SMB 2.1, you may only mount from an Azure VM within the same region as the storage account. To mount your Azure file share on a Linux distribution that does not support SMB 3.0 with encryption, you will need to disable encryption in transit for the storage account.
When you are done using the Azure file share, you may use sudo umount $mntPath
to unmount the share.
Create a persistent mount point for the Azure file share with /etc/fstab
Create a folder for the mount point: A folder for a mount point can be created anywhere on the file system, but it's common convention to create this under /mnt. For example, the following command creates a new directory, replace
<your-resource-group>
,<your-storage-account>
, and<your-file-share>
with the appropriate information for your environment:resourceGroupName="<your-resource-group>" storageAccountName="<your-storage-account>" fileShareName="<your-file-share>" mntPath="/mnt/$storageAccountName/$fileShareName" sudo mkdir -p $mntPath
Create a credential file to store the username (the storage account name) and password (the storage account key) for the file share.
if [ ! -d "/etc/smbcredentials" ]; then sudo mkdir "/etc/smbcredentials" fi storageAccountKey=$(az storage account keys list \ --resource-group $resourceGroupName \ --account-name $storageAccountName \ --query "[0].value" | tr -d '"') smbCredentialFile="/etc/smbcredentials/$storageAccountName.cred" if [ ! -f $smbCredentialFile ]; then echo "username=$storageAccountName" | sudo tee $smbCredentialFile > /dev/null echo "password=$storageAccountKey" | sudo tee -a $smbCredentialFile > /dev/null else echo "The credential file $smbCredentialFile already exists, and was not modified." fi
Change permissions on the credential file so only root can read or modify the password file. Since the storage account key is essentially a super-administrator password for the storage account, setting the permissions on the file such that only root can access is important so that lower privilege users cannot retrieve the storage account key.
sudo chmod 600 $smbCredentialFile
Use the following command to append the following line to
/etc/fstab
: In the example below, the local Linux file and folder permissions default 0755, which means read, write, and execute for the owner (based on the file/directory Linux owner), read and execute for users in owner group, and read and execute for others on the system. You can use theuid
andgid
mount options to set the user ID and group ID for the mount. You can also usedir_mode
andfile_mode
to set custom permissions as desired. For more information on how to set permissions, see UNIX numeric notation on Wikipedia.# This command assumes you have logged in with az login httpEndpoint=$(az storage account show \ --resource-group $resourceGroupName \ --name $storageAccountName \ --query "primaryEndpoints.file" | tr -d '"') smbPath=$(echo $httpEndpoint | cut -c7-$(expr length $httpEndpoint))$fileShareName if [ -z "$(grep $smbPath\ $mntPath /etc/fstab)" ]; then echo "$smbPath $mntPath cifs nofail,vers=3.0,credentials=$smbCredentialFile,serverino" | sudo tee -a /etc/fstab > /dev/null else echo "/etc/fstab was not modified to avoid conflicting entries as this Azure file share was already present. You may want to double check /etc/fstab to ensure the configuration is as desired." fi sudo mount -a
Note
The above mount command mounts with SMB 3.0. If your Linux distribution does not support SMB 3.0 with encryption or if it only supports SMB 2.1, you may only mount from an Azure VM within the same region as the storage account. To mount your Azure file share on a Linux distribution that does not support SMB 3.0 with encryption, you will need to disable encryption in transit for the storage account.
Using autofs to automatically mount the Azure file share(s)
Ensure the autofs package is installed.
The autofs package can be installed using the package manager on the Linux distribution of your choice.
On Ubuntu and Debian-based distributions, use the
apt
package manager:sudo apt update sudo apt install autofs
On Fedora, Red Hat Enterprise Linux 8+, and CentOS 8 +, use the
dnf
package manager:sudo dnf install autofs
On older versions of Red Hat Enterprise Linux and CentOS, use the
yum
package manager:sudo yum install autofs
On openSUSE, use the
zypper
package manager:sudo zypper install autofs
Create a mount point for the share(s):
sudo mkdir /fileshares
Crete a new custom autofs configuration file
sudo vi /etc/auto.fileshares
Add the following entries to /etc/auto.fileshares
echo "$fileShareName -fstype=cifs,credentials=$smbCredentialFile :$smbPath"" > /etc/auto.fileshares
Add the following entry to /etc/auto.master
/fileshares /etc/auto.fileshares --timeout=60
Restart autofs
sudo systemctl restart autofs
Access the folder designated for the share
cd /fileshares/$filesharename
Securing Linux
In order to mount an Azure file share on Linux, port 445 must be accessible. Many organizations block port 445 because of the security risks inherent with SMB 1. SMB 1, also known as CIFS (Common Internet File System), is a legacy file system protocol included with many Linux distributions. SMB 1 is an outdated, inefficient, and most importantly insecure protocol. The good news is that Azure Files does not support SMB 1, and starting with Linux kernel version 4.18, Linux makes it possible to disable SMB 1. We always strongly recommend disabling the SMB 1 on your Linux clients before using SMB file shares in production.
Starting with Linux kernel 4.18, the SMB kernel module, called cifs
for legacy reasons, exposes a new module parameter (often referred to as parm by various external documentations), called disable_legacy_dialects
. Although introduced in Linux kernel 4.18, some vendors have backported this change to older kernels that they support. For convenience, the following table details the availability of this module parameter on common Linux distributions.
Distribution | Can disable SMB 1 |
---|---|
Ubuntu 14.04-16.04 | No |
Ubuntu 18.04 | Yes |
Ubuntu 19.04+ | Yes |
Debian 8-9 | No |
Debian 10+ | Yes |
Fedora 29+ | Yes |
CentOS 7 | No |
CentOS 8+ | Yes |
Red Hat Enterprise Linux 6.x-7.x | No |
Red Hat Enterprise Linux 8+ | Yes |
openSUSE Leap 15.0 | No |
openSUSE Leap 15.1+ | Yes |
openSUSE Tumbleweed | Yes |
SUSE Linux Enterprise 11.x-12.x | No |
SUSE Linux Enterprise 15 | No |
SUSE Linux Enterprise 15.1 | No |
You can check to see if your Linux distribution supports the disable_legacy_dialects
module parameter via the following command.
sudo modinfo -p cifs | grep disable_legacy_dialects
This command should output the following message:
disable_legacy_dialects: To improve security it may be helpful to restrict the ability to override the default dialects (SMB2.1, SMB3 and SMB3.02) on mount with old dialects (CIFS/SMB1 and SMB2) since vers=1.0 (CIFS/SMB1) and vers=2.0 are weaker and less secure. Default: n/N/0 (bool)
Before disabling SMB 1, you must check to make sure that the SMB module is not currently loaded on your system (this happens automatically if you have mounted an SMB share). You can do this with the following command, which should output nothing if SMB is not loaded:
lsmod | grep cifs
To unload the module, first unmount all SMB shares (using the umount
command as described above). You can identify all the mounted SMB shares on your system with the following command:
mount | grep cifs
Once you have unmounted all SMB file shares, it's safe to unload the module. You can do this with the modprobe
command:
sudo modprobe -r cifs
You can manually load the module with SMB 1 unloaded using the modprobe
command:
sudo modprobe cifs disable_legacy_dialects=Y
Finally, you can check the SMB module has been loaded with the parameter by looking at the loaded parameters in /sys/module/cifs/parameters
:
cat /sys/module/cifs/parameters/disable_legacy_dialects
To persistently disable SMB 1 on Ubuntu and Debian-based distributions, you must create a new file (if you don't already have custom options for other modules) called /etc/modprobe.d/local.conf
with the setting. You can do this with the following command:
echo "options cifs disable_legacy_dialects=Y" | sudo tee -a /etc/modprobe.d/local.conf > /dev/null
You can verify that this has worked by loading the SMB module:
sudo modprobe cifs
cat /sys/module/cifs/parameters/disable_legacy_dialects
Next steps
See these links for more information about Azure Files: