Настройка VPN типа "точка — сеть" в Linux для использования с файлами Azure

✔️ Область применения: классические общие папки SMB и NFS, созданные с помощью поставщика ресурсов Microsoft.Storage

Не применяется к: общим папкам, созданным с помощью поставщика ресурсов Microsoft.FileShares (предварительная версия)

Вы можете использовать соединение виртуальной частной сети типа "точка-сайт" (VPN) для монтирования файловых ресурсов Azure извне Azure без передачи данных по открытому Интернету. VPN-подключение типа "точка — сеть" — это VPN-подключение между Azure и отдельным клиентским компьютером. Чтобы использовать VPN-подключение типа "точка — сеть" с файлами Azure, необходимо настроить VPN-подключение типа "точка — сеть" для каждого клиентского компьютера, который хочет подключиться. Если у вас есть множество клиентских компьютеров, которые должны подключаться к общим папкам Azure из локальной сети, вы можете использовать VPN-подключение типа "сеть — сеть" вместо подключения типа "точка — сеть" для каждого клиентского компьютера. Дополнительные сведения см. в статье Настройка VPN типа «сеть — сеть» для использования с Azure Files.

Полный обзор сетевых параметров, доступных для файлов Azure, см. в разделе "Общие сведения о сети файлов Azure".

В этой статье описаны действия по настройке VPN типа "точка — сеть" в Linux для подключения общих папок Azure непосредственно в локальной среде.

Предпосылки

  • Последняя версия Azure CLI. Сведения о том, как установить Azure CLI, см. в статье "Установка Azure CLI " и выбор операционной системы. Вместо этого можно использовать модуль Azure PowerShell в Linux, но инструкции из этой статьи предназначены для Azure CLI.

  • Ресурс файлов Azure, который вы планируете смонтировать локально. Файловые ресурсы Azure создаются в учетных записях хранения, представляющих собой общий пул хранилища, в котором можно создавать несколько файловых ресурсов. Дополнительные сведения о развертывании общих папок Azure и учетных записей хранения см. в статье Создание общей папки Azure.

  • Частная конечная точка для учетной записи хранения, содержащей общую папку Azure, которую вы хотите подключить локально. Сведения о создании частной конечной точки см. в статье "Настройка сетевых конечных точек Azure Files".

Установка необходимого программного обеспечения

Шлюз виртуальной сети Azure может предоставлять VPN-подключения с помощью нескольких VPN-протоколов, включая IPsec и OpenVPN. В этой статье показано, как использовать IPsec и использовать пакет strongSwan для предоставления поддержки в Linux.

Примечание.

Эти инструкции были протестированы в Ubuntu 18.10 и должны работать в Ubuntu 18.04 LTS и более поздних версий, а также Debian 10+. Для других дистрибутивов, поддерживающих strongSwan (например, Fedora, CentOS или openSUSE), могут потребоваться разные имена пакетов или команды установки.

# For Ubuntu/Debian-based distributions (Ubuntu 18.04+, Debian 10+)
sudo apt update
sudo apt install strongswan strongswan-pki libstrongswan-extra-plugins curl libxml2-utils cifs-utils unzip

Если установка завершается ошибкой или возникает ошибка, например EAP_IDENTITY not supported, sending EAP_NAK, может потребоваться установить дополнительные подключаемые модули:

sudo apt install -y libcharon-extra-plugins

Развертывание виртуальной сети

Чтобы получить доступ к общей папке Azure и другим ресурсам Azure из локальной среды через VPN типа "точка — сеть", необходимо создать виртуальную сеть. VPN-подключение типа "точка — сеть" устанавливает безопасный туннель между локальным клиентским компьютером Linux и этой виртуальной сетью Azure.

Следующий сценарий создает виртуальную сеть Azure с тремя подсетями: одну для конечной точки службы учетной записи хранения, одну для частной конечной точки учетной записи хранения, которая требуется для доступа к локальной учетной записи хранения без создания пользовательской маршрутизации для общедоступного IP-адреса учетной записи хранения, которая может измениться, и один для шлюза виртуальной сети, предоставляющего VPN-службу.

# Variables - replace <region>, <resource-group>, and <desired-vnet-name> with your values
REGION="<region>"
RESOURCE_GROUP_NAME="<resource-group>"
VIRTUAL_NETWORK_NAME="<desired-vnet-name>"

Создайте виртуальную сеть:

# Requires: REGION, RESOURCE_GROUP_NAME, VIRTUAL_NETWORK_NAME defined above
VIRTUAL_NETWORK=$(az network vnet create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $VIRTUAL_NETWORK_NAME \
    --location $REGION \
    --address-prefixes "192.168.0.0/16" \
    --query "newVNet.id" | tr -d '"')

Создайте подсети для конечных точек службы, частных конечных точек и шлюза:

