如何保护 DNS 区域和记录

注释

建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az。

DNS 区域和记录是关键资源。 删除 DNS 区域或单个 DNS 记录可能会导致服务中断。 请务必保护 DNS 区域和记录免受未经授权的或意外更改。

本文将解释Azure DNS如何帮助您保护公共DNS区域和记录。 它涵盖了 Azure 资源管理器 提供的两个强大安全功能:Azure 基于角色的访问控制(Azure RBAC)和资源锁。

Azure 基于角色的访问控制

Azure 基于角色的访问控制(Azure RBAC)为 Azure 用户、组和资源启用精细的访问管理。 使用 Azure RBAC,可以授予用户所需的访问权限级别。 有关 Azure RBAC 如何帮助你管理访问权限的详细信息,请参阅什么是 Azure 基于角色的访问控制(Azure RBAC)。

DNS 区域参与者角色

DNS 区域贡献者角色是管理 Azure DNS 公共 DNS 资源的内置角色(Microsoft.Network/DNSZones)。 当你将这个角色分配给用户或组时,他们可以管理这些DNS资源。 它不会授予私有DNS区域权限。 如需保护私有DNS区域和记录集,请参见 保护私有DNS区域和记录。

资源组 myResourceGroup 包含 Contoso Corporation 的五个区域。 向 DNS 管理员授予对该资源组的 DNS 区域参与者权限,可以完全控制这些 DNS 区域。 它避免授予不必要的权限。 DNS 管理员无法创建或停止虚拟机。

分配 Azure RBAC 权限的最简单方法是 通过 Azure 门户。

打开 访问控制(IAM) 以管理资源组,然后选择 + Add,然后选择 DNS Zone Contributor 角色。 选择要授予权限所需的用户或组。

资源组的访问控制页的屏幕截图。

还可以 使用 Azure PowerShell 授予权限:

# Grant 'DNS Zone Contributor' permissions to all zones in a resource group

$usr = "<user email address>"
$rol = "DNS Zone Contributor"
$rsg = "<resource group name>"

New-AzRoleAssignment -SignInName $usr -RoleDefinitionName $rol -ResourceGroupName $rsg

还可以 通过 Azure CLI 使用等效命令:

# Grant 'DNS Zone Contributor' permissions to all zones in a resource group

az role assignment create \
--assignee "<user email address>" \
--role "DNS Zone Contributor" \
--resource-group "<resource group name>"

区域级别 Azure RBAC

Azure RBAC 规则可以应用于订阅、资源组或单个资源。 该资源可以是单个 DNS 区域,也可以是单个记录集。

例如,资源组 myResourceGroup 包含区域 contoso.com 和子区域 customers.contoso.com。 为每个客户帐户创建 CNAME 记录。 用于管理 CNAME 记录的管理员帐户分配了在 customers.contoso.com 区域中创建记录的权限。 该帐户只能管理 customers.contoso.com 。

可以通过 Azure 门户授予区域级 Azure RBAC 权限。 打开区域的 访问控制(IAM), 选择 “+ 添加”,然后选择 DNS 区域参与者 角色,然后选择所需的用户或组来授予权限。

DNS 区域的访问控制页的屏幕截图。

还可以 使用 Azure PowerShell 授予权限:

# Grant 'DNS Zone Contributor' permissions to a specific zone

$usr = "<user email address>"
$rol = "DNS Zone Contributor"
$rsg = "<resource group name>"
$zon = "<zone name>"
$typ = "Microsoft.Network/DNSZones"

New-AzRoleAssignment -SignInName $usr -RoleDefinitionName $rol -ResourceGroupName $rsg -ResourceName $zon -ResourceType $typ

还可以 通过 Azure CLI 使用等效命令:

# Grant 'DNS Zone Contributor' permissions to a specific zone

az role assignment create \
--assignee <user email address> \
--role "DNS Zone Contributor" \
--scope "/subscriptions/<subscription id>/resourceGroups/<resource group name>/providers/Microsoft.Network/DnsZones/<zone name>/"

