您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

在 Windows 上配置点到站点 (P2S) VPN 以与 Azure 文件存储一起使用Configure a Point-to-Site (P2S) VPN on Windows for use with Azure Files

你可以使用点到站点 (P2S) VPN 连接从 Azure 外部通过 SMB 装载 Azure 文件共享,而无需打开端口 445。You can use a Point-to-Site (P2S) VPN connection to mount your Azure file shares over SMB from outside of Azure, without opening up port 445. 点到站点 VPN 连接是 Azure 与单个客户端之间的 VPN 连接。A Point-to-Site VPN connection is a VPN connection between Azure and an individual client. 若要将 P2S VPN 连接与 Azure 文件存储一起使用,需要为每个要连接的客户端配置 P2S VPN 连接。To use a P2S VPN connection with Azure Files, a P2S VPN connection will need to be configured for each client that wants to connect. 如果有多个客户端需要从本地网络连接到 Azure 文件共享,则可以为每个客户端使用站点到站点 (S2S) VPN 连接,而不使用点到站点连接。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 (S2S) VPN connection instead of a Point-to-Site connection for each client. 若要了解详细信息,请参阅配置站点到站点 VPN 以与 Azure 文件存储一起使用To learn more, see Configure a Site-to-Site VPN for use with Azure Files.

我们强烈建议先阅读关于直接访问 Azure 文件共享的网络注意事项,然后再继续阅读本方法指南文章,以全面讨论 Azure 文件存储可用的网络选项。We strongly recommend that you read Networking considerations for direct Azure file share access before continuing with this how to article for a complete discussion of the networking options available for Azure Files.

本文详细介绍了在 Windows(Windows 客户端和 Windows Server)上配置点到站点 VPN 以直接在本地装载 Azure 文件共享的相关步骤。The article details the steps to configure a Point-to-Site VPN on Windows (Windows client and Windows Server) to mount Azure file shares directly on-premises. 如果想要通过 VPN 路由 Azure 文件同步流量,请参阅配置 Azure 文件同步代理和防火墙设置If you're looking to route Azure File Sync traffic over a VPN, please see configuring Azure File Sync proxy and firewall settings.

先决条件Prerequisites

  • 最新版本的 Azure PowerShell 模块。The most recent version of the Azure PowerShell module. 若要详细了解如何安装 Azure PowerShell,请参阅安装 Azure PowerShell 模块并选择操作系统。For more information on how to install the Azure PowerShell, see Install the Azure PowerShell module and select your operating system. 如果你更想在 Windows 上使用 Azure CLI,也可以使用,但下面是针对 Azure PowerShell 的说明。If you prefer to use the Azure CLI on Windows, you may, however the instructions below are presented for Azure PowerShell.

  • 要在本地装载的 Azure 文件共享。An Azure file share you would like to mount on-premises. Azure 文件共享部署在存储帐户中,是代表共享存储池的管理结构,可以在其中部署多个文件共享以及其他存储资源(例如 Blob 容器或队列)。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, as well as other storage resources, such as blob containers or queues. 可以在创建 Azure 文件共享中详细了解如何部署 Azure 文件共享和存储帐户。You can learn more about how to deploy Azure file shares and storage accounts in Create an Azure file share.

  • 包含要在本地装载的 Azure 文件共享的存储帐户的专用终结点。A private endpoint for the storage account containing the Azure file share you want to mount on-premises. 若要详细了解如何创建专用终结点,请参阅配置 Azure 文件存储网络终结点To learn more about how to create a private endpoint, see Configuring Azure Files network endpoints.

部署虚拟网络Deploy a virtual network

若要通过点到站点 VPN 从本地访问 Azure 文件共享和其他 Azure 资源,必须创建虚拟网络或 VNet。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, or VNet. 将自动创建的 P2S VPN 连接是本地 Windows 计算机与此 Azure 虚拟网络之间的桥。The P2S VPN connection you will automatically create is a bridge between your on-premises Windows machine and this Azure virtual network.

