你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

限制 Azure 中的跨租户专用终结点连接

客户越来越多地在租户中使用专用终结点,通过私有和安全的方式连接 Azure 平台即服务 (PaaS) 服务。 专用终结点可以跨 Microsoft Entra 租户连接到服务。 为了确保安全性和合规性,可能需要阻止专用终结点上的跨 Microsoft Entra 租户连接。 本指南说明了建议使用哪些配置选项来限制或阻止跨租户专用终结点连接。 这些选项可帮助在 Azure 环境中创建数据泄露防护 (DLP) 控制。

专用终结点简介

使用专用终结点通过现有网络边界控制 Azure 环境中的流量。 但是在某些情况下,必须仅在企业 Microsoft Entra 租户中保留专用终结点连接。 以下示例显示了可能产生安全风险的连接。

  • 连接 A:恶意管理员在客户虚拟网络上创建专用终结点。 这些终结点链接到托管在客户环境之外的服务,比如另一个 Microsoft Entra 租户。
  • 连接 B:恶意管理员在其他 Microsoft Entra 租户中创建专用终结点,这些终结点链接到客户的 Microsoft Entra 租户中托管的服务。

关系图显示跨租户专用终结点连接方案。

图 1:专用终结点跨租户方案示意图。

对于这两种情况,都可以指定服务的资源 ID,并手动批准专用终结点连接。 用户还需要基于角色的访问控制 (RBAC) 访问权限来运行这些操作。

图 1 中的连接 C 和 D 显示了客户通常希望允许的方案。 专用终结点连接保存在企业 Microsoft Entra 租户中。 它们不表示安全风险,因此本文未介绍这两种方案。

以下信息提供了阻止跨 Microsoft Entra 租户预配专用终结点的选项。

拒绝链接到其他租户中的服务的专用终结点

方案一:恶意管理员需要在客户的 Microsoft Entra 租户的订阅中拥有以下权限。

  • privateEndpointNetworkPolicies 设置为“已禁用”的子网上的 Microsoft.Network/virtualNetworks/join/action 权限。
  • 对客户环境中资源组的 Microsoft.Network/privateEndpoints/write 访问权限。

借助这些权限,恶意管理员可以在客户的 Microsoft Entra 租户中创建专用终结点。 此专用终结点链接到单独订阅和 Microsoft Entra 租户中的服务。 图 1 将此方案显示为连接 A。

对于此方案,用户设置外部 Microsoft Entra 租户和 Azure 订阅。 接下来,他们通过手动指定服务的资源 ID,在客户环境中创建一个专用终结点。 最后,恶意管理员批准外部 Microsoft Entra 租户中托管的链接服务上的专用终结点,以允许流量通过连接。

恶意管理员批准专用终结点连接后,可以将公司数据从公司虚拟网络复制到外部 Microsoft Entra 租户上的 Azure 服务。 仅当使用 Azure RBAC 授予访问权限时,才会出现此安全风险。

方案一的缓解措施

使用以下 Azure Policy 自动阻止在链接到外部 Azure 服务的公司 Microsoft Entra 租户中创建专用终结点的功能。

"if": {
    "allOf": [
        {
            "field": "type",
            "equals": "Microsoft.Network/privateEndpoints"
        },
        {
            "anyOf": [
                {
                    "count": {
                        "field": "Microsoft.Network/privateEndpoints/manualprivateLinkServiceConnections[*]",
                        "where": {
                            "allOf": [
                                {
                                    "field": "Microsoft.Network/privateEndpoints/manualprivateLinkServiceConnections[*].privateLinkServiceId",
                                    "notEquals": ""
                                },
                                {
                                    "value": "[split(concat(first(field('Microsoft.Network/privateEndpoints/manualprivateLinkServiceConnections[*].privateLinkServiceId')), '//'), '/')[2]]",
                                    "notEquals": "[subscription().subscriptionId]"
                                }
                            ]
                        }
                    },
                    "greaterOrEquals": 1
                },
                {
                    "count": {
                        "field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*]",
                        "where": {
                            "allOf": [
                                {
                                    "field": "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].privateLinkServiceId",
                                    "notEquals": ""
                                },
                                {
                                    "value": "[split(concat(first(field('Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].privateLinkServiceId')), '//'), '/')[2]]",
                                    "notEquals": "[subscription().subscriptionId]"
                                }
                            ]
                        }
                    },
                    "greaterOrEquals": 1
                }
            ]
        }
    ]
},
"then": {
    "effect": "Deny"
}