记录集级别 Azure RBAC

权限在记录集层面上应用。 用户有权控制他们需要的条目,并且无法进行任何其他更改。

可以在 Azure 门户的记录集页中,使用“用户”按钮来配置记录集级别的 Azure RBAC 权限。

记录集的用户按钮屏幕截图。

还可以 使用 Azure PowerShell授予 Azure RBAC 记录集级权限:

# Grant permissions to a specific record set

$usr = "<user email address>"
$rol = "DNS Zone Contributor"
$sco = "/subscriptions/<subscription id>/resourceGroups/<resource group name>/providers/Microsoft.Network/dnszones/<zone name>/<record type>/<record name>"

New-AzRoleAssignment -SignInName $usr -RoleDefinitionName $rol -Scope $sco

还可以 通过 Azure CLI 使用等效命令:

# Grant permissions to a specific record set

az role assignment create \
--assignee "<user email address>" \
--role "DNS Zone Contributor" \
--scope "/subscriptions/<subscription id>/resourceGroups/<resource group name>/providers/Microsoft.Network/dnszones/<zone name>/<record type>/<record name>"

自定义角色

内置的 DNS 区域参与者角色可完全控制 DNS 资源。 可以生成自己的自定义 Azure 角色以提供精细的控制。

用于管理 CNAME 的帐户被授予仅管理 CNAME 记录的权限。 该帐户无法修改其他类型的记录。 账户无法执行区域级操作,例如区域删除等。

以下示例演示用于仅管理 CNAME 记录的自定义角色定义:

{
    "Name": "DNS CNAME Contributor",
    "Id": "",
    "IsCustom": true,
    "Description": "Can manage DNS CNAME records only.",
    "Actions": [
        "Microsoft.Network/dnsZones/CNAME/*",
        "Microsoft.Network/dnsZones/read",
        "Microsoft.Authorization/*/read",
        "Microsoft.Insights/alertRules/*",
        "Microsoft.ResourceHealth/availabilityStatuses/read",
        "Microsoft.Resources/deployments/*",
        "Microsoft.Resources/subscriptions/resourceGroups/read",
        "Microsoft.Support/*"
    ],
    "NotActions": [
    ],
    "AssignableScopes": [
        "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
    ]
}