以下 PowerShell 将创建包含三个子网的 Azure 虚拟网络:一个用于存储帐户的服务终结点,一个用于存储帐户的专用终结点(用于访问本地存储帐户,而无需为可能更改的存储帐户的公共 IP 创建自定义路由),以及一个用于提供 VPN 服务的虚拟网关。The following PowerShell will create 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.

请记得将 <region><resource-group><desired-vnet-name> 替换为适合你的环境的值。Remember to replace <region>, <resource-group>, and <desired-vnet-name> with the appropriate values for your environment.

$region = "<region>"
$resourceGroupName = "<resource-group>" 
$virtualNetworkName = "<desired-vnet-name>"

$virtualNetwork = New-AzVirtualNetwork `
    -ResourceGroupName $resourceGroupName `
    -Name $virtualNetworkName `
    -Location $region `
    -AddressPrefix "192.168.0.0/16"

Add-AzVirtualNetworkSubnetConfig `
    -Name "ServiceEndpointSubnet" `
    -AddressPrefix "192.168.0.0/24" `
    -VirtualNetwork $virtualNetwork `
    -ServiceEndpoint "Microsoft.Storage" `
    -WarningAction SilentlyContinue | Out-Null

Add-AzVirtualNetworkSubnetConfig `
    -Name "PrivateEndpointSubnet" `
    -AddressPrefix "192.168.1.0/24" `
    -VirtualNetwork $virtualNetwork `
    -WarningAction SilentlyContinue | Out-Null

Add-AzVirtualNetworkSubnetConfig `
    -Name "GatewaySubnet" `
    -AddressPrefix "192.168.2.0/24" `
    -VirtualNetwork $virtualNetwork `
    -WarningAction SilentlyContinue | Out-Null

$virtualNetwork | Set-AzVirtualNetwork | Out-Null
$virtualNetwork = Get-AzVirtualNetwork `
    -ResourceGroupName $resourceGroupName `
    -Name $virtualNetworkName

$serviceEndpointSubnet = $virtualNetwork.Subnets | `
    Where-Object { $_.Name -eq "ServiceEndpointSubnet" }
$privateEndpointSubnet = $virtualNetwork.Subnets | `
    Where-Object { $_.Name -eq "PrivateEndpointSubnet" }
$gatewaySubnet = $virtualNetwork.Subnets | ` 
    Where-Object { $_.Name -eq "GatewaySubnet" }

为 VPN 身份验证创建根证书Create root certificate for VPN authentication

为了对来自本地 Windows 计算机的 VPN 连接进行身份验证以访问虚拟网络,必须创建两个证书:根证书(将提供给虚拟机网关)和客户端证书(将使用根证书进行签名)。In order for VPN connections from your on-premises Windows machines to be authenticated to access your virtual network, you must create two certificates: a root certificate, which will be provided to the virtual machine gateway, and a client certificate, which will be signed with the root certificate. 以下 PowerShell 将创建根证书;创建 Azure 虚拟网络网关之后,将创建客户端证书,其中包含来自网关的信息。The following PowerShell creates the root certificate; the client certificate will be created after the Azure virtual network gateway is created with information from the gateway.

$rootcertname = "CN=P2SRootCert"
$certLocation = "Cert:\CurrentUser\My"
$vpnTemp = "C:\vpn-temp\"
$exportedencodedrootcertpath = $vpnTemp + "P2SRootCertencoded.cer"
$exportedrootcertpath = $vpnTemp + "P2SRootCert.cer"

if (-Not (Test-Path $vpnTemp)) {
    New-Item -ItemType Directory -Force -Path $vpnTemp | Out-Null
}

if ($PSVersionTable.PSVersion -ge [System.Version]::new(6, 0)) {
    Install-Module WindowsCompatibility
    Import-WinModule PKI
}