此策略将拒绝在链接服务的订阅之外创建的任何专用终结点(如连接 A 和 D)。该策略还可灵活使用 manualPrivateLinkServiceConnectionsprivateLinkServiceConnections

可以更新此策略,以便仅在一组特定的订阅中创建专用终结点。 可以通过添加一个 list 参数并使用 "notIn": "[parameters('allowedSubscriptions')]" 构造来进行此更改。 但不建议使用此方法,因为这意味着你必须不断维护此策略的订阅列表。 每当在租户内部创建新订阅时,都必须将订阅 ID 添加到参数中。

相反,将策略分配给顶级管理组,然后在需要的地方使用豁免。

方案一的注意事项

此策略阻止创建与服务本身订阅不同的专用终结点。 如果某些用例需要这些终结点,请使用策略豁免。 为数据工厂和 Azure Synapse 创建更多策略,以确保托管虚拟网络上托管的托管专用终结点只能连接到 Microsoft Entra 租户中托管的服务。

拒绝从其他租户创建的专用终结点的连接

方案二:恶意管理员需要对应为其创建专用终结点的客户环境中的服务具有写入权限。

使用此权限,恶意管理员可以在外部 Microsoft Entra 租户和订阅中创建专用终结点。 此终结点链接到客户的 Microsoft Entra 租户中的服务。 图 1 将此方案显示为连接 B。

在这种情况下,恶意管理员需要首先配置外部专用 Microsoft Entra 租户和 Azure 订阅。 接下来,他们通过在企业 Microsoft Entra 租户中手动指定服务的资源 ID 和组 ID,在其环境中创建专用终结点。 最后,他们批准链接服务上的专用终结点,以允许跨 Microsoft Entra 租户通过连接的流量。

在恶意管理员或服务所有者批准私有终端节点后,将从外部虚拟网络访问数据。

方案二的缓解措施

使用服务特定的策略来防止在客户租户中出现这种情况。 专用终结点连接是相应服务的子资源,并显示在其属性部分下。 使用以下策略定义拒绝不合规的连接:

"if": {
    "allOf": [
        {
            "field": "type",
            "equals": "Microsoft.Storage/storageAccounts/privateEndpointConnections"
        },
        {
            "field": "Microsoft.Storage/storageAccounts/privateEndpointConnections/privateLinkServiceConnectionState.status",
            "equals": "Approved"
        },
        {
            "anyOf": [
                {
                    "field": "Microsoft.Storage/storageAccounts/privateEndpointConnections/privateEndpoint.id",
                    "exists": false
                },
                {
                    "value": "[split(concat(field('Microsoft.Storage/storageAccounts/privateEndpointConnections/privateEndpoint.id'), '//'), '/')[2]]",
                    "notEquals": "[subscription().subscriptionId]"
                }
            ]
        }
    ]
},
"then": {
    "effect": "Deny"
}

此策略显示 Azure 存储示例。 为密钥保管库Azure AI 服务SQL Server 等其他服务复制相同的策略定义。

为了进一步提高可管理性,请将特定于服务的策略捆绑到一个计划中。 此策略拒绝审批专用终结点与在相应服务的订阅外部托管的专用终结点之间的连接。 它不会拒绝对专用终结点连接的拒绝或删除,这是客户所需的行为。 自动审批工作流(例如连接 C)不受此策略影响。

但是,这种方法会阻止门户内兼容的专用终结点连接的批准。 之所以出现此问题,是因为门户 UI 不会在其有效负载中发送已连接专用终结点的资源 ID。 建议使用 Azure 资源管理器Azure PowerShellAzure CLI 来批准专用终结点连接。

另外,将策略分配给顶级管理组,并在需要的地方使用豁免。

方案二的注意事项