Actions 属性定义以下特定于 DNS 的权限:

  • Microsoft.Network/dnsZones/CNAME/* 授予对 CNAME 记录的完全控制
  • Microsoft.Network/dnsZones/read 授予读取 DNS 区域的权限,但不允许对其进行修改,使你能够查看在其中创建 CNAME 的区域。

其余操作将被从DNS 区域参与者内置角色复制。

注释

使用 Azure 自定义角色来防止删除记录集,同时允许它们被更新,这种方式并不是一种有效的控制措施。 它阻止删除记录集,但不会阻止它们被修改。 允许的修改包括添加和删除记录集中的记录,包括删除所有记录以保留空记录集。 这与从 DNS 解析角度删除记录集的效果相同。

目前无法通过 Azure 门户定义自定义角色定义。 可以使用 Azure PowerShell 创建基于此角色定义的自定义角色:

# Create new role definition based on input file
New-AzRoleDefinition -InputFile <file path>

还可以通过 Azure CLI 创建它:

# Create new role definition based on input file
az role definition create --role-definition <file path>

然后,可以采用与内置角色相同的方式分配该角色,如本文前面所述。

有关如何创建、管理和分配自定义角色的详细信息,请参阅 Azure 自定义角色。

资源锁

Azure 资源管理器支持另一种类型的安全控制,即锁定资源的能力。 资源锁应用于资源,并且可在所有用户和角色中有效。 有关详细信息,请参阅 使用 Azure 资源管理器锁定资源。

资源锁有两种类型: CanNotDelete 和 ReadOnly。 你可以将这些锁类型应用到公共DNS区域或单个记录集上。 以下章节描述了几种常见场景,以及如何通过资源锁来支持它们。

防止所有更改

若要防止进行更改,请将 ReadOnly 锁应用于该区域。 此锁可防止创建新记录集,并阻止修改或删除现有记录集。

可以通过 Azure 门户创建区域级别资源锁。 在“DNS 区域”页中,选择“ 锁定”,然后选择“ + 添加:

区域级别资源锁的屏幕截图。

还可以通过 Azure PowerShell 创建区域级资源锁:

# Lock a DNS zone

$lvl = "<lock level>"
$lnm = "<lock name>"
$rsc = "<zone name>"
$rty = "Microsoft.Network/DNSZones"
$rsg = "<resource group name>"

New-AzResourceLock -LockLevel $lvl -LockName $lnm -ResourceName $rsc -ResourceType $rty -ResourceGroupName $rsg

还可以 通过 Azure CLI 使用等效命令:

# Lock a DNS zone

az lock create \
--lock-type "<lock level>" \
--name "<lock name>" \
--resource-name "<zone name>" \
--namespace "Microsoft.Network" \
--resource-type "DnsZones" \
--resource-group "<resource group name>"

保护单个记录

若要防止现有 DNS 记录集进行修改,请将 ReadOnly 锁应用于记录集。

注释

将 CanNotDelete 锁应用于记录集不是有效的控件。 它阻止删除记录集,但不会阻止它被修改。 允许的修改包括添加和删除记录集中的记录,包括删除所有记录以保留空记录集。 这与从 DNS 解析角度删除记录集的效果相同。

记录集级别资源锁目前只能使用 Azure PowerShell 进行配置。 Azure 门户或 Azure CLI 不支持它们。

# Lock a DNS record set

$lvl = "<lock level>"
$lnm = "<lock name>"
$rsc = "<zone name>/<record set name>"
$rty = "Microsoft.Network/DNSZones/<record type>"
$rsg = "<resource group name>"

New-AzResourceLock -LockLevel $lvl -LockName $lnm -ResourceName $rsc -ResourceType $rty -ResourceGroupName $rsg

防止区域删除

在 Azure DNS 中删除某个区域时,将删除该区域中的所有记录集。 此操作无法撤消。 意外删除关键区域可能会产生重大业务影响。 请务必防止意外删除区域。

将 CanNotDelete 锁应用于区域可防止删除该区域。 锁由子资源继承。 锁可防止删除区域中的任何记录集。 如上述说明所述,由于仍可从现有记录集中删除记录,因此无效。

或者,将 CanNotDelete 锁应用于区域中的记录集,例如 SOA 记录集。 在不同时删除记录集的情况下,不会删除该区域。 此锁可防止区域删除,同时仍允许自由修改区域中的记录集。 如果尝试删除该区域,Azure 资源管理器将检测此删除。 删除作还会删除 SOA 记录集,Azure 资源管理器会阻止调用,因为 SOA 已锁定。 不会删除任何记录集。

以下 PowerShell 命令针对给定区域的 SOA 记录创建 CanNotDelete 锁:

# Protect against zone delete with CanNotDelete lock on the record set

$lvl = "CanNotDelete"
$lnm = "<lock name>"
$rsc = "<zone name>/@"
$rty = "Microsoft.Network/DNSZones/SOA"
$rsg = "<resource group name>"

New-AzResourceLock -LockLevel $lvl -LockName $lnm -ResourceName $rsc -ResourceType $rty -ResourceGroupName $rsg

防止意外删除区域的另一个选项是使用自定义角色。 此角色可确保用于管理区域的帐户没有区域删除权限。

当确实需要删除区域时,可以强制实施双重删除:

  • 首先,授予区域删除权限
  • 其次,授予删除区域的权限。

自定义角色适用于这些帐户访问的所有区域。 具有区域删除权限(例如订阅所有者)的帐户仍可能会意外删除区域。

可以同时使用这两种方法(资源锁和自定义角色)作为 DNS 区域保护的深层防御方法。

后续步骤