# Requires: RESOURCE_GROUP_NAME, VIRTUAL_NETWORK_NAME defined above
SERVICE_ENDPOINT_SUBNET=$(az network vnet subnet create \
    --resource-group $RESOURCE_GROUP_NAME \
    --vnet-name $VIRTUAL_NETWORK_NAME \
    --name "ServiceEndpointSubnet" \
    --address-prefixes "192.168.0.0/24" \
    --service-endpoints "Microsoft.Storage" \
    --query "id" | tr -d '"')

PRIVATE_ENDPOINT_SUBNET=$(az network vnet subnet create \
    --resource-group $RESOURCE_GROUP_NAME \
    --vnet-name $VIRTUAL_NETWORK_NAME \
    --name "PrivateEndpointSubnet" \
    --address-prefixes "192.168.1.0/24" \
    --query "id" | tr -d '"')

GATEWAY_SUBNET=$(az network vnet subnet create \
    --resource-group $RESOURCE_GROUP_NAME \
    --vnet-name $VIRTUAL_NETWORK_NAME \
    --name "GatewaySubnet" \
    --address-prefixes "192.168.2.0/24" \
    --query "id" | tr -d '"')

Проверьте: Запустите az network vnet subnet list --resource-group $RESOURCE_GROUP_NAME --vnet-name $VIRTUAL_NETWORK_NAME --output table и убедитесь, что отображаются три подсети: ServiceEndpointSubnet, PrivateEndpointSubnet и GatewaySubnet.

Создание сертификатов для проверки подлинности VPN

Для VPN-подключений с локальных клиентских компьютеров Linux для проверки подлинности с помощью шлюза виртуальной сети необходимо создать два сертификата:

  • Корневой сертификат, который предоставляется шлюзу виртуальных машин
  • Сертификат клиента, подписанный корневым сертификатом и установленный на каждом клиентском компьютере

Задайте переменные сертификата и создайте рабочий каталог:

# Variables
ROOT_CERT_NAME="P2SRootCert"
USERNAME="client"              # Client certificate identity (not a machine login)
PASSWORD="1234"                # Password for the client certificate PKCS#12 file

mkdir temp
cd temp

Создайте корневой сертификат:

# Requires: ROOT_CERT_NAME defined above; run from temp directory
sudo ipsec pki --gen --outform pem > rootKey.pem
sudo ipsec pki --self --in rootKey.pem --dn "CN=$ROOT_CERT_NAME" --ca --outform pem > rootCert.pem

ROOT_CERTIFICATE=$(openssl x509 -in rootCert.pem -outform der | base64 -w0 ; echo)

Создайте сертификат клиента, подписанный корневым сертификатом:

# Requires: USERNAME, PASSWORD defined; rootCert.pem and rootKey.pem from previous step
sudo ipsec pki --gen --size 4096 --outform pem > "clientKey.pem"
sudo ipsec pki --pub --in "clientKey.pem" | \
    sudo ipsec pki \
        --issue \
        --cacert rootCert.pem \
        --cakey rootKey.pem \
        --dn "CN=$USERNAME" \
        --san $USERNAME \
        --flag clientAuth \
        --outform pem > "clientCert.pem"

openssl pkcs12 -in "clientCert.pem" -inkey "clientKey.pem" -certfile rootCert.pem -export -out "client.p12" -password "pass:$PASSWORD"

Проверьте: Запустите ls -la *.pem client.p12 и убедитесь, что существуют пять файлов: rootKey.pem, rootCert.pem, clientKey.pem, clientCert.pem, и client.p12.

Развертывание шлюза виртуальной сети

Шлюз виртуальной сети Azure — это служба, к к которому подключается локальный клиентский компьютер Linux. Для развертывания этой службы требуются два компонента:

  • Общедоступный IP-адрес, определяющий шлюз для клиентских машин.
  • Созданный ранее корневой сертификат, который проверяет подлинность клиентских компьютеров с помощью сертификатов клиента.

Примечание.

Развертывание шлюза виртуальной сети Azure может занять до 45 минут. Хотя этот ресурс развертывается, этот сценарий блокирует завершение развертывания.

Подключения IKEv2/OpenVPN типа "точка — сеть" не поддерживаются с номером SKU шлюза "Базовый ". Этот скрипт использует номер SKU VpnGw1 для шлюза виртуальной сети, который является минимальным номером SKU для подключений IKEv2. Общедоступный IP-адрес может использовать номер SKU "Базовый " с динамическим выделением.

# Variables - replace <desired-vpn-name-here> with your value
VPN_NAME="<desired-vpn-name-here>"
PUBLIC_IP_ADDR_NAME="$VPN_NAME-PublicIP"

Создайте общедоступный IP-адрес для шлюза:

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

