阻止对容器和 Blob 的匿名公共读取访问

对 Azure 存储中的容器和 blob 进行匿名公共读取访问虽然是共享数据的一种简便方法,但也可能会带来安全风险。 请务必谨慎管理匿名访问,并了解如何评估对数据的匿名访问。 操作复杂性、人为错误或对可公共访问的数据的恶意攻击可能会导致代价高昂的数据泄露。 Azure 建议仅在必要时为应用程序方案启用匿名访问。

默认情况下,始终会禁止对 blob 数据的公共访问。 但是,存储帐户的默认配置允许具有适当权限的用户配置对存储帐户中的容器和 blob 的公共访问。 为增强安全性,无论单个容器的公共访问设置如何,都可以禁止对存储帐户的所有公共访问。 禁止对存储帐户进行公共访问可以阻止用户启用帐户中的容器的公共访问权限。 Azure 建议你禁止对存储帐户的公共访问,除非你的情况要求你进行公共访问。 禁止公共访问有助于防止意外的匿名访问产生的数据泄露。

当你禁止对存储帐户的公共 blob 访问时,Azure 存储会拒绝对该帐户的所有匿名请求。 禁止对某个帐户的公共访问后,以后无法为该帐户中的容器配置公共访问。 已配置了公共访问的所有容器将不再接受匿名请求。 有关详细信息,请参阅配置对容器和 Blob 的匿名公共读取访问

本文介绍了如何使用 DRAG(Detection-Remediation-Audit-Governance,检测-修正-审核-治理)框架持续管理对存储帐户的公共访问。

检测来自客户端应用程序的匿名请求

如果你禁止对存储帐户的公共读取访问,系统可能会拒绝对当前配置了公共访问的容器和 blob 的请求。 禁止对存储帐户的公共访问将替代该存储帐户中各个容器的公共访问设置。 禁止对存储帐户的公共访问后,将来对该帐户的任何匿名请求都会失败。

为了理解禁止公共访问可能会对客户端应用程序造成的影响,Azure 建议你为该帐户启用日志记录和指标,并分析一段时间间隔内的匿名请求的模式。 使用指标来确定对存储帐户的匿名请求数,并使用日志来确定匿名访问了哪些容器。

使用指标资源管理器监视匿名请求

若要跟踪对存储帐户的匿名请求,请在 Azure 门户中使用 Azure 指标资源管理器。 若要详细了解 Azure 指标资源管理器,请参阅 Azure 指标资源管理器入门

按照以下步骤创建跟踪匿名请求的指标:

  1. 导航到 Azure 门户中的存储帐户。 在“监视”部分下,选择“指标” 。

  2. 选择“添加指标”。 在“指标”对话框中,指定以下值:

    1. 将“作用域”字段设置为存储帐户的名称。
    2. 将“指标命名空间”设置为“Blob”。 此指标仅报告对 Blob 存储的请求。
    3. 将“指标”字段设置为“事务”。
    4. 将“聚合”字段设置为“求和”。

    新指标会显示给定时间间隔内针对 Blob 存储的事务数之和。 生成的指标如下图所示:

    Screenshot showing how to configure metric to sum blob transactions

  3. 接下来,选择“添加筛选器”按钮,为匿名请求创建基于指标的筛选器。

  4. 在“筛选器”对话框中,指定以下值:

    1. 将属性值设置为“身份验证”。
    2. 将“运算符”字段设置为等号 (=)。
    3. 通过从下拉列表中选择或输入将“值”字段设置为“匿名”。
  5. 在右上角,选择要查看指标的时间间隔。 还可以通过指定从 1 分钟到 1 个月的时间间隔,来指示请求聚合粒度。

配置指标后,匿名请求将开始显示在图形上。 下图显示了在过去 30 分钟内聚合的匿名请求。

Screenshot showing aggregated anonymous requests against Blob storage

你还可以配置警报规则,让系统在针对你的存储帐户发出的匿名请求达到一定数量时通知你。 有关详细信息,请参阅使用 Azure Monitor 创建、查看和管理指标警报

修正匿名公共访问

评估对存储帐户中的容器和 blob 的匿名请求后,可以采取措施来限制或阻止公共访问。 如果你的存储帐户中的某些容器可能需要供公共访问,你可以为存储帐户中的每个容器配置公共访问设置。 此选项提供对公共访问的最精细控制。 有关详细信息,请参阅为容器设置公共访问级别

为增强安全性,可以禁止对整个存储帐户的公共访问。 存储帐户的公共访问设置会替代该帐户中容器的单个设置。 如果你禁止对存储帐户的公共访问,则任何配置为允许公共访问的容器将不再可供以匿名方式访问。 有关详细信息,请参阅允许或禁止对存储帐户的公共读取访问