$rootcert = New-SelfSignedCertificate `
    -Type Custom `
    -KeySpec Signature `
    -Subject $rootcertname `
    -KeyExportPolicy Exportable `
    -HashAlgorithm sha256 `
    -KeyLength 2048 `
    -CertStoreLocation $certLocation `
    -KeyUsageProperty Sign `
    -KeyUsage CertSign

Export-Certificate `
    -Cert $rootcert `
    -FilePath $exportedencodedrootcertpath `
    -NoClobber | Out-Null

certutil -encode $exportedencodedrootcertpath $exportedrootcertpath | Out-Null

$rawRootCertificate = Get-Content -Path $exportedrootcertpath

[System.String]$rootCertificate = ""
foreach($line in $rawRootCertificate) { 
    if ($line -notlike "*Certificate*") { 
        $rootCertificate += $line 
    } 
}

部署虚拟网络网关Deploy virtual network gateway

Azure 虚拟网络网关是本地 Windows 计算机将连接到的服务。The Azure virtual network gateway is the service that your on-premises Windows machines will connect to. 部署此服务需要两个基本组件:一个公共 IP(无论客户端位于何处,都可用此 IP 来标识其网关),一个之前创建的根证书(将用于对客户端进行身份验证)。Deploying this service requires two basic components: a public IP that will identify the gateway to your clients wherever they are in the world and a root certificate you created earlier which will be used to authenticate your clients.

请记得将 <desired-vpn-name-here> 替换为要为这些资源使用的名称。Remember to replace <desired-vpn-name-here> with the name you would like for these resources.

备注

部署 Azure 虚拟网络网关最多需要 45 分钟。Deploying the Azure virtual network gateway can take up to 45 minutes. 部署此资源时,此 PowerShell 脚本将阻止部署完成。While this resource is being deployed, this PowerShell script will block for the deployment to be completed. 这是正常情况。This is expected.

$vpnName = "<desired-vpn-name-here>" 
$publicIpAddressName = "$vpnName-PublicIP"

$publicIPAddress = New-AzPublicIpAddress `
    -ResourceGroupName $resourceGroupName `
    -Name $publicIpAddressName `
    -Location $region `
    -Sku Basic `
    -AllocationMethod Dynamic

$gatewayIpConfig = New-AzVirtualNetworkGatewayIpConfig `
    -Name "vnetGatewayConfig" `
    -SubnetId $gatewaySubnet.Id `
    -PublicIpAddressId $publicIPAddress.Id

$azRootCertificate = New-AzVpnClientRootCertificate `
    -Name "P2SRootCert" `
    -PublicCertData $rootCertificate

$vpn = New-AzVirtualNetworkGateway `
    -ResourceGroupName $resourceGroupName `
    -Name $vpnName `
    -Location $region `
    -GatewaySku VpnGw1 `
    -GatewayType Vpn `
    -VpnType RouteBased `
    -IpConfigurations $gatewayIpConfig `
    -VpnClientAddressPool "172.16.201.0/24" `
    -VpnClientProtocol IkeV2 `
    -VpnClientRootCertificates $azRootCertificate

创建客户端证书Create client certificate

客户端证书是使用虚拟网络网关的 URI 创建的。The client certificate is created with the URI of the virtual network gateway. 此证书使用之前创建的根证书进行签名。This certificate is signed with the root certificate you created earlier.

$clientcertpassword = "1234"

