修正对 blob 数据的匿名读取访问(经典部署)

Azure Blob 存储支持对容器和 blob 进行可选的匿名读取访问。 但是,匿名访问可能会带来安全风险。 建议禁用匿名访问,以获得最佳安全性。 禁止匿名访问有助于防止意外匿名访问导致的数据泄露。

默认情况下,始终会禁止对 blob 数据的匿名访问。 但是,经典存储帐户的默认配置允许具有适当权限的用户配置对存储帐户中的容器和 blob 的匿名访问。 要防止对经典存储帐户进行匿名访问,必须将帐户中的每个容器配置为阻止匿名访问。

如果存储帐户使用经典部署模型,建议尽快迁移到 Azure 资源管理器部署模型。 迁移帐户后,可以将其配置为禁止在帐户级别进行匿名访问。 有关如何禁止对 Azure 资源管理器帐户进行匿名访问的信息,请参阅修正对 blob 数据的匿名读取访问(Azure 资源管理器部署)

如果目前无法迁移经典存储帐户,则应通过将所有容器设置为专用来修正对这些帐户的匿名访问。 本文介绍如何修正对经典存储帐户中容器的访问。

使用经典部署模型的 Azure 存储帐户将于 2024 年 8 月 31 日停用。 有关详细信息,请参阅 Azure 经典存储帐户将于 2024 年 8 月 31 日停用

警告

匿名访问会带来安全风险。 建议执行以下部分中所述的操作,以修正所有经典存储帐户的匿名访问,除非你的方案特别需要匿名访问。

阻止对容器的匿名访问

要修正经典存储帐户的匿名访问,请将帐户中每个容器的匿名访问级别设置为“专用”。

要在 Azure 门户中修正一个或多个容器的匿名访问,请执行以下步骤:

  1. 在 Azure 门户中导航到存储帐户概述。

  2. 在菜单边栏选项卡上的“数据存储”下,选择“Blob 容器” 。

  3. 选择要对其设置匿名访问级别的容器。

  4. 使用“更改访问级别”按钮显示访问设置。

  5. 从“匿名访问级别”下拉列表中选择“专用(无匿名访问)”,然后单击“确定”按钮应用对选定容器的更改。

    Screenshot showing how to set anonymous access level in the portal.

检查一组容器的匿名访问设置

可以通过列出容器并检查匿名访问设置来检查为一个或多个存储帐户中的哪些容器配置了匿名访问。 当存储帐户未包含大量容器时,或者当你检查少量存储帐户的设置时,此方法是一个可行的选项。 但是,如果你尝试枚举大量的容器,则性能可能会降低。

以下示例使用 PowerShell 获取某个存储帐户中所有容器的匿名访问设置。 请记得将括号中的占位符值替换为你自己的值:

$rgName = "<resource-group>"
$accountName = "<storage-account>"

$storageAccount = Get-AzStorageAccount -ResourceGroupName $rgName -Name $accountName
$ctx = $storageAccount.Context

Get-AzStorageContainer -Context $ctx | Select Name, PublicAccess

批量修正的示例脚本

以下示例 PowerShell 脚本针对订阅中的所有经典存储帐户运行,并将这些帐户中的容器的匿名访问设置设为“专用”。

注意

针对具有极大量容器的存储帐户运行此脚本可能需要大量资源,并且需要很长时间。 如果有一个包含大量容器的存储帐户,则可能需要设计一种不同的方法来修正匿名访问。

# This script runs against all classic storage accounts in a single subscription
# and sets containers to private.

## IMPORTANT ##
# Running this script requires a connected account through the previous version 
# of Azure PowerShell. Use the following command to install:
# Install-Module Azure -scope CurrentUser -force
#
# Once installed, you will need to connect with:
# Add-AzureAccount -Environment AzureChinaCloud
#
# This command may fail if there are modules installed that conflict with it.
# One known conflicting module is AzureRm.Accounts
# You will need to remove conflicting modules using the following:
# Remove-Module -name <name>
#
# The Azure PowerShell module assumes a current subscription when enumerating
# storage accounts.  You can set the current subscription with:
# Select-AzureSubscription -subscriptionId <subscriptionId>
#
# Get-AzureSubscription lists all subscriptions available to the Azure
# module. Not all subscriptions listed under your name in the portal may 
# appear here. If a subscription does not appear, you may need to use 
# the portal to remediate public access for those accounts.
# After you have selected your subscription, verify that it is current
# by running:
# Get-AzureSubscription -current
# 
# After the current subscription runs, you can run this script, change
# to another subscription after it completes, and then run again as necessary.
## END IMPORTANT##

# Standard operation will enumerate all accounts and check for containers with public 
# access, then allow the user to decide whether or not to disable the setting.  

# Run with BypassConfirmation=$true if you wish to remove permissions from all containers
# without individual confirmation

# Run with BypassArmUpgrade=$true if you wish to upgrade your storage account to use the 
# Azure Resource Manager deployment model. All accounts must be upgraded by 31 August 2024.

param(
    [boolean]$BypassConfirmation=$false,
    [boolean]$BypassArmUpgrade=$false
)

#Do not change this
$convertAccounts = $false

foreach($classicAccount in Get-AzureStorageAccount)
{
    $enumerate = $false

    if(!$BypassArmUpgrade)
    {
        write-host "Classic Storage Account" $classicAccount.storageAccountname "found"
        $confirmation = read-host "Convert to ARM? [y/n]:"
    }
    if(($confirmation -eq 'y') -and (!$BypassArmUpgrade))
    {
        write-host "Conversion selected"
        $convertAccounts = $true
    }
    else
    {
        write-host $classicAccount.StorageAccountName "conversion not selected.  Searching for public containers..."
        $enumerate = $true
    }

    if($enumerate)
    {
        foreach($container in get-azurestoragecontainer -context (get-azurestorageaccount -storageaccountname $classicAccount.StorageAccountName).context)
        {
            if($container.PublicAccess -eq 'Off')
            {
            } 
            else 
            {
                if(!$BypassConfirmation)
                {
                    $selection = read-host $container.Name $container.PublicAccess "access found, Make private?[y/n]:"
                }
                if(($selection -eq 'y') -or ($BypassConfirmation))
                {
                    write-host "Removing permissions from" $container.name "container on storage account" $classicaccount.StorageAccountName
                    try
                    {
                        Set-AzureStorageContainerAcl -context $classicAccount.context -name $container.name -Permission Off
                        write-host "Success!"
                    }
                    catch
                    {
                        $_
                    }
                }
                else
                {
                    write-host "Skipping..."
                }
            }
        }
    }
}
if($convertAccounts)
{
    write-host "Converting accounts to ARM is the preferred method, however there are some caveats."
    write-host "The preferred method would be to use the portal to perform the conversions and then "
    write-host "run the ARM script against them.  For more information on converting a classic account"
    write-host "to an ARM account, please see:"
    write-host "https://docs.azure.cn/virtual-machines/migration-classic-resource-manager-overview"
}
write-host "Script complete"

另请参阅