Создайте шлюз виртуальной сети:

# Requires: RESOURCE_GROUP_NAME, REGION, VIRTUAL_NETWORK_NAME from 'Deploy a virtual network'; VPN_NAME, PUBLIC_IP_ADDR defined above
# Note: VpnGw1 is the minimum SKU required for IKEv2/OpenVPN; Basic SKU doesn't support point-to-site IKEv2
az network vnet-gateway create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $VPN_NAME \
    --vnet $VIRTUAL_NETWORK_NAME \
    --public-ip-addresses $PUBLIC_IP_ADDR \
    --location $REGION \
    --sku "VpnGw1" \
    --gateway-type "Vpn" \
    --vpn-type "RouteBased" \
    --address-prefixes "172.16.201.0/24" \
    --client-protocol "IkeV2" > /dev/null

Отправьте корневой сертификат в шлюз:

# Requires: RESOURCE_GROUP_NAME from 'Deploy a virtual network'; VPN_NAME defined above; ROOT_CERT_NAME, ROOT_CERTIFICATE from 'Create certificates'
az network vnet-gateway root-cert create \
    --resource-group $RESOURCE_GROUP_NAME \
    --gateway-name $VPN_NAME \
    --name $ROOT_CERT_NAME \
    --public-cert-data $ROOT_CERTIFICATE \
    --output none

Проверяем подлинность: Выполните az network vnet-gateway show --resource-group $RESOURCE_GROUP_NAME --name $VPN_NAME --query "provisioningState" и подтвердите выходные данные "Succeeded".

Настройка VPN-клиента

Шлюз виртуальной сети Azure создает скачиваемый пакет с файлами конфигурации, необходимыми для инициализации VPN-подключения на локальном клиентском компьютере Linux. Следующий скрипт копирует сертификат клиента в каталоги сертификатов strongSwan (/etc/ipsec.d/) и настраивает ipsec.conf файл со значениями из скачаированного пакета конфигурации.

# Requires: RESOURCE_GROUP_NAME from 'Deploy a virtual network'; VPN_NAME from 'Deploy virtual network gateway'
VPN_CLIENT=$(az network vnet-gateway vpn-client generate \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $VPN_NAME \
    --authentication-method EAPTLS | tr -d '"')

curl $VPN_CLIENT --output vpnClient.zip
unzip vpnClient.zip

Извлеките значения конфигурации VPN:

# Requires: vpnClient.zip extracted in current directory
VPN_SERVER=$(xmllint --xpath "string(/VpnProfile/VpnServer)" Generic/VpnSettings.xml)
VPN_TYPE=$(xmllint --xpath "string(/VpnProfile/VpnType)" Generic/VpnSettings.xml | tr '[:upper:]' '[:lower:]')
ROUTES=$(xmllint --xpath "string(/VpnProfile/Routes)" Generic/VpnSettings.xml)

Скопируйте сертификаты в каталоги strongSwan:

# Requires: USERNAME from 'Create certificates'; client.p12 (client certificate) from temp directory
INSTALL_DIR="/etc/"

sudo cp "${INSTALL_DIR}ipsec.conf" "${INSTALL_DIR}ipsec.conf.backup"
sudo cp "Generic/VpnServerRoot.cer_0" "${INSTALL_DIR}ipsec.d/cacerts"
sudo cp "${USERNAME}.p12" "${INSTALL_DIR}ipsec.d/private"

Настройте подключение IPsec:

# Requires: VIRTUAL_NETWORK_NAME from 'Deploy a virtual network'; VPN_SERVER, VPN_TYPE, ROUTES extracted above; INSTALL_DIR defined above
sudo tee -a "${INSTALL_DIR}ipsec.conf" <<EOF
conn $VIRTUAL_NETWORK_NAME
    keyexchange=$VPN_TYPE
    type=tunnel
    leftfirewall=yes
    left=%any
    leftauth=eap-tls
    leftid=%client
    right=$VPN_SERVER
    rightid=%$VPN_SERVER
    rightsubnet=$ROUTES
    leftsourceip=%config
    auto=add
EOF

Настройте секреты IPsec и запустите VPN-подключение:

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

sudo ipsec restart
sudo ipsec up $VIRTUAL_NETWORK_NAME

Проверьте: Запустите sudo ipsec status и убедитесь, что выходные данные показывают ESTABLISHED для подключения, названного в честь вашей виртуальной сети.

Подключение файлового ресурса Azure

После настройки VPN типа "точка-точка" вы можете монтировать общую папку Azure. См. раздел подключение общих папок SMB к Linux или подключение общих папок NFS к Linux.

Проверяем подлинность: Запустите df -h | grep <mount-point> (замените <mount-point> путь подключения) и убедитесь, что общая папка Azure отображается с ожидаемым размером.

См. также