Azure 文件同步 使用两个 Azure 资源,每个资源都有自己的网络端点:存储账户(负责 Azure 文件共享)和存储同步服务(负责协调同步、服务器注册和同步组)。 这两个资源默认使用公共端点。
Azure 文件同步 代理通过 HTTPS(端口 443)与两个资源通信。 对于通过互联网连接Azure且没有VPN或ExpressRoute的服务器,你可以使用公共端点,无需配置。 然而,大多数 Azure 文件同步 客户希望配置私有端点。
请参考下表判断是否需要私有端点。 如果需要,就为两个资源创建私有端点。
| 我需要... |
Use |
| 同步通过互联网连接Azure的服务器,无需VPN或ExpressRoute |
公共端点(无需配置) |
| 通过ExpressRoute或站点对站点VPN连接路由所有同步流量 |
两个资源的私有终结点 |
| 满足禁止在公共互联网上传输数据的合规要求 |
两个资源的专用终结点 |
| 禁用公共端点作为安全加固措施 |
先为两个资源设置私有端点,然后限制访问 |
| 实现零信任网络访问 |
两个资源的专用终结点 |
关于更广泛的网络相关概念,请参阅 Azure 文件同步 网络注意事项。 要配置端点以直接访问Azure文件共享(不使用Azure 文件同步),请参见配置Azure 文件存储网络端点。
先决条件
本文假设:
此外:
- 如果你打算使用 Azure PowerShell,请安装最新版本。
- 如果你打算使用 Azure CLI,请安装最新版本。
创建专用终结点
为 Azure 资源创建专用终结点时,将部署以下资源:
| 部署资源 |
Description |
你做的事情 |
|
专用终结点 |
一个Azure资源,将你的存储账户或存储同步服务连接到虚拟网络中的网络接口 |
在创建存储账户私有端点和创建存储同步服务私有端点中,为每个资源创建一个 |
|
网络接口 (NIC) |
保存你子网内私有端点的私有IP地址 |
通过私有端点自动创建;无需额外操作 |
|
专用 DNS 区域 |
将资源的公共主机名映射到私有端点的IP地址,使客户端在不更改连接字符串的情况下解析到私有端点 |
如果不存在,则会自动创建;建议避免手动配置 DNS。 |
备注
本文使用了Azure公共区域的DNS后缀:core.windows.net存储账户和afs.azure.net存储同步服务。 这种命名法同样适用于 Azure 主权云,如 Azure 美国政府 云。 只需根据环境替换相应的后缀即可。
创建存储帐户专用终结点
请进入要为其创建专用终结点的存储帐户。 在服务菜单的“安全性 + 网络”下,依次选择“网络”、“专用终结点连接”,然后选择“+ 专用终结点”创建新的专用终结点。
生成的向导有多个需要填写的页面。
在“基本信息”边栏选项卡中,为专用终结点选择所需的订阅、资源组、名称、网络接口名称和区域。 资源组、名称和区域可以任意配置,不必与存储帐户匹配,但必须在同一区域中创建专用终结点和用于容纳该专用终结点的存储帐户。 然后选择“下一步: 资源”。
在“资源”选项卡中,为目标子资源选择“文件”。 然后选择“下一步: 虚拟网络”。
在“虚拟网络”边栏选项卡中,可以选择要向其添加专用终结点的特定虚拟网络和子网。 为新的专用终结点选择动态或静态 IP 地址分配。 如果选择静态,则还需要提供名称和专用 IP 地址。 还可以选择指定应用程序安全组。 完成后,选择“下一步: DNS”。
DNS 边栏选项卡包含用于将专用终结点与专用 DNS 区域集成的信息。 确保订阅和资源组正确,然后选择“下一步: 标记”。
可以选择性地应用标记来对资源进行分类,如将名称“环境”和值“测试”应用于所有测试资源。 输入名称/值对(如果需要),然后选择“下一步: 查看 + 创建”。
选择“创建”以创建专用终结点。
如果你的虚拟网络内有虚拟机,或者你按照《配置 Azure 文件存储 的 DNS 转发配置了》中的描述,可以通过从 PowerShell、命令行或终端(适用于 Windows、Linux 或 macOS)执行以下命令来测试你的私有端点是否正确设置。 用你的存储账户名称替换 <storage-account-name> :
nslookup <storage-account-name>.file.core.windows.net
如果一切成功进行,则应会看到以下输出,其中 192.168.0.5 是虚拟网络中专用终结点的专用 IP 地址(Windows 中显示的输出):
Server: UnKnown
Address: 10.2.4.4
Non-authoritative answer:
Name: storageaccount.privatelink.file.core.windows.net
Address: 192.168.0.5
Aliases: storageaccount.file.core.windows.net
若要为存储帐户创建专用终结点,首先需要获取对存储帐户的引用,以及要将专用终结点添加到的虚拟网络子网的引用。 请替换下面的 <storage-account-resource-group-name>、<storage-account-name>、<vnet-resource-group-name>、<vnet-name> 和 <vnet-subnet-name>:
$storageAccountResourceGroupName = "<storage-account-resource-group-name>"
$storageAccountName = "<storage-account-name>"
$virtualNetworkResourceGroupName = "<vnet-resource-group-name>"
$virtualNetworkName = "<vnet-name>"
$subnetName = "<vnet-subnet-name>"
# Get storage account reference, and throw error if it doesn't exist
$storageAccount = Get-AzStorageAccount `
-ResourceGroupName $storageAccountResourceGroupName `
-Name $storageAccountName `
-ErrorAction SilentlyContinue
if ($null -eq $storageAccount) {
$errorMessage = "Storage account $storageAccountName not found "
$errorMessage += "in resource group $storageAccountResourceGroupName."
Write-Error -Message $errorMessage -ErrorAction Stop
}
# Get virtual network reference, and throw error if it doesn't exist
$virtualNetwork = Get-AzVirtualNetwork `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $virtualNetworkName `
-ErrorAction SilentlyContinue
if ($null -eq $virtualNetwork) {
$errorMessage = "Virtual network $virtualNetworkName not found "
$errorMessage += "in resource group $virtualNetworkResourceGroupName."
Write-Error -Message $errorMessage -ErrorAction Stop
}
# Get reference to virtual network subnet, and throw error if it doesn't exist
$subnet = $virtualNetwork | `
Select-Object -ExpandProperty Subnets | `
Where-Object { $_.Name -eq $subnetName }
if ($null -eq $subnet) {
Write-Error `
-Message "Subnet $subnetName not found in virtual network $virtualNetworkName." `
-ErrorAction Stop
}
若要创建专用终结点,必须与存储帐户建立专用链接服务连接。 专用链接服务连接是创建专用终结点时使用的输入。
# Disable private endpoint network policies
$subnet.PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork = $virtualNetwork | `
Set-AzVirtualNetwork -ErrorAction Stop
# Create a private link service connection to the storage account.
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "$storageAccountName-Connection" `
-PrivateLinkServiceId $storageAccount.Id `
-GroupId "file" `
-ErrorAction Stop
# Create a new private endpoint.
$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName $storageAccountResourceGroupName `
-Name "$storageAccountName-PrivateEndpoint" `
-Location $virtualNetwork.Location `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnection `
-ErrorAction Stop
创建 Azure 专用 DNS 区域可将存储帐户的原始名称(例如 storageaccount.file.core.windows.net)解析为虚拟网络内部的专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果直接使用 AD 用户主体装载或通过 REST API 访问 Azure 文件共享,则此操作肯定是必需的。
# Get the desired storage account suffix (core.windows.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
$storageAccountSuffix = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty StorageEndpointSuffix
# For public cloud, this will generate the following DNS suffix:
# privatelink.file.core.windows.net.
$dnsZoneName = "privatelink.file.$storageAccountSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create new one.
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
获取对专用 DNS 区域的引用后,接下来必须创建存储帐户的 A 记录。
$privateEndpointIP = $privateEndpoint | `
Select-Object -ExpandProperty NetworkInterfaces | `
Select-Object @{
Name = "NetworkInterfaces";
Expression = { Get-AzNetworkInterface -ResourceId $_.Id }
} | `
Select-Object -ExpandProperty NetworkInterfaces | `
Select-Object -ExpandProperty IpConfigurations | `
Select-Object -ExpandProperty PrivateIpAddress
$privateDnsRecordConfig = New-AzPrivateDnsRecordConfig `
-IPv4Address $privateEndpointIP
New-AzPrivateDnsRecordSet `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $storageAccountName `
-RecordType A `
-ZoneName $dnsZoneName `
-Ttl 600 `
-PrivateDnsRecords $privateDnsRecordConfig `
-ErrorAction Stop | `
Out-Null
如果你的虚拟网络中有虚拟机,或者你按照“配置 Azure 文件存储 DNS 转发”中描述的配置了 DNS,可以通过以下命令测试你的私有端点是否正确设置:
$storageAccountHostName = [System.Uri]::new($storageAccount.PrimaryEndpoints.file) | `
Select-Object -ExpandProperty Host
Resolve-DnsName -Name $storageAccountHostName
如果一切成功进行,则应会看到以下输出,其中 192.168.0.5 是虚拟网络中专用终结点的专用 IP 地址:
Name Type TTL Section NameHost
---- ---- --- ------- --------
storageaccount.file.core.windows CNAME 60 Answer storageaccount.privatelink.file.core.windows.net
.net
Name : storageaccount.privatelink.file.core.windows.net
QueryType : A
TTL : 600
Section : Answer
IP4Address : 192.168.0.5
若要为存储帐户创建专用终结点,首先需要获取对存储帐户的引用,以及要将专用终结点添加到的虚拟网络子网的引用。 请替换下面的 <storage-account-resource-group-name>、<storage-account-name>、<vnet-resource-group-name>、<vnet-name> 和 <vnet-subnet-name>:
storageAccountResourceGroupName="<storage-account-resource-group-name>"
storageAccountName="<storage-account-name>"
virtualNetworkResourceGroupName="<vnet-resource-group-name>"
virtualNetworkName="<vnet-name>"
subnetName="<vnet-subnet-name>"
# Get storage account ID
storageAccount=$(az storage account show \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--query "id" | \
tr -d '"')
# Get virtual network ID
virtualNetwork=$(az network vnet show \
--resource-group $virtualNetworkResourceGroupName \
--name $virtualNetworkName \
--query "id" | \
tr -d '"')
# Get subnet ID
subnet=$(az network vnet subnet show \
--resource-group $virtualNetworkResourceGroupName \
--vnet-name $virtualNetworkName \
--name $subnetName \
--query "id" | \
tr -d '"')
若要创建专用终结点,首先必须确保子网的专用终结点网络策略设置为“已禁用”。 然后,可以使用 az network private-endpoint create 命令创建专用终结点。
# Disable private endpoint network policies
az network vnet subnet update \
--ids $subnet \
--disable-private-endpoint-network-policies \
--output none
# Get virtual network location
region=$(az network vnet show \
--ids $virtualNetwork \
--query "location" | \
tr -d '"')
# Create a private endpoint
privateEndpoint=$(az network private-endpoint create \
--resource-group $storageAccountResourceGroupName \
--name "$storageAccountName-PrivateEndpoint" \
--location $region \
--subnet $subnet \
--private-connection-resource-id $storageAccount \
--group-id "file" \
--connection-name "$storageAccountName-Connection" \
--query "id" | \
tr -d '"')
创建 Azure 专用 DNS 区域可将存储帐户的原始名称(例如 storageaccount.file.core.windows.net)解析为虚拟网络内部的专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果使用 AD 用户主体装载或通过 REST API 访问 Azure 文件共享,则此操作肯定是必需的。
# Get the desired storage account suffix (core.windows.net for public cloud).
# This is done like this so this script will seamlessly work for non-public Azure.
storageAccountSuffix=$(az cloud show \
--query "suffixes.storageEndpoint" | \
tr -d '"')
# For public cloud, this will generate the following DNS suffix:
# privatelink.file.core.windows.net.
dnsZoneName="privatelink.file.$storageAccountSuffix"
# Find a DNS zone matching desired name attached to this virtual network.
possibleDnsZones=""
possibleDnsZones=$(az network private-dns zone list \
--query "[?name == '$dnsZoneName'].id" \
--output tsv)
dnsZone=""
possibleDnsZone=""
for possibleDnsZone in $possibleDnsZones
do
possibleResourceGroupName=$(az resource show \
--ids $possibleDnsZone \
--query "resourceGroup" | \
tr -d '"')
link=$(az network private-dns link vnet list \
--resource-group $possibleResourceGroupName \
--zone-name $dnsZoneName \
--query "[?virtualNetwork.id == '$virtualNetwork'].id" \
--output tsv)
if [ -z $link ]
then
echo "1" > /dev/null
else
dnsZoneResourceGroup=$possibleResourceGroupName
dnsZone=$possibleDnsZone
break
fi
done
if [ -z $dnsZone ]
then
# No matching DNS zone attached to virtual network, so create a new one
dnsZone=$(az network private-dns zone create \
--resource-group $virtualNetworkResourceGroupName \
--name $dnsZoneName \
--query "id" | \
tr -d '"')
az network private-dns link vnet create \
--resource-group $virtualNetworkResourceGroupName \
--zone-name $dnsZoneName \
--name "$virtualNetworkName-DnsLink" \
--virtual-network $virtualNetwork \
--registration-enabled false \
--output none
dnsZoneResourceGroup=$virtualNetworkResourceGroupName
fi
获取对专用 DNS 区域的引用后,接下来必须创建存储帐户的 A 记录。
privateEndpointNIC=$(az network private-endpoint show \
--ids $privateEndpoint \
--query "networkInterfaces[0].id" | \
tr -d '"')
privateEndpointIP=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[0].privateIPAddress" | \
tr -d '"')
az network private-dns record-set a create \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--name $storageAccountName \
--output none
az network private-dns record-set a add-record \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--record-set-name $storageAccountName \
--ipv4-address $privateEndpointIP \
--output none
如果你的虚拟网络中有虚拟机,或者你按照“配置 Azure 文件存储 DNS 转发”中描述的配置了 DNS,可以通过以下命令测试你的私有端点是否正确设置:
httpEndpoint=$(az storage account show \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--query "primaryEndpoints.file" | \
tr -d '"')
hostName=$(echo $httpEndpoint | cut -c7-$(expr length $httpEndpoint) | tr -d "/")
nslookup $hostName
如果一切成功进行,则应会看到以下输出,其中 192.168.0.5 是虚拟网络中专用终结点的专用 IP 地址:
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
storageaccount.file.core.windows.net canonical name = storageaccount.privatelink.file.core.windows.net.
Name: storageaccount.privatelink.file.core.windows.net
Address: 192.168.0.5
创建存储同步服务专用终结点
在Azure门户顶部的搜索栏输入“专用链接”,前往专用链接中心。 在 专用链接 Center 的目录中,选择 Private 端点,然后选择 + 添加以创建新的私有端点。
生成的向导有多个需要填写的页面。
在 基础 标签中,选择私有端点的资源组、名称和区域。 这些值可以是任何有效的值。 它们不需要在任何方面与存储同步服务匹配,但你必须在与你选择的虚拟网络相同的区域创建私有端点。
在“资源”选项卡中选择“连接到目录中的 Azure 资源” 。 在资源类型中,选择Microsoft。存储同步/存储同步服务。
配置标签允许你选择想要添加私有端点的特定虚拟网络和子网。 选择与你用来存储账户的虚拟网络相同的网络。
配置标签页还包含创建和更新私有DNS区域的信息。
选择“查看 + 创建”以创建专用终结点。
可以通过运行以下 PowerShell 命令来测试专用终结点是否已正确设置。
$privateEndpointResourceGroupName = "<your-private-endpoint-resource-group>"
$privateEndpointName = "<your-private-endpoint-name>"
Get-AzPrivateEndpoint `
-ResourceGroupName $privateEndpointResourceGroupName `
-Name $privateEndpointName `
-ErrorAction Stop | `
Select-Object -ExpandProperty NetworkInterfaces | `
Select-Object -ExpandProperty Id | `
ForEach-Object { Get-AzNetworkInterface -ResourceId $_ } | `
Select-Object -ExpandProperty IpConfigurations | `
Select-Object -ExpandProperty PrivateLinkConnectionProperties | `
Select-Object -ExpandProperty Fqdns | `
ForEach-Object { Resolve-DnsName -Name $_ } | `
Format-List
如果一切设置正确,则应看到以下输出,其中 192.168.1.4、192.168.1.5、192.168.1.6 和 192.168.1.7 是分配给专用终结点的专用 IP 地址:
Name : mysssmanagement.westus2.afs.azure.net
Type : CNAME
TTL : 60
Section : Answer
NameHost : mysssmanagement.westus2.privatelink.afs.azure.net
Name : mysssmanagement.westus2.privatelink.afs.azure.net
QueryType : A
TTL : 60
Section : Answer
IP4Address : 192.168.1.4
Name : myssssyncp.westus2.afs.azure.net
Type : CNAME
TTL : 60
Section : Answer
NameHost : myssssyncp.westus2.privatelink.afs.azure.net
Name : myssssyncp.westus2.privatelink.afs.azure.net
QueryType : A
TTL : 60
Section : Answer
IP4Address : 192.168.1.5
Name : myssssyncs.westus2.afs.azure.net
Type : CNAME
TTL : 60
Section : Answer
NameHost : myssssyncs.westus2.privatelink.afs.azure.net
Name : myssssyncs.westus2.privatelink.afs.azure.net
QueryType : A
TTL : 60
Section : Answer
IP4Address : 192.168.1.6
Name : mysssmonitoring.westus2.afs.azure.net
Type : CNAME
TTL : 60
Section : Answer
NameHost : mysssmonitoring.westus2.privatelink.afs.azure.net
Name : mysssmonitoring.westus2.privatelink.afs.azure.net
QueryType : A
TTL : 60
Section : Answer
IP4Address : 192.168.1.7
要为存储同步服务创建专用终结点,首先需要获取对存储同步服务的引用。 将 <storage-sync-service-resource-group> 和 <storage-sync-service> 替换为对你的环境而言正确的值。 以下PowerShell命令假设你已经填充了虚拟网络信息。
$storageSyncServiceResourceGroupName = "<storage-sync-service-resource-group>"
$storageSyncServiceName = "<storage-sync-service>"
$storageSyncService = Get-AzStorageSyncService `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name $storageSyncServiceName `
-ErrorAction SilentlyContinue
if ($null -eq $storageSyncService) {
$errorMessage = "Storage Sync Service $storageSyncServiceName not found "
$errorMessage += "in resource group $storageSyncServiceResourceGroupName."
Write-Error -Message $errorMessage -ErrorAction Stop
}
若要创建专用终结点,必须与存储同步服务建立专用链接服务连接。 专用链接连接是创建专用终结点时使用的输入。
# Disable private endpoint network policies
$subnet.PrivateEndpointNetworkPolicies = "Disabled"
$virtualNetwork = $virtualNetwork | `
Set-AzVirtualNetwork -ErrorAction Stop
# Create a private link service connection to the storage account
$privateEndpointConnection = New-AzPrivateLinkServiceConnection `
-Name "$storageSyncServiceName-Connection" `
-PrivateLinkServiceId $storageSyncService.ResourceId `
-GroupId "Afs" `
-ErrorAction Stop
# Create a new private endpoint
$privateEndpoint = New-AzPrivateEndpoint `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name "$storageSyncServiceName-PrivateEndpoint" `
-Location $virtualNetwork.Location `
-Subnet $subnet `
-PrivateLinkServiceConnection $privateEndpointConnection `
-ErrorAction Stop
通过创建 Azure 专用 DNS 区域,存储同步服务的主机名(如 mysssmanagement.westus2.afs.azure.net)可解析为虚拟网络内的存储同步服务的正确专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果 Azure 文件同步代理要访问存储同步服务,则此操作肯定是必需的。
# Get the desired Storage Sync Service suffix (afs.azure.net for public cloud)
# This is done like this so this script will seamlessly work for non-public Azure
$azureEnvironment = Get-AzContext | `
Select-Object -ExpandProperty Environment | `
Select-Object -ExpandProperty Name
switch($azureEnvironment) {
"AzureCloud" {
$storageSyncSuffix = "afs.azure.net"
}
"AzureUSGovernment" {
$storageSyncSuffix = "afs.azure.us"
}
"AzureChinaCloud" {
$storageSyncSuffix = "afs.azure.cn"
}
default {
Write-Error
-Message "The Azure environment $_ is not currently supported by Azure File Sync." `
-ErrorAction Stop
}
}
# For public cloud, this will generate the following DNS suffix:
# privatelink.afs.azure.net
$dnsZoneName = "privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network
$dnsZone = Get-AzPrivateDnsZone | `
Where-Object { $_.Name -eq $dnsZoneName } | `
Where-Object {
$privateDnsLink = Get-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $_.ResourceGroupName `
-ZoneName $_.Name `
-ErrorAction SilentlyContinue
$privateDnsLink.VirtualNetworkId -eq $virtualNetwork.Id
}
if ($null -eq $dnsZone) {
# No matching DNS zone attached to virtual network, so create a new one
$dnsZone = New-AzPrivateDnsZone `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsZoneName `
-ErrorAction Stop
$privateDnsLink = New-AzPrivateDnsVirtualNetworkLink `
-ResourceGroupName $virtualNetworkResourceGroupName `
-ZoneName $dnsZoneName `
-Name "$virtualNetworkName-DnsLink" `
-VirtualNetworkId $virtualNetwork.Id `
-ErrorAction Stop
}
获取对专用 DNS 区域的引用后,接下来必须创建存储同步服务的 A 记录。
$privateEndpointIpFqdnMappings = $privateEndpoint | `
Select-Object -ExpandProperty NetworkInterfaces | `
Select-Object -ExpandProperty Id | `
ForEach-Object { Get-AzNetworkInterface -ResourceId $_ } | `
Select-Object -ExpandProperty IpConfigurations | `
ForEach-Object {
$privateIpAddress = $_.PrivateIpAddress;
$_ | `
Select-Object -ExpandProperty PrivateLinkConnectionProperties | `
Select-Object -ExpandProperty Fqdns | `
Select-Object `
@{
Name = "PrivateIpAddress";
Expression = { $privateIpAddress }
}, `
@{
Name = "FQDN";
Expression = { $_ }
}
}
foreach($ipFqdn in $privateEndpointIpFqdnMappings) {
$privateDnsRecordConfig = New-AzPrivateDnsRecordConfig `
-IPv4Address $ipFqdn.PrivateIpAddress
$dnsEntry = $ipFqdn.FQDN.Substring(0,
$ipFqdn.FQDN.IndexOf(".", $ipFqdn.FQDN.IndexOf(".") + 1))
New-AzPrivateDnsRecordSet `
-ResourceGroupName $virtualNetworkResourceGroupName `
-Name $dnsEntry `
-RecordType A `
-ZoneName $dnsZoneName `
-Ttl 600 `
-PrivateDnsRecords $privateDnsRecordConfig `
-ErrorAction Stop | `
Out-Null
}
要为存储同步服务创建专用终结点,首先需要获取对存储同步服务的引用。 将 <storage-sync-service-resource-group> 和 <storage-sync-service> 替换为对你的环境而言正确的值。 以下CLI命令假设你已经填充了虚拟网络信息。
storageSyncServiceResourceGroupName="<storage-sync-service-resource-group>"
storageSyncServiceName="<storage-sync-service>"
storageSyncService=$(az resource show \
--resource-group $storageSyncServiceResourceGroupName \
--name $storageSyncServiceName \
--resource-type "Microsoft.StorageSync/storageSyncServices" \
--query "id" | \
tr -d '"')
storageSyncServiceRegion=$(az resource show \
--resource-group $storageSyncServiceResourceGroupName \
--name $storageSyncServiceName \
--resource-type "Microsoft.StorageSync/storageSyncServices" \
--query "location" | \
tr -d '"')
要创建私有端点,首先确保子网的私有端点网络策略被 设置为禁用。 然后用命令 az network private-endpoint create 创建一个私有端点。
# Disable private endpoint network policies
az network vnet subnet update \
--ids $subnet \
--disable-private-endpoint-network-policies \
--output none
# Get virtual network location
region=$(az network vnet show \
--ids $virtualNetwork \
--query "location" | \
tr -d '"')
# Create a private endpoint
privateEndpoint=$(az network private-endpoint create \
--resource-group $storageSyncServiceResourceGroupName \
--name "$storageSyncServiceName-PrivateEndpoint" \
--location $region \
--subnet $subnet \
--private-connection-resource-id $storageSyncService \
--group-id "Afs" \
--connection-name "$storageSyncServiceName-Connection" \
--query "id" | \
tr -d '"')
通过创建 Azure 专用 DNS 区域,存储同步服务的主机名(如 mysssmanagement.westus2.afs.azure.net)可解析为虚拟网络内的存储同步服务的正确专用 IP。 尽管从创建专用终结点的角度来看,此操作是可选的,但如果 Azure 文件同步代理要访问存储同步服务,则此操作肯定是必需的。
# Get the desired storage account suffix (afs.azure.net for public cloud)
# This is done like this so this script will seamlessly work for non-public Azure
azureEnvironment=$(az cloud show \
--query "name" |
tr -d '"')
storageSyncSuffix=""
if [ $azureEnvironment == "AzureCloud" ]
then
storageSyncSuffix="afs.azure.net"
elif [ $azureEnvironment == "AzureUSGovernment" ]
then
storageSyncSuffix="afs.azure.us"
else
echo "Unsupported Azure environment $azureEnvironment."
fi
# For public cloud, this will generate the following DNS suffix:
# privatelink.afs.azure.net
dnsZoneName="privatelink.$storageSyncSuffix"
# Find a DNS zone matching desired name attached to this virtual network
possibleDnsZones=""
possibleDnsZones=$(az network private-dns zone list \
--query "[?name == '$dnsZoneName'].id" \
--output tsv)
dnsZone=""
possibleDnsZone=""
for possibleDnsZone in $possibleDnsZones
do
possibleResourceGroupName=$(az resource show \
--ids $possibleDnsZone \
--query "resourceGroup" | \
tr -d '"')
link=$(az network private-dns link vnet list \
--resource-group $possibleResourceGroupName \
--zone-name $dnsZoneName \
--query "[?virtualNetwork.id == '$virtualNetwork'].id" \
--output tsv)
if [ -z $link ]
then
echo "1" > /dev/null
else
dnsZoneResourceGroup=$possibleResourceGroupName
dnsZone=$possibleDnsZone
break
fi
done
if [ -z $dnsZone ]
then
# No matching DNS zone attached to virtual network, so create a new one
dnsZone=$(az network private-dns zone create \
--resource-group $virtualNetworkResourceGroupName \
--name $dnsZoneName \
--query "id" | \
tr -d '"')
az network private-dns link vnet create \
--resource-group $virtualNetworkResourceGroupName \
--zone-name $dnsZoneName \
--name "$virtualNetworkName-DnsLink" \
--virtual-network $virtualNetwork \
--registration-enabled false \
--output none
dnsZoneResourceGroup=$virtualNetworkResourceGroupName
fi
获取对专用 DNS 区域的引用后,接下来必须创建存储同步服务的 A 记录。
privateEndpointNIC=$(az network private-endpoint show \
--ids $privateEndpoint \
--query "networkInterfaces[0].id" | \
tr -d '"')
privateIpAddresses=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[].privateIpAddress" \
--output tsv)
hostNames=$(az network nic show \
--ids $privateEndpointNIC \
--query "ipConfigurations[].privateLinkConnectionProperties.fqdns[]" \
--output tsv)
i=0
for privateIpAddress in $privateIpAddresses
do
j=0
targetHostName=""
for hostName in $hostNames
do
if [ $i == $j ]
then
targetHostName=$hostName
break
fi
j=$(expr $j + 1)
done
endpointName=$(echo $targetHostName | \
cut -c1-$(expr $(expr index $targetHostName ".") - 1))
az network private-dns record-set a create \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--name "$endpointName.$storageSyncServiceRegion" \
--output none
az network private-dns record-set a add-record \
--resource-group $dnsZoneResourceGroup \
--zone-name $dnsZoneName \
--record-set-name "$endpointName.$storageSyncServiceRegion" \
--ipv4-address $privateIpAddress \
--output none
i=$(expr $i + 1)
done
限制对公共终结点的访问
可以限制对存储帐户和存储同步服务的公共终结点的访问。 限制对公共终结点的访问可确保仅从批准的位置接受网络数据包,从而提高安全性。
限制对存储帐户公共终结点的访问
你可以通过存储账户的防火墙设置来限制对公共端点的访问。 通常,大多数针对存储帐户的防火墙策略仅限一个或多个虚拟网络进行网络访问。 若要限制对虚拟网络存储帐户的访问,请使用以下方法之一:
-
为存储帐户创建一个或多个专用终结点,并禁止对公共终结点的访问。 这可以确保只有源自所需虚拟网络内部的流量才能访问存储帐户中的 Azure 文件共享。
- 将公共终结点限制为只能由一个或多个虚拟网络访问。 该方法通过利用虚拟网络中的 服务端点功能来实现。 当你通过服务端点限制流量到某个存储账户时,你仍然通过公共IP访问该存储账户。
备注
要允许可信的第一方 Microsoft 服务(如 Azure 文件同步)访问存储账户,请在你的存储账户上选择“允许可信的 Microsoft 服务 访问此资源”复选框。 更多信息请参见 “限制对公共端点的访问仅限特定网络”。
重要
Azure 文件同步对于网络安全边界 (NSP) 存在已知限制。
存储同步服务不能放置在外围内,并且不支持完整的外围集成。
将存储同步服务连接到由 NSP 保护的存储帐户:
- 将存储同步服务配置为使用 托管标识。
- 创建一个 NSP 入站配置文件规则,将托管存储同步服务的订阅加入允许列表。
存储同步服务必须保留在外围之外,才能正常进行同步。
授予对受信任的 Azure 服务的访问权限并禁用对存储帐户公共终结点的访问权限
当你禁用对公共端点的访问时,仍可以通过其私有端点访问该存储账户,但对存储账户公用端点的请求会被拒绝。
导航到您想限制所有公共终结点访问的存储帐户。 在该存储帐户的目录中,选择“网络”。
在页面顶部,选择“从所选虚拟网络和 IP 地址启用”单选按钮。 随后会显示一些用于控制公共终结点限制的设置。 选择“允许受信任服务列表上的 Azure 服务访问此存储帐户”,以允许受信任的第一方 Microsoft 服务(例如 Azure 文件同步)访问存储帐户。
以下 PowerShell 命令将拒绝发往存储帐户公共终结点的所有流量。 请注意,此命令的 -Bypass 参数设置为 AzureServices。 这会允许受信任的第一方服务(例如 Azure 文件同步)通过公共终结点访问存储帐户。
# This assumes $storageAccount is still defined from the beginning of this of this guide.
$storageAccount | Update-AzStorageAccountNetworkRuleSet `
-DefaultAction Deny `
-Bypass AzureServices `
-WarningAction SilentlyContinue `
-ErrorAction Stop | `
Out-Null
以下 CLI 命令将拒绝发往存储帐户公共终结点的所有流量。 请注意,此命令的 -bypass 参数设置为 AzureServices。 这会允许受信任的第一方服务(例如 Azure 文件同步)通过公共终结点访问存储帐户。
# This assumes $storageAccountResourceGroupName and $storageAccountName
# are still defined from the beginning of this guide.
az storage account update \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--bypass "AzureServices" \
--default-action "Deny" \
--output none
授予对受信任的 Azure 服务的访问权限,并仅限从特定的虚拟网络访问存储帐户公共终结点
如果仅限从特定的虚拟网络访问存储帐户,则会允许从指定的虚拟网络内部对公共终结点发出请求。 为此,可以使用称作“服务终结点”的虚拟网络功能。 在具有或没有专用终结点的情况下都可以使用此功能。
导航到您想要将公共终结点限制为特定虚拟网络的存储帐户。 在该存储帐户的目录中,选择“网络”。
在页面顶部,选择“从所选虚拟网络和 IP 地址启用”单选按钮。 随后会显示一些用于控制公共终结点限制的设置。 选择“+添加现有虚拟网络”,以选择应允许其通过公共终结点访问存储帐户的特定虚拟网络。 选择虚拟网络并为该虚拟网络选择子网,然后选择“启用”。
选择“允许受信任服务列表上的 Azure 服务访问此存储帐户”,以允许受信任的第一方 Microsoft 服务(例如 Azure 文件同步)访问存储帐户。
若要仅限特定的虚拟网络使用服务终结点访问存储帐户的公共终结点,首先需要收集有关该存储帐户和虚拟网络的信息。 填写 <storage-account-resource-group>、<storage-account-name>、<vnet-resource-group-name>、<vnet-name> 和 <subnet-name> 以收集此信息。
$storageAccountResourceGroupName = "<storage-account-resource-group>"
$storageAccountName = "<storage-account-name>"
$restrictToVirtualNetworkResourceGroupName = "<vnet-resource-group-name>"
$restrictToVirtualNetworkName = "<vnet-name>"
$subnetName = "<subnet-name>"
$storageAccount = Get-AzStorageAccount `
-ResourceGroupName $storageAccountResourceGroupName `
-Name $storageAccountName `
-ErrorAction Stop
$virtualNetwork = Get-AzVirtualNetwork `
-ResourceGroupName $restrictToVirtualNetworkResourceGroupName `
-Name $restrictToVirtualNetworkName `
-ErrorAction Stop
$subnet = $virtualNetwork | `
Select-Object -ExpandProperty Subnets | `
Where-Object { $_.Name -eq $subnetName }
if ($null -eq $subnet) {
Write-Error `
-Message "Subnet $subnetName not found in virtual network $restrictToVirtualNetworkName." `
-ErrorAction Stop
}
要使 Azure 网络结构允许来自该虚拟网络的流量进入存储帐户公共终结点,该虚拟网络的子网必须公开 Microsoft.Storage 服务终结点。 以下 PowerShell 命令将 Microsoft.Storage 服务终结点添加到子网(如果其中不存在该服务终结点)。
$serviceEndpoints = $subnet | `
Select-Object -ExpandProperty ServiceEndpoints | `
Select-Object -ExpandProperty Service
if ($serviceEndpoints -notcontains "Microsoft.Storage") {
if ($null -eq $serviceEndpoints) {
$serviceEndpoints = @("Microsoft.Storage")
} elseif ($serviceEndpoints -is [string]) {
$serviceEndpoints = @($serviceEndpoints, "Microsoft.Storage")
} else {
$serviceEndpoints += "Microsoft.Storage"
}
$virtualNetwork = $virtualNetwork | Set-AzVirtualNetworkSubnetConfig `
-Name $subnetName `
-AddressPrefix $subnet.AddressPrefix `
-ServiceEndpoint $serviceEndpoints `
-WarningAction SilentlyContinue `
-ErrorAction Stop | `
Set-AzVirtualNetwork `
-ErrorAction Stop
}
限制发往存储帐户的流量的最后一步是创建网络规则并将其添加到存储帐户的网络规则集。
$networkRule = $storageAccount | Add-AzStorageAccountNetworkRule `
-VirtualNetworkResourceId $subnet.Id `
-ErrorAction Stop
$storageAccount | Update-AzStorageAccountNetworkRuleSet `
-DefaultAction Deny `
-Bypass AzureServices `
-VirtualNetworkRule $networkRule `
-WarningAction SilentlyContinue `
-ErrorAction Stop | `
Out-Null
若要仅限特定的虚拟网络使用服务终结点访问存储帐户的公共终结点,首先需要收集有关该存储帐户和虚拟网络的信息。 填写 <storage-account-resource-group>、<storage-account-name>、<vnet-resource-group-name>、<vnet-name> 和 <subnet-name> 以收集此信息。
storageAccountResourceGroupName="<storage-account-resource-group>"
storageAccountName="<storage-account-name>"
restrictToVirtualNetworkResourceGroupName="<vnet-resource-group-name>"
restrictToVirtualNetworkName="<vnet-name>"
subnetName="<subnet-name>"
storageAccount=$(az storage account show \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--query "id" | \
tr -d '"')
virtualNetwork=$(az network vnet show \
--resource-group $restrictToVirtualNetworkResourceGroupName \
--name $restrictToVirtualNetworkName \
--query "id" | \
tr -d '"')
subnet=$(az network vnet subnet show \
--resource-group $restrictToVirtualNetworkResourceGroupName \
--vnet-name $restrictToVirtualNetworkName \
--name $subnetName \
--query "id" | \
tr -d '"')
要使 Azure 网络结构允许来自该虚拟网络的流量进入存储帐户公共终结点,该虚拟网络的子网必须公开 Microsoft.Storage 服务终结点。 以下 CLI 命令将 Microsoft.Storage 服务终结点添加到子网(如果其中不存在该服务终结点)。
serviceEndpoints=$(az network vnet subnet show \
--resource-group $restrictToVirtualNetworkResourceGroupName \
--vnet-name $restrictToVirtualNetworkName \
--name $subnetName \
--query "serviceEndpoints[].service" \
--output tsv)
foundStorageServiceEndpoint=false
for serviceEndpoint in $serviceEndpoints
do
if [ $serviceEndpoint = "Microsoft.Storage" ]
then
foundStorageServiceEndpoint=true
fi
done
if [ $foundStorageServiceEndpoint = false ]
then
serviceEndpointList=""
for serviceEndpoint in $serviceEndpoints
do
serviceEndpointList+=$serviceEndpoint
serviceEndpointList+=" "
done
serviceEndpointList+="Microsoft.Storage"
az network vnet subnet update \
--ids $subnet \
--service-endpoints $serviceEndpointList \
--output none
fi
限制发往存储帐户的流量的最后一步是创建网络规则并将其添加到存储帐户的网络规则集。
az storage account network-rule add \
--resource-group $storageAccountResourceGroupName \
--account-name $storageAccountName \
--subnet $subnet \
--output none
az storage account update \
--resource-group $storageAccountResourceGroupName \
--name $storageAccountName \
--bypass "AzureServices" \
--default-action "Deny" \
--output none
禁止对存储同步服务公共终结点的访问
Azure 文件同步允许你仅通过专用终结点限制对特定虚拟网络的访问;Azure 文件同步不支持使用服务终结点来限制公共终结点的访问,仅限于特定虚拟网络。 这意味着存储同步服务的公共终结点的两个状态为“已启用”和“已禁用”。
重要
必须先创建专用终结点,然后才能禁用对公共终结点的访问。 如果禁用了公共终结点,但未配置专用终结点,则无法同步。
若要禁用对存储同步服务公共终结点的访问,请执行以下步骤:
- 登录 Azure 门户。
- 进入存储同步服务,从左侧导航中选择 设置>网络 。
- 在“允许访问来源”下,选择“仅限私有终结点”。
- 从“专用终结点连接”列表中选择一个专用终结点。
要禁用对存储同步服务公共端点的访问,请将存储同步服务incomingTrafficPolicy的属性设置为 AllowVirtualNetworksOnly 。 要启用对存储同步服务公共端点的访问,请设 incomingTrafficPolicy 为 AllowAllTraffic。 将 <storage-sync-service-resource-group> 和 <storage-sync-service> 替换为自己的值。
$storageSyncServiceResourceGroupName = "<storage-sync-service-resource-group>"
$storageSyncServiceName = "<storage-sync-service>"
Set-AzStorageSyncService `
-ResourceGroupName $storageSyncServiceResourceGroupName `
-Name $storageSyncServiceName `
-IncomingTrafficPolicy AllowVirtualNetworksOnly
Azure CLI 不支持在存储同步服务上设置 incomingTrafficPolicy 属性。 选择 Azure PowerShell 标签页,获取如何禁用存储同步服务公共端点的说明。
用于 Azure 文件和 Azure 文件同步的 Azure 策略
Azure Policy 可帮助强制执行组织标准并根据这些标准大规模评估合规性。 Azure 文件存储和 Azure 文件同步公开了几个有用的审核和修正网络策略,可帮助你监视和自动执行部署。
这些策略会审核你的环境,并在你的存储帐户或存储同步服务与定义的行为相背离时向你发出警报。 例如,如果某个公共终结点已启用,而你的策略设置为禁用公共终结点,则该策略会提醒你。 修改和部署策略可以主动修改资源(如存储同步服务)或部署资源(如私有端点)以符合策略。
以下预定义策略可用于 Azure 文件存储和 Azure 文件同步:
| 操作 |
服务 |
条件 |
策略名称 |
| 审核 |
Azure 文件存储 |
已启用存储帐户的公共终结点。 有关详细信息,请参阅授予对受信任的 Azure 服务的访问权限并禁用对存储帐户公共终结点的访问权限。 |
存储帐户应限制网络访问 |
| 审核 |
Azure 文件同步 |
已启用存储同步服务的公共终结点。 有关详细信息,请参阅禁止访问存储同步服务公共终结点。 |
应禁用对 Azure 文件同步进行公用网络访问 |
| 审核 |
Azure 文件存储 |
存储帐户需要至少一个专用终结点。 有关详细信息,请参阅创建存储帐户专用终结点。 |
存储帐户应使用专用链接连接 |
| 审核 |
Azure 文件同步 |
存储同步服务需要至少一个专用终结点。 有关详细信息,请参阅创建存储同步服务专用终结点。 |
Azure 文件同步应使用专用链接 |
| 修改 |
Azure 文件同步 |
禁用存储同步服务的公共终结点。 |
修改 - 将 Azure 文件同步配置为禁用公用网络访问 |
| 部署 |
Azure 文件同步 |
为存储同步服务部署专用终结点。 |
为 Azure 文件同步配置专用终结点 |
| 部署 |
Azure 文件同步 |
将 A 记录部署到 privatelink.afs.azure.net DNS 区域。 |
将 Azure 文件同步配置为使用专用 DNS 区域 |
设置专用终结点部署策略
要设置私有端点部署策略,请遵循以下步骤:
- 登录 Azure 门户,搜索“策略”。 从结果中选择 政策 。
- 请访问政策中心目录中的“作者定义>”。
- 在定义面板中,选择类别筛选中的存储类别,或搜索“配置 Azure 文件同步 with Private endpoints”。
- 在政策旁边选择 ...... 然后选择 分配。
- 在 基本信息 页面上,可选择设置策略的范围、排除列表和易记名称。 选择“下一步”。
- 在 参数 页面,选择 ... ,位于 privateEndpointSubnetId 字段旁边。 选择虚拟网络和子网,用于部署存储同步服务资源的私有端点。 向导加载可用虚拟网络可能需要几秒钟。 选择“下一步”。
- 在 修复 页面,选择 创建修复任务 ,当识别出没有私有端点的存储同步服务时,私有端点会被部署。
- 选择 审核+创建 以查看政策分配,然后选择 创建。
生成的策略分配将定期执行,在创建后可能不会立即运行。
另请参阅