Azure Synapse Analytics 和 Azure 数据工厂提供托管虚拟网络和托管专用终结点。 凭借这些新功能,策略会阻止这些服务的安全和专用使用。

建议在方案二缓解措施中使用的策略定义中使用审核效果,而不是拒绝效果。 此更改可帮助跟踪在单独的订阅和租户中创建的专用终结点。 你还可以对相应的数据平台范围使用策略豁免。

Azure 数据工厂

若要克服 Azure 数据工厂的托管虚拟网络上的方案一,请使用以下策略定义

"if": {
    "allOf": [
        {
            "field": "type",
            "equals": "Microsoft.DataFactory/factories/managedVirtualNetworks/managedPrivateEndpoints"
        },
        {
            "anyOf": [
                {
                    "field": "Microsoft.DataFactory/factories/managedVirtualNetworks/managedPrivateEndpoints/privateLinkResourceId",
                    "exists": false
                },
                {
                    "value": "[split(field('Microsoft.DataFactory/factories/managedVirtualNetworks/managedPrivateEndpoints/privateLinkResourceId'), '/')[2]]",
                    "notEquals": "[subscription().subscriptionId]"
                }
            ]
        }
    ]
},
"then": {
    "effect": "[parameters('effect')]"
}

此策略拒绝链接到服务的托管专用终结点,这些服务托管在数据工厂订阅之外。 通过添加 list 参数并使用 "notIn": "[parameters('allowedSubscriptions')]" 构造,可以将此策略更改为允许连接到订阅集中托管的服务。 对租户或环境中的数据平台执行此更改,在这些租户或环境中,广泛使用具有托管虚拟网络和托管专用终结点的服务。

建议将此策略分配给顶级管理组,并在需要时使用豁免。 对于数据平台,请进行这些更改并将策略分配给数据平台订阅集。

Azure Synapse

Azure Synapse 还使用托管虚拟网络。 建议为方案一的数据工厂策略应用类似策略。 Azure Synapse 不提供托管专用终结点的策略别名。 但是,有一个数据外泄防护功能,可以使用以下策略对工作区强制执行:

"if": {
    "allOf": [
        {
            "field": "type",
            "equals": "Microsoft.Synapse/workspaces"
        },
        {
            "anyOf": [
                {
                    "field": "Microsoft.Synapse/workspaces/managedVirtualNetworkSettings.preventDataExfiltration",
                    "exists": false
                },
                {
                    "field": "Microsoft.Synapse/workspaces/managedVirtualNetworkSettings.preventDataExfiltration",
                    "notEquals": true
                },
                {
                    "count": {
                        "field": "Microsoft.Synapse/workspaces/managedVirtualNetworkSettings.allowedAadTenantIdsForLinking[*]",
                        "where": {
                            "field": "Microsoft.Synapse/workspaces/managedVirtualNetworkSettings.allowedAadTenantIdsForLinking[*]",
                            "notEquals": "[subscription().tenantId]"
                        }
                    },
                    "greaterOrEquals": 1
                }
            ]
        }
    ]
},
"then": {
    "effect": "Deny"
}

此策略强制使用 Azure Synapse 的数据外泄功能。 借助 Azure Synapse,可以拒绝来自在客户租户之外托管的服务的任何专用终结点。 还可以拒绝在指定租户 ID 集外托管的任何专用终结点。 此策略仅允许创建链接到服务的托管专用终结点,这些服务托管在客户租户中。

这些策略现在内置提供。

  • Azure Synapse 工作区应该只允许传送到已批准目标的出站数据流量。

    定义 ID:/providers/Microsoft.Authorization/policyDefinitions/3484ce98-c0c5-4c83-994b-c5ac24785218

  • Azure Synapse 托管专用终结点应仅连接到已批准的 Microsoft Entra 租户中的资源。

    定义 ID:/providers/Microsoft.Authorization/policyDefinitions/3a003702-13d2-4679-941b-937e58c443f0

建议将此策略分配给顶级管理组,并在需要时使用豁免。

后续步骤

必须了解进出公共 Internet 的入站和出站连接的推荐连接模型。 下一篇文章将回顾设计注意事项、设计建议和推荐内容,以便进一步阅读。