如何保护 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 区域参与者角色是用于管理专用 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 资源管理器锁定资源

有两种类型的资源锁: CanNotDeleteReadOnly。 这些锁类型可以应用于专用 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 区域保护的深层防御方法。

后续步骤