如果你的方案要求某些容器可供公共访问,则建议将这些容器及其 blob 移动到保留用于公共访问的存储帐户中。 然后,你可以禁止对任何其他存储帐户的公共访问。

验证是否不允许对 blob 进行公共访问

若要验证是否禁止对特定 blob 进行公共访问,你可以尝试通过其 URL 下载 blob。 如果下载成功,则 blob 仍可供公共使用。 如果 blob 因为对存储帐户的公共访问被禁止而不可公共访问,则你将看到一条错误消息,指示此存储帐户不允许公共访问。

下面的示例演示了如何使用 PowerShell 来尝试通过 URL 下载 blob。 请记得将括号中的占位符值替换为你自己的值:

$url = "<absolute-url-to-blob>"
$downloadTo = "<file-path-for-download>"
Invoke-WebRequest -Uri $url -OutFile $downloadTo -ErrorAction Stop

验证是否不允许修改容器的公共访问设置

若要验证在禁止对存储帐户的公共访问后是否无法修改容器的公共访问设置,可以尝试修改该设置。 如果禁止对存储帐户的公共访问,则更改容器的公共访问设置将失败。

下面的示例演示了如何使用 PowerShell 来尝试更改容器的公共访问设置。 请记得将括号中的占位符值替换为你自己的值:

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

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

Set-AzStorageContainerAcl -Context $ctx -Container $containerName -Permission Blob

验证是否不允许创建启用了公共访问的容器

如果禁止对存储帐户的公共访问,则你将无法创建启用了公共访问的新容器。 若要进行验证,你可以尝试创建启用了公共访问的容器。

下面的示例演示了如何使用 PowerShell 来尝试创建启用了公共访问的容器。 请记得将括号中的占位符值替换为你自己的值:

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

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

New-AzStorageContainer -Name $containerName -Permission Blob -Context $ctx

检查多个帐户的公共访问设置

若要检查具有最佳性能的一组存储帐户的公共访问设置,可以使用 Azure 门户中的 Azure Resource Graph 资源管理器。 若要详细了解如何使用 Resource Graph 资源管理器,请参阅快速入门:使用 Azure Resource Graph 资源管理器运行你的第一个 Resource Graph 查询

默认情况下,不会为存储帐户设置 AllowBlobPublicAccess 属性,在你显式设置此属性之前,它不会返回值。 当此属性值为 null 或为 true 时,存储帐户允许公共访问。

在 Resource Graph 资源管理器中运行以下查询会返回存储帐户的列表,并显示每个帐户的公共访问设置:

resources
| where type =~ 'Microsoft.Storage/storageAccounts'
| extend allowBlobPublicAccess = parse_json(properties).allowBlobPublicAccess
| project subscriptionId, resourceGroup, name, allowBlobPublicAccess

下图显示了整个订阅中的查询结果。 请注意,对于已显式设置了 AllowBlobPublicAccess 属性的存储帐户,它在结果中显示为 true 或 false。 如果尚未为存储帐户设置 AllowBlobPublicAccess 属性,则它在查询结果中显示为空白(或 null)。

Screenshot showing query results for public access setting across storage accounts

使用 Azure Policy 审核合规性

如果你有大量存储帐户,则可能需要执行审核,以确保将这些帐户配置为阻止公共访问。 若要审核一组存储帐户的合规性,请使用 Azure Policy。 Azure Policy 是一项服务,可用于创建、分配和管理将规则应用于 Azure 资源的策略。 Azure Policy 可帮助你确保这些资源始终符合公司标准和服务级别协议。 有关详细信息,请参阅 Azure Policy 概述

创建具有 Audit 效果的策略

Azure Policy 支持的效果决定了针对资源评估某个策略规则时会发生什么情况。 当资源不合规时,Audit 效果会创建一个警告,但不会停止请求。 有关效果的详细信息,请参阅了解 Azure Policy 效果

若要通过 Azure 门户为存储帐户的公共访问设置创建具有“审核”效果的策略,请执行以下步骤:

  1. 在 Azure 门户中,导航到 Azure Policy 服务。

  2. 在“创作”部分下,选择“定义”。

  3. 选择“添加策略定义”以创建新的策略定义。

  4. 对于“定义位置”字段,选择“更多”按钮以指定审核策略资源所在的位置。

  5. 指定策略的名称。 还可以指定说明和类别。

  6. 在“策略规则”下,将以下策略定义添加到“policyRule”部分。

    {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.Storage/storageAccounts"
          },
          {
            "not": {
              "field":"Microsoft.Storage/storageAccounts/allowBlobPublicAccess",
              "equals": "false"
            }
          }
        ]
      },
      "then": {
        "effect": "audit"
      }
    }
    
  7. 保存策略。

