Skip to content

Commit b52bd5e

Browse files
authored
Merge pull request #310753 from khdownie/kendownie012126-4
Retrieval risk fixes for AI readiness
2 parents f92b532 + e56371c commit b52bd5e

1 file changed

Lines changed: 98 additions & 29 deletions

File tree

articles/storage/files/storage-files-configure-p2s-vpn-linux.md

Lines changed: 98 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Learn how to configure a point-to-site virtual private network (VPN
44
author: khdownie
55
ms.service: azure-file-storage
66
ms.topic: how-to
7-
ms.date: 01/14/2026
7+
ms.date: 01/21/2026
88
ms.author: kendownie
99
ms.custom:
1010
- devx-track-azurecli
@@ -15,11 +15,11 @@ ms.custom:
1515

1616
# Configure a point-to-site VPN on Linux for use with Azure Files
1717

18-
You can use a point-to-site virtual private network (VPN) connection to mount your Azure file shares from outside of Azure, without sending data over the open internet. A point-to-site VPN connection is a VPN connection between Azure and an individual client. To use a point-to-site VPN connection with Azure Files, you need to configure a point-to-site VPN connection for each client that wants to connect. If you have many clients that need to connect to your Azure file shares from your on-premises network, you can use a site-to-site VPN connection instead of a point-to-site connection for each client. To learn more, see [Configure a site-to-site VPN for use with Azure Files](storage-files-configure-s2s-vpn.md).
18+
You can use a point-to-site virtual private network (VPN) connection to mount your Azure file shares from outside of Azure, without sending data over the open internet. A point-to-site VPN connection is a VPN connection between Azure and an individual client machine. To use a point-to-site VPN connection with Azure Files, you need to configure a point-to-site VPN connection for each client machine that wants to connect. If you have many client machines that need to connect to your Azure file shares from your on-premises network, you can use a site-to-site VPN connection instead of a point-to-site connection for each client machine. To learn more, see [Configure a site-to-site VPN for use with Azure Files](storage-files-configure-s2s-vpn.md).
1919

20-
We strongly recommend that you read [Azure Files networking overview](storage-files-networking-overview.md) before continuing with this article for a complete discussion of the networking options available for Azure Files.
20+
For a complete discussion of the networking options available for Azure Files, see [Azure Files networking overview](storage-files-networking-overview.md).
2121

22-
The article details the steps to configure a point-to-site VPN on Linux to mount Azure file shares directly on-premises.
22+
This article details the steps to configure a point-to-site VPN on Linux to mount Azure file shares directly on-premises.
2323

2424
## Applies to
2525
| Management model | Billing model | Media tier | Redundancy | SMB | NFS |
@@ -37,23 +37,23 @@ The article details the steps to configure a point-to-site VPN on Linux to mount
3737

3838
## Prerequisites
3939

40-
- The most recent version of the Azure CLI. For information on how to install the Azure CLI, see [Install the Azure CLI](/cli/azure/install-azure-cli) and select your operating system. If you prefer to use the Azure PowerShell module on Linux, you may. However, the instructions below are for Azure CLI.
40+
- The most recent version of the Azure CLI. For information on how to install the Azure CLI, see [Install the Azure CLI](/cli/azure/install-azure-cli) and select your operating system. You can use the Azure PowerShell module on Linux instead, but the instructions in this article are for Azure CLI.
4141

42-
- An Azure file share you'd like to mount on-premises. Azure file shares are deployed within storage accounts, which are management constructs that represent a shared pool of storage in which you can deploy multiple file shares. You can learn more about how to deploy Azure file shares and storage accounts in [Create an Azure file share](storage-how-to-create-file-share.md).
42+
- An Azure file share you intend to mount on-premises. Azure file shares are deployed within storage accounts, which are management constructs that represent a shared pool of storage in which you can deploy multiple file shares. You can learn more about how to deploy Azure file shares and storage accounts in [Create an Azure file share](storage-how-to-create-file-share.md).
4343

4444
- A private endpoint for the storage account containing the Azure file share you want to mount on-premises. To learn how to create a private endpoint, see [Configuring Azure Files network endpoints](storage-files-networking-endpoints.md?tabs=azure-cli).
4545

4646
## Install required software
4747

4848
The Azure virtual network gateway can provide VPN connections using several VPN protocols, including IPsec and OpenVPN. This article shows how to use IPsec and uses the strongSwan package to provide the support on Linux.
4949

50-
> Verified with Ubuntu 18.10.
50+
> [!NOTE]
51+
> These instructions were tested on Ubuntu 18.10 and should work on Ubuntu 18.04 LTS and later, as well as Debian 10+. Other distributions that support strongSwan (such as Fedora, CentOS, or openSUSE) might require different package names or installation commands.
5152
5253
```bash
54+
# For Ubuntu/Debian-based distributions (Ubuntu 18.04+, Debian 10+)
5355
sudo apt update
5456
sudo apt install strongswan strongswan-pki libstrongswan-extra-plugins curl libxml2-utils cifs-utils unzip
55-
56-
INSTALL_DIR="/etc/"
5757
```
5858

5959
If the installation fails or you get an error such as `EAP_IDENTITY not supported, sending EAP_NAK`, you might need to install extra plugins:
@@ -64,24 +64,33 @@ sudo apt install -y libcharon-extra-plugins
6464

6565
### Deploy a virtual network
6666

67-
To access your Azure file share and other Azure resources from on-premises via a point-to-site VPN, you must create a virtual network. You can think of the point-to-site VPN connection as creating a bridge between your on-premises Linux machine and this Azure virtual network.
67+
To access your Azure file share and other Azure resources from on-premises via a point-to-site VPN, you must create a virtual network. The point-to-site VPN connection establishes a secure tunnel between your on-premises Linux client machine and this Azure virtual network.
6868

69-
The following script creates an Azure virtual network with three subnets: one for your storage account's service endpoint, one for your storage account's private endpoint, which is required to access the storage account on-premises without creating custom routing for the public IP of the storage account that may change, and one for your virtual network gateway that provides the VPN service.
70-
71-
Replace `<region>`, `<resource-group>`, and `<desired-vnet-name>` with the appropriate values for your environment.
69+
The following script creates an Azure virtual network with three subnets: one for your storage account's service endpoint, one for your storage account's private endpoint, which is required to access the storage account on-premises without creating custom routing for the public IP of the storage account that may change, and one for your virtual network gateway that provides the VPN service.
7270

7371
```bash
72+
# Variables - replace <region>, <resource-group>, and <desired-vnet-name> with your values
7473
REGION="<region>"
7574
RESOURCE_GROUP_NAME="<resource-group>"
7675
VIRTUAL_NETWORK_NAME="<desired-vnet-name>"
76+
```
77+
78+
Create the virtual network:
7779

80+
```bash
81+
# Requires: REGION, RESOURCE_GROUP_NAME, VIRTUAL_NETWORK_NAME defined above
7882
VIRTUAL_NETWORK=$(az network vnet create \
7983
--resource-group $RESOURCE_GROUP_NAME \
8084
--name $VIRTUAL_NETWORK_NAME \
8185
--location $REGION \
8286
--address-prefixes "192.168.0.0/16" \
8387
--query "newVNet.id" | tr -d '"')
88+
```
89+
90+
Create the subnets for service endpoints, private endpoints, and the gateway:
8491

92+
```bash
93+
# Requires: RESOURCE_GROUP_NAME, VIRTUAL_NETWORK_NAME defined above
8594
SERVICE_ENDPOINT_SUBNET=$(az network vnet subnet create \
8695
--resource-group $RESOURCE_GROUP_NAME \
8796
--vnet-name $VIRTUAL_NETWORK_NAME \
@@ -105,28 +114,41 @@ GATEWAY_SUBNET=$(az network vnet subnet create \
105114
--query "id" | tr -d '"')
106115
```
107116

117+
**Verify:** Run `az network vnet subnet list --resource-group $RESOURCE_GROUP_NAME --vnet-name $VIRTUAL_NETWORK_NAME --output table` and confirm three subnets appear: `ServiceEndpointSubnet`, `PrivateEndpointSubnet`, and `GatewaySubnet`.
118+
108119
## Create certificates for VPN authentication
109120

110-
In order for VPN connections from your on-premises Linux machines to be authenticated to access your virtual network, you must create two certificates:
121+
For VPN connections from your on-premises Linux client machines to authenticate with the virtual network gateway, you must create two certificates:
111122

112123
- A root certificate, which is provided to the virtual machine gateway
113-
- A client certificate, which is signed with the root certificate
124+
- A client certificate, which is signed with the root certificate and installed on each client machine
114125

115-
The following script creates the required certificates.
126+
Set the certificate variables and create a working directory:
116127

117128
```bash
129+
# Variables
118130
ROOT_CERT_NAME="P2SRootCert"
119-
USERNAME="client"
120-
PASSWORD="1234"
131+
USERNAME="client" # Client certificate identity (not a machine login)
132+
PASSWORD="1234" # Password for the client certificate PKCS#12 file
121133

122134
mkdir temp
123135
cd temp
136+
```
124137

138+
Generate the root certificate:
139+
140+
```bash
141+
# Requires: ROOT_CERT_NAME defined above; run from temp directory
125142
sudo ipsec pki --gen --outform pem > rootKey.pem
126143
sudo ipsec pki --self --in rootKey.pem --dn "CN=$ROOT_CERT_NAME" --ca --outform pem > rootCert.pem
127144

128145
ROOT_CERTIFICATE=$(openssl x509 -in rootCert.pem -outform der | base64 -w0 ; echo)
146+
```
129147

148+
Generate the client certificate signed by the root certificate:
149+
150+
```bash
151+
# Requires: USERNAME, PASSWORD defined; rootCert.pem and rootKey.pem from previous step
130152
sudo ipsec pki --gen --size 4096 --outform pem > "clientKey.pem"
131153
sudo ipsec pki --pub --in "clientKey.pem" | \
132154
sudo ipsec pki \
@@ -141,32 +163,45 @@ sudo ipsec pki --pub --in "clientKey.pem" | \
141163
openssl pkcs12 -in "clientCert.pem" -inkey "clientKey.pem" -certfile rootCert.pem -export -out "client.p12" -password "pass:$PASSWORD"
142164
```
143165

144-
## Deploy virtual network gateway
166+
**Verify:** Run `ls -la *.pem client.p12` and confirm five files exist: `rootKey.pem`, `rootCert.pem`, `clientKey.pem`, `clientCert.pem`, and `client.p12`.
145167

146-
The Azure virtual network gateway is the service that your on-premises Linux client connects to. Deploying this service requires two basic components:
168+
## Deploy virtual network gateway
147169

148-
- A public IP address that identifies the gateway to your clients wherever they are in the world.
149-
- The root certificate you created earlier that is used to authenticate your clients
170+
The Azure virtual network gateway is the service that your on-premises Linux client machine connects to. Deploying this service requires two components:
150171

151-
Replace `<desired-vpn-name-here>` with the name you would like for these resources.
172+
- A public IP address that identifies the gateway to your client machines.
173+
- The root certificate you created earlier, which authenticates your client machines using their client certificates.
152174

153175
> [!NOTE]
154-
> Deploying the Azure virtual network gateway can take up to 45 minutes. While this resource is being deployed, this bash script blocks the deployment from being completed.
176+
> Deploying the Azure virtual network gateway can take up to 45 minutes. While this resource is being deployed, this script blocks the deployment from being completed.
155177
>
156-
> Point-to-site IKEv2/OpenVPN connections aren't supported with the **Basic** SKU. This script uses the **VpnGw1** SKU for the virtual network gateway.
178+
> Point-to-site IKEv2/OpenVPN connections aren't supported with the **Basic** gateway SKU. This script uses the **VpnGw1** SKU for the virtual network gateway, which is the minimum required SKU for IKEv2 connections. The public IP address can use the **Basic** SKU with dynamic allocation.
157179
158180
```azurecli
181+
# Variables - replace <desired-vpn-name-here> with your value
159182
VPN_NAME="<desired-vpn-name-here>"
160183
PUBLIC_IP_ADDR_NAME="$VPN_NAME-PublicIP"
184+
```
185+
186+
Create the public IP address for the gateway:
161187

188+
```azurecli
189+
# Requires: RESOURCE_GROUP_NAME, REGION from 'Deploy a virtual network'; VPN_NAME, PUBLIC_IP_ADDR_NAME defined above
190+
# Note: Basic SKU with dynamic allocation is sufficient for the public IP; the gateway SKU (VpnGw1) is what matters for IKEv2 support
162191
PUBLIC_IP_ADDR=$(az network public-ip create \
163192
--resource-group $RESOURCE_GROUP_NAME \
164193
--name $PUBLIC_IP_ADDR_NAME \
165194
--location $REGION \
166195
--sku "Basic" \
167196
--allocation-method "Dynamic" \
168197
--query "publicIp.id" | tr -d '"')
198+
```
169199

200+
Create the virtual network gateway:
201+
202+
```azurecli
203+
# Requires: RESOURCE_GROUP_NAME, REGION, VIRTUAL_NETWORK_NAME from 'Deploy a virtual network'; VPN_NAME, PUBLIC_IP_ADDR defined above
204+
# Note: VpnGw1 is the minimum SKU required for IKEv2/OpenVPN; Basic SKU doesn't support point-to-site IKEv2
170205
az network vnet-gateway create \
171206
--resource-group $RESOURCE_GROUP_NAME \
172207
--name $VPN_NAME \
@@ -178,7 +213,12 @@ az network vnet-gateway create \
178213
--vpn-type "RouteBased" \
179214
--address-prefixes "172.16.201.0/24" \
180215
--client-protocol "IkeV2" > /dev/null
216+
```
181217

218+
Upload the root certificate to the gateway:
219+
220+
```azurecli
221+
# Requires: RESOURCE_GROUP_NAME from 'Deploy a virtual network'; VPN_NAME defined above; ROOT_CERT_NAME, ROOT_CERTIFICATE from 'Create certificates'
182222
az network vnet-gateway root-cert create \
183223
--resource-group $RESOURCE_GROUP_NAME \
184224
--gateway-name $VPN_NAME \
@@ -187,27 +227,47 @@ az network vnet-gateway root-cert create \
187227
--output none
188228
```
189229

230+
**Verify:** Run `az network vnet-gateway show --resource-group $RESOURCE_GROUP_NAME --name $VPN_NAME --query "provisioningState"` and confirm the output is `"Succeeded"`.
231+
190232
## Configure the VPN client
191233

192-
The Azure virtual network gateway creates a downloadable package with configuration files required to initialize the VPN connection on your on-premises Linux machine. The following script places the certificates you created in the correct spot and configures the `ipsec.conf` file with the correct values from the configuration file in the downloadable package.
234+
The Azure virtual network gateway creates a downloadable package with configuration files required to initialize the VPN connection on your on-premises Linux client machine. The following script copies the client certificate to the strongSwan certificate directories (`/etc/ipsec.d/`) and configures the `ipsec.conf` file with the values from the downloaded configuration package.
193235

194236
```azurecli
237+
# Requires: RESOURCE_GROUP_NAME from 'Deploy a virtual network'; VPN_NAME from 'Deploy virtual network gateway'
195238
VPN_CLIENT=$(az network vnet-gateway vpn-client generate \
196239
--resource-group $RESOURCE_GROUP_NAME \
197240
--name $VPN_NAME \
198241
--authentication-method EAPTLS | tr -d '"')
199242
200243
curl $VPN_CLIENT --output vpnClient.zip
201244
unzip vpnClient.zip
245+
```
246+
247+
Extract the VPN configuration values:
202248

249+
```bash
250+
# Requires: vpnClient.zip extracted in current directory
203251
VPN_SERVER=$(xmllint --xpath "string(/VpnProfile/VpnServer)" Generic/VpnSettings.xml)
204252
VPN_TYPE=$(xmllint --xpath "string(/VpnProfile/VpnType)" Generic/VpnSettings.xml | tr '[:upper:]' '[:lower:]')
205253
ROUTES=$(xmllint --xpath "string(/VpnProfile/Routes)" Generic/VpnSettings.xml)
254+
```
255+
256+
Copy certificates to the strongSwan directories:
257+
258+
```bash
259+
# Requires: USERNAME from 'Create certificates'; client.p12 (client certificate) from temp directory
260+
INSTALL_DIR="/etc/"
206261

207262
sudo cp "${INSTALL_DIR}ipsec.conf" "${INSTALL_DIR}ipsec.conf.backup"
208263
sudo cp "Generic/VpnServerRoot.cer_0" "${INSTALL_DIR}ipsec.d/cacerts"
209-
sudo cp "${USERNAME}.p12" "${INSTALL_DIR}ipsec.d/private"
264+
sudo cp "${USERNAME}.p12" "${INSTALL_DIR}ipsec.d/private"
265+
```
266+
267+
Configure the IPsec connection:
210268

269+
```bash
270+
# Requires: VIRTUAL_NETWORK_NAME from 'Deploy a virtual network'; VPN_SERVER, VPN_TYPE, ROUTES extracted above; INSTALL_DIR defined above
211271
sudo tee -a "${INSTALL_DIR}ipsec.conf" <<EOF
212272
conn $VIRTUAL_NETWORK_NAME
213273
keyexchange=$VPN_TYPE
@@ -222,16 +282,25 @@ conn $VIRTUAL_NETWORK_NAME
222282
leftsourceip=%config
223283
auto=add
224284
EOF
285+
```
286+
287+
Configure the IPsec secrets and start the VPN connection:
225288

289+
```bash
290+
# Requires: PASSWORD from 'Create certificates'; INSTALL_DIR, VIRTUAL_NETWORK_NAME defined above
226291
echo ": P12 client.p12 '$PASSWORD'" | sudo tee -a "${INSTALL_DIR}ipsec.secrets" > /dev/null
227292

228293
sudo ipsec restart
229-
sudo ipsec up $VIRTUAL_NETWORK_NAME
294+
sudo ipsec up $VIRTUAL_NETWORK_NAME
230295
```
231296

297+
**Verify:** Run `sudo ipsec status` and confirm the output shows `ESTABLISHED` for the connection named after your virtual network.
298+
232299
## Mount Azure file share
233300

234-
After setting up your point-to-site VPN, you can mount your Azure file share. See [Mount SMB file shares to Linux](storage-how-to-use-files-linux.md) or [Mount NFS file share to Linux](storage-files-how-to-mount-nfs-shares.md).
301+
After setting up your point-to-site VPN, you can mount your Azure file share. See [Mount SMB file shares to Linux](storage-how-to-use-files-linux.md) or [Mount NFS file share to Linux](storage-files-how-to-mount-nfs-shares.md).
302+
303+
**Verify:** Run `df -h | grep <mount-point>` (replace `<mount-point>` with your mount path) and confirm the Azure file share appears with the expected size.
235304

236305
## See also
237306

0 commit comments

Comments
 (0)