$vpnClientConfiguration = New-AzVpnClientConfiguration `
    -ResourceGroupName $resourceGroupName `
    -Name $vpnName `
    -AuthenticationMethod EAPTLS

Invoke-WebRequest `
    -Uri $vpnClientConfiguration.VpnProfileSASUrl `
    -OutFile "$vpnTemp\vpnclientconfiguration.zip"

Expand-Archive `
    -Path "$vpnTemp\vpnclientconfiguration.zip" `
    -DestinationPath "$vpnTemp\vpnclientconfiguration"

$vpnGeneric = "$vpnTemp\vpnclientconfiguration\Generic"
$vpnProfile = ([xml](Get-Content -Path "$vpnGeneric\VpnSettings.xml")).VpnProfile

$exportedclientcertpath = $vpnTemp + "P2SClientCert.pfx"
$clientcertname = "CN=" + $vpnProfile.VpnServer

$clientcert = New-SelfSignedCertificate `
    -Type Custom `
    -DnsName $vpnProfile.VpnServer `
    -KeySpec Signature `
    -Subject $clientcertname `
    -KeyExportPolicy Exportable `
    -HashAlgorithm sha256 `
    -KeyLength 2048 `
    -CertStoreLocation $certLocation `
    -Signer $rootcert `
    -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2")

$mypwd = ConvertTo-SecureString -String $clientcertpassword -Force -AsPlainText

Export-PfxCertificate `
    -FilePath $exportedclientcertpath `
    -Password $mypwd `
    -Cert $clientcert | Out-Null

配置 VPN 客户端Configure the VPN client

Azure 虚拟网络网关将创建一个可下载的包,其中包含在本地 Windows 计算机上初始化 VPN 连接所需的配置文件。The Azure virtual network gateway will create a downloadable package with configuration files required to initialize the VPN connection on your on-premises Windows machine. 我们将使用 Windows 10/Windows Server 2016 及更高版本的 Always On VPN 功能配置 VPN 连接。We will configure the VPN connection using the Always On VPN feature of Windows 10/Windows Server 2016+. 此包还包含将配置旧版 Windows VPN 客户端的可执行包(如果确实需要)。This package also contains executable packages which will configure the legacy Windows VPN client, if so desired. 本指南使用 Always On VPN 而不是旧版 Windows VPN 客户端,因为使用 Always On VPN 客户端,最终用户无需拥有对其计算机的管理员权限,即可连接 Azure VPN 或断开与其建立的连接。This guide uses Always On VPN rather than the legacy Windows VPN client as the Always On VPN client allows end-users to connect/disconnect from the Azure VPN without having administrator permissions to their machine.

以下脚本将安装针对虚拟网络网关进行身份验证所需的客户端证书,下载并安装 VPN 包。The following script will install the client certificate required for authentication against the virtual network gateway, download, and install the VPN package. 请记得将 <computer1><computer2> 替换为所需的计算机。Remember to replace <computer1> and <computer2> with the desired computers. 通过将更多的 PowerShell 会话添加到 $sessions 数组,可以在所需的任意数量的计算机上运行此脚本。You can run this script on as many machines as you desire by adding more PowerShell sessions to the $sessions array. 使用帐户必须是每台计算机上的管理员。Your use account must be an administrator on each of these machines. 如果其中一台计算机是正在运行脚本的本地计算机,则必须从提升权限的 PowerShell 会话运行该脚本。If one of these machines is the local machine you are running the script from, you must run the script from an elevated PowerShell session.

$sessions = [System.Management.Automation.Runspaces.PSSession[]]@()
$sessions += New-PSSession -ComputerName "<computer1>"
$sessions += New-PSSession -ComputerName "<computer2>"