分配策略

接下来,将策略分配给资源。 策略的作用域对应于该资源及其下的所有资源。 有关策略分配的详细信息,请参阅 Azure Policy 分配结构

若要在 Azure 门户中分配策略,请执行下列步骤:

  1. 在 Azure 门户中,导航到 Azure Policy 服务。
  2. 在“创作”部分下,选择“分配”。
  3. 选择“分配策略”以创建新的策略分配。
  4. 对于“作用域”字段,请选择策略分配的作用域。
  5. 对于“策略定义”字段,请选择“更多”按钮,然后从列表中选择你在上一部分定义的策略。
  6. 提供策略分配的名称。 说明是可选的。
  7. 让“策略强制实施”设置为“启用”状态。 此设置对审核策略没有影响。
  8. 选择“查看 + 创建”以创建分配。

查看合规性报告

分配策略后,你可以查看合规性报告。 审核策略的合规性报告会指出哪些存储帐户不符合策略。 有关详细信息,请参阅获取策略合规性数据

创建策略分配后,合规性报告可能需要几分钟时间才会变得可用。

若要在 Azure 门户中查看合规性报告,请执行以下步骤:

  1. 在 Azure 门户中,导航到 Azure Policy 服务。

  2. 选择“合规性”。

  3. 筛选你在上一步创建的策略分配名称的结果。 该报告显示有多少资源不符合策略。

  4. 你可以在报告中向下钻取以获取更多详细信息,包括不合规的存储帐户的列表。

    Screenshot showing compliance report for audit policy for blob public access

使用 Azure Policy 强制实施授权访问

Azure Policy 可以确保 Azure 资源符合要求和标准,从而为云治理提供支持。 若要确保组织中的存储帐户仅允许经授权的请求,你可以创建一个策略,用以阻止创建其公共访问设置允许匿名请求的新存储帐户。 如果该帐户的公共访问设置不符合策略,则此策略还会阻止对现有帐户进行的所有配置更改。

强制实施策略会使用“拒绝”效果来阻止将创建或修改一个允许公共访问的存储帐户的请求。 有关效果的详细信息,请参阅了解 Azure Policy 效果

若要为允许匿名请求的公共访问设置创建具有“拒绝”效果的策略,请执行使用 Azure Policy 审核合规性中所述的步骤,但在策略定义的“policyRule”节中提供以下 JSON:

{
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Storage/storageAccounts"
      },
      {
        "not": {
          "field":"Microsoft.Storage/storageAccounts/allowBlobPublicAccess",
          "equals": "false"
        }
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}

创建具有“拒绝”效果的策略并将其分配给作用域后,用户无法创建允许公共访问的存储帐户。 用户也不能对当前允许公共访问的现有存储帐户进行任何配置更改。 如果尝试这样做,将会导致错误。 必须将存储帐户的公共访问设置设为 false,然后才能继续创建或配置帐户。

下图显示了在以下情况下发生的错误:当具有“拒绝”效果的策略要求禁止公共访问时,你尝试创建允许公共访问(针对新帐户的默认设置)的存储帐户。

Screenshot showing the error that occurs when creating a storage account in violation of policy

允许或禁止公共访问的权限

若要为存储帐户设置 AllowBlobPublicAccess 属性,用户必须有权创建和管理存储帐户。 提供这些权限的 Azure 基于角色的访问控制 (Azure RBAC) 角色包含 Microsoft.Storage/storageAccounts/write 或 Microsoft.Storage/storageAccounts/* 操作。 具有此操作的内置角色包括:

这些角色不提供通过 Azure Active Directory (Azure AD) 对存储帐户中数据的访问权限。 但是,它们包含 Microsoft.Storage/storageAccounts/listkeys/action,可以授予对帐户访问密钥的访问权限。 借助此权限,用户可以使用帐户访问密钥访问存储帐户中的所有数据。

角色分配的范围必须设定为存储帐户级别或更高级别,以允许用户启用或禁用存储帐户的公共访问。 有关角色作用域的详细信息,请参阅了解 Azure RBAC 的作用域

请注意,仅向需要能够创建存储帐户或更新其属性的用户分配这些角色。 使用最小特权原则确保用户拥有完成任务所需的最少权限。 有关使用 Azure RBAC 管理访问权限的详细信息,请参阅 Azure RBAC 最佳做法

注意

经典订阅管理员角色“服务管理员”和“共同管理员”具有 Azure 资源管理器所有者角色的等效权限。 所有者角色包括所有操作,因此具有这些管理角色之一的用户也可以创建和管理存储帐户。 有关详细信息,请参阅经典订阅管理员角色、Azure 角色和 Azure AD 管理员角色

后续步骤