foreach ($session in $sessions) {
    Invoke-Command -Session $session -ArgumentList $vpnTemp -ScriptBlock { 
        $vpnTemp = $args[0]
        if (-Not (Test-Path $vpnTemp)) {
            New-Item `
                -ItemType Directory `
                -Force `
                -Path "C:\vpn-temp" | Out-Null
        }
    }

    Copy-Item `
        -Path $exportedclientcertpath, $exportedrootcertpath, "$vpnTemp\vpnclientconfiguration.zip" `
        -Destination $vpnTemp `
        -ToSession $session

    Invoke-Command `
        -Session $session `
        -ArgumentList `
            $mypwd, `
            $vpnTemp, `
            $virtualNetworkName `
        -ScriptBlock { 
            $mypwd = $args[0] 
            $vpnTemp = $args[1]
            $virtualNetworkName = $args[2]

            Import-PfxCertificate `
                -Exportable `
                -Password $mypwd `
                -CertStoreLocation "Cert:\LocalMachine\My" `
                -FilePath "$vpnTemp\P2SClientCert.pfx" | Out-Null

            Import-Certificate `
                -FilePath "$vpnTemp\P2SRootCert.cer" `
                -CertStoreLocation "Cert:\LocalMachine\Root" | Out-Null

            Expand-Archive `
                -Path "$vpnTemp\vpnclientconfiguration.zip" `
                -DestinationPath "$vpnTemp\vpnclientconfiguration"
            $vpnGeneric = "$vpnTemp\vpnclientconfiguration\Generic"

            $vpnProfile = ([xml](Get-Content -Path "$vpnGeneric\VpnSettings.xml")).VpnProfile

            Add-VpnConnection `
                -Name $virtualNetworkName `
                -ServerAddress $vpnProfile.VpnServer `
                -TunnelType Ikev2 `
                -EncryptionLevel Required `
                -AuthenticationMethod MachineCertificate `
                -SplitTunneling `
                -AllUserConnection

            Add-VpnConnectionRoute `
                -Name $virtualNetworkName `
                -DestinationPrefix $vpnProfile.Routes `
                -AllUserConnection

            Add-VpnConnectionRoute `
                -Name $virtualNetworkName `
                -DestinationPrefix $vpnProfile.VpnClientAddressPool `
                -AllUserConnection

            rasdial $virtualNetworkName
        }
}

Remove-Item -Path $vpnTemp -Recurse

装载 Azure 文件共享Mount Azure file share

现在,你已设置点到站点 VPN,可以使用它在通过 PowerShell 设置的计算机上装载 Azure 文件共享。Now that you have set up your Point-to-Site VPN, you can use it to mount the Azure file share on the computers you setup via PowerShell. 以下示例将装载共享、列出共享的根目录(证明实际上已装载该共享),然后卸载该共享。The following example will mount the share, list the root directory of the share to prove the share is actually mounted, and the unmount the share. 遗憾的是,无法通过 PowerShell 远程处理永久装载共享。Unfortunately, it is not possible to mount the share persistently over PowerShell remoting. 若要永久装载,请参阅将 Azure 文件共享与 Windows 配合使用To mount persistently, see Use an Azure file share with Windows.

$myShareToMount = "<file-share>"

$storageAccountKeys = Get-AzStorageAccountKey `
    -ResourceGroupName $resourceGroupName `
    -Name $storageAccountName
$storageAccountKey = ConvertTo-SecureString `
    -String $storageAccountKeys[0].Value `
    -AsPlainText `
    -Force

$nic = Get-AzNetworkInterface -ResourceId $privateEndpoint.NetworkInterfaces[0].Id
$storageAccountPrivateIP = $nic.IpConfigurations[0].PrivateIpAddress

Invoke-Command `
    -Session $sessions `
    -ArgumentList  `
        $storageAccountName, `
        $storageAccountKey, `
        $storageAccountPrivateIP, `
        $myShareToMount `
    -ScriptBlock {
        $storageAccountName = $args[0]
        $storageAccountKey = $args[1]
        $storageAccountPrivateIP = $args[2]
        $myShareToMount = $args[3]

        $credential = [System.Management.Automation.PSCredential]::new(
            "AZURE\$storageAccountName", 
            $storageAccountKey)

        New-PSDrive `
            -Name Z `
            -PSProvider FileSystem `
            -Root "\\$storageAccountPrivateIP\$myShareToMount" `
            -Credential $credential `
            -Persist | Out-Null
        Get-ChildItem -Path Z:\
        Remove-PSDrive -Name Z
    }

另请参阅See also