用于解决 Azure SQL 数据库和 Azure SQL 托管实例常见安全要求的 playbook
适用于: Azure SQL 数据库 Azure SQL 托管实例
本文提供了有关如何解决常见安全要求的最佳做法。 并非所有要求都适用于所有环境,你应该向数据库和安全团队咨询要实现哪些功能。
注意
Microsoft Entra ID 以前称为 Azure Active Directory (Azure AD)。
解决常见的安全要求
本文档提供有关如何解决使用 Azure SQL 数据库和 Azure SQL 托管实例的新应用程序或现有应用程序的常见安全要求的指导。 本文档的内容已从较高层面按照安全考虑因素进行组织。 若要解决特定的威胁,请参阅常见安全威胁和潜在缓解措施部分。 提供的某些建议在将应用程序从本地迁移到 Azure 时适用,不过,本文档不会重点说明迁移方案。
本指南涉及的 Azure SQL 数据库部署产品/服务
本指南不涉及的部署产品/服务
- Azure Synapse Analytics
- Azure SQL VM (IaaS)
- SQL Server
目标受众
本指南的目标读者是在保护 Azure SQL 数据库时遇到问题的客户。 对本最佳做法文章感兴趣的角色包括但不限于:
- 安全架构师
- 安全经理
- 合规性主管
- 隐私主管
- 安全工程师
如何使用本指南
本文档旨在用作现有 Azure SQL 数据库安全性文档的配套资源。
除非另有说明,否则我们建议遵循每个部分中列出的所有最佳做法,以实现相关的目标或要求。 为了帮助客户满足特定的安全合规标准或最佳做法,在适用的情况下,“要求或目标”部分下面会列出重要的法规控制措施。 本文参考了以下安全标准和法规:
- FedRAMP:AC-04、AC-06
- SOC:CM-3、SDL-3
- ISO/IEC 27001:访问控制、加密
- Microsoft 操作安全保障 (OSA) 做法:做法 #1-6 和 #9
- NIST 专刊 800-53 安全控制:AC-5、AC-6
- PCI DSS:6.3.2、6.4.2
我们计划持续更新本文列出的建议和最佳做法。
身份验证
身份验证是证明用户所声明身份的过程。 Azure SQL 数据库和 SQL 托管实例支持两种类型的身份验证:
- SQL 身份验证
- Microsoft Entra 身份验证
注意
并非所有工具和第三方应用程序都支持 Microsoft Entra 身份验证。
标识的集中管理
集中式标识管理提供以下优势:
- 管理组帐户并控制用户权限,而无需跨服务器、数据库和托管实例重复登录。
- 简化且灵活的权限管理。
- 应用程序的大规模管理。
如何实现
- 使用 Microsoft Entra 身份验证进行集中式身份管理。
最佳实践
创建 Microsoft Entra 租户,创建用户来表示人类用户,并创建服务主体来表示应用、服务和自动化工具。 服务主体相当于 Windows 和 Linux 中的服务帐户。
通过组分配向 Microsoft Entra 主体分配资源访问权限:创建 Microsoft Entra 组,向组授予访问权限,并将各个成员添加到组中。 在数据库中,创建映射到 Microsoft Entra 组的包含数据库用户。 若要在数据库中分配权限,将代表组的包含的数据库用户添加到数据库角色,或直接向其授予权限。
注意
在 SQL 托管实例中,还可以创建映射到
master
数据库中 Microsoft Entra 主体的登录名。 请参阅 CREATE LOGIN (Transact-SQL)。使用 Microsoft Entra 组可以简化权限管理,组所有者和资源所有者都可以在组中添加/删除成员。
为每个服务器或托管实例的 MicrosoftEntra 管理员创建单独的组。
使用 Microsoft Entra ID 审核活动报告监视 Microsoft Entra 组成员身份更改。
对于托管实例,需要单独的步骤来创建 Microsoft Entra 管理员。
注意
- Microsoft Entra 身份验证记录在 Azure SQL 审核日志中,但不记录在 Microsoft Entra 登录日志中。
- 在 Azure 中授予的 Azure RBAC 权限不适用于 Azure SQL 数据库或 SQL 托管实例权限。 必须使用现有的 SQL 权限手动创建/映射此类权限。
- 在客户端,Microsoft Entra 身份验证需要访问 Internet 或通过用户定义路由 (UDR) 访问虚拟网络。
- Microsoft Entra 访问令牌缓存在客户端,其生存期取决于令牌配置。 请参阅文章 Microsoft Entra ID 中的可配置令牌生存期
- 有关排除 Microsoft Entra 身份验证问题的指南,请参阅博客 Microsoft Entra ID 故障排除。
Microsoft Entra 多重身份验证
内容来源:OSA 做法 #2,ISO 访问控制 (AC)
Microsoft Entra 多重身份验证要求完成多种形式的身份验证来提供额外的安全性。
如何实现
使用条件访问在 Microsoft Entra ID 中启用多重身份验证,并使用交互式身份验证。
替代方法是为整个 Microsoft Entra 租户或 Active Directory 域启用多重身份验证。
最佳实践
创建 Microsoft Entra 组,并使用 Microsoft Entra 条件访问为选定的组启用多重身份验证策略。
- 请参阅规划条件访问部署一文。
可以为整个 Microsoft Entra 租户或与 Microsoft Entra ID 联合的 Active Directory 启用多重身份验证。
对以交互方式请求密码的 Azure SQL 数据库和 Azure SQL 托管实例使用 Microsoft Entra 交互式身份验证模式,然后启用多重身份验证:
- 在 SSMS 中使用通用身份验证。 请参阅文章在 Azure SQL 数据库、SQL 托管实例和 Azure Synapse 中使用 Microsoft Entra 多重身份验证(SSMS 支持多重身份验证)。
- 使用 SQL Server Data Tools (SSDT) 中支持的交互式身份验证。 请参阅文章 SQL Server Data Tools (SSDT) 中的 Microsoft Entra ID 支持。
- 使用支持多重身份验证的其他 SQL 工具。
- SSMS 向导对导出/提取/部署数据库操作的支持
- SqlPackage:选项“/ua”
- sqlcmd 实用工具:选项 -G(交互式)
- bcp 实用工具:选项 -G(交互式)
实现应用程序,以使用支持多重身份验证的交互式身份验证连接到 Azure SQL 数据库或 Azure SQL 托管实例。
注意
此身份验证模式需要使用基于用户的标识。 如果使用绕过单个 Microsoft Entra 用户身份验证的受信任身份模型(例如,使用 Azure 资源托管标识),则多重身份验证不适用。
尽量减少对用户使用基于密码的身份验证
内容来源:OSA 做法 #4,ISO 访问控制 (AC)
基于密码的身份验证方法是较弱的身份验证形式。 凭据可能会透露或者被错误地丢弃。
如何实现
- 使用 Microsoft Entra 集成身份验证,无需使用密码。
最佳实践
- 使用 Windows 凭据进行单一登录身份验证。 将本地 Active Directory 域与 Microsoft Entra ID 联合,并使用集成 Windows 身份验证(适用于使用 Microsoft Entra ID 加入域的计算机)。
尽量减少对应用程序使用基于密码的身份验证
内容来源:OSA 做法 #4,ISO 访问控制 (AC)
如何实现
- 启用 Azure 托管标识。 还可以使用集成式或基于证书的身份验证。
最佳实践
使用 Azure 资源的托管标识。
对应用程序使用基于证书的身份验证。
- 请参阅此代码示例。
对集成的联盟域和加入域的计算机使用 Microsoft Entra 身份验证(请参阅上一部分)。
- 请参阅集成身份验证的示例应用程序。
保护密码和机密
如果不可避免地需要使用密码,请确保密码受到保护。
如何实现
- 使用 Azure Key Vault 存储密码和机密。 在适用的情况下,请对 Microsoft Entra 用户的 Azure SQL 数据库使用多重身份验证。
最佳实践
如果无法避免密码或机密的使用,请在 Azure Key Vault 中存储用户密码和应用程序机密,并通过 Key Vault 访问策略管理访问权限。
各种应用开发框架还可能提供框架特定的机制来保护应用中的机密。 例如:ASP.NET Core 应用。
对旧式应用程序使用 SQL 身份验证
SQL 身份验证是指使用用户名和密码连接到 Azure SQL 数据库或 SQL 托管实例时对用户进行身份验证。 需要在每个服务器或托管实例中创建一个登录名,并在每个数据库中创建一个用户。
如何实现
- 使用 SQL 身份验证。
最佳实践
以服务器或实例管理员的身份创建登录名和用户。 除非将包含的数据库用户与密码配合使用,否则所有密码将存储在
master
数据库中。
访问管理
访问管理(也称为授权)是控制和管理已授权用户对 Azure SQL 数据库或 SQL 托管实例的访问权限与特权的过程。
实施最低特权原则
内容来源:FedRamp 控制措施 AC-06,NIST:AC-6,OSA 做法 #3
最低特权原则指出,用户拥有的特权不应超过他们完成任务所需的特权。 有关详细信息,请参阅 Just Enough Administration 一文。
如何实现
仅分配完成所需任务而需要的权限:
在 SQL 数据库中:
- 使用粒度权限和用户定义的数据库角色(或 SQL 托管实例中的服务器角色):
- 创建所需的角色
- 创建所需的用户
- 将用户作为成员添加到角色
- 然后将权限分配给角色。
- 确保不要将用户分配到不必要的角色。
- 使用粒度权限和用户定义的数据库角色(或 SQL 托管实例中的服务器角色):
在 Azure 资源管理器中:
- 使用内置角色(如果可用)或 Azure 自定义角色,并分配所需的权限。
最佳实践
以下最佳做法是可选的,但可以改善安全策略的易管理性和支持性:
如果可能,请从尽可能低的权限集开始,在有实际需要(和理由)时逐个添加权限,而不要采用相反的方法:逐步去除权限。
避免将权限分配给单个用户。 改为以一致的方式使用角色(数据库角色或服务器角色)。 角色能够为报告权限和排查权限问题提供很大的帮助。 (Azure RBAC 仅支持通过角色分配权限。)
创建和使用具有所需确切权限的自定义角色。 实践中使用的典型角色:
- 安全部署
- 管理员
- 开发人员
- 支持人员
- 审核员
- 自动化过程
- 最终用户
只有当角色的权限与用户所需的权限完全匹配时,才使用内置角色。 可将用户分配到多个角色。
请记住,数据库引擎中的权限可以在以下范围内应用(范围越小,授予的权限的影响越小):
- Azure 中的服务器(
master
数据库中的特殊角色) - 数据库
- 架构
- 最佳做法是使用架构在数据库中授予权限。
- 对象(表、视图、过程等)
注意
不建议在对象级别应用权限,因为此级别会给整个实现带来不必要的复杂性。 如果决定使用对象级权限,应明确阐述这些权限。 这同样适用于列级权限,出于相同的原因,我们更不建议应用此类权限 另请注意,默认情况下,表级 DENY 不会覆盖列级授权。 这需要激活通用标准合规性服务器配置。
- Azure 中的服务器(
使用漏洞评估 (VA) 执行定期检查,以测试权限是否过多。
实现职责分离
内容来源:FedRamp:AC-04,NIST:AC-5,ISO:A.6.1.2、PCI 6.4.2,SOC:CM-3、SDL-3
“职责分离”描述将敏感任务拆分为要分配给不同用户的多个任务的要求。 职责分离有助于防止数据违规。
如何实现
识别所需的职责分离级别。 示例:
- 在开发/测试环境与生产环境之间
- 安全相关的任务、数据库管理员 (DBA) 管理级别任务与开发人员任务。
- 示例:审核员为角色级安全性 (RLS) 创建安全策略,并使用 DDL 权限实现 SQL 数据库对象。
识别有权访问系统的用户(和自动化过程)的综合层次结构。
根据所需的用户组创建角色,并将权限分配给角色。
- 对于通过 Azure 门户或 PowerShell 自动化完成的管理级任务,请使用 Azure 角色。 查找符合要求的内置角色,或者使用可用权限创建 Azure 自定义角色
- 在托管实例中为服务器范围的任务(创建新的登录名和数据库)创建服务器角色。
- 为数据库级任务创建数据库角色。
对于某些敏感任务,考虑创建由证书签名的特殊存储过程,以代表用户执行这些任务。 数字签名存储过程的一个重要优点是,如果更改了该过程,则会立即删除授予该过程的旧版本的权限。
使用 Azure Key Vault 中客户管理的密钥实现透明数据加密 (TDE),以便在数据所有者与安全所有者之间实现职责分离。
为了确保 DBA 无法看到高度敏感的数据但仍可执行 DBA 任务,可将 Always Encrypted 与角色分离配合使用。
如果使用 Always Encrypted 不可行(最起码在不付出极大成本和工作量的情况下做不到这一点,但如果付出,甚至可能会导致系统几乎不可用),可以通过补偿性的控制措施来采取折衷办法,例如:
- 在过程中进行人工干预。
- 审核线索 - 有关审核的详细信息,请参阅审核关键安全事件。
最佳实践
确保将不同的帐户用于开发/测试环境和生产环境。 不同的帐户有助于满足测试和生产系统分离的原则。
避免将权限分配给单个用户。 改为以一致的方式使用角色(数据库角色或服务器角色)。 使用角色能够为报告权限和排查权限问题提供很大的帮助。
当权限与所需权限完全匹配时使用内置角色 - 如果多个内置角色的所有权限的联合导致 100% 匹配,则还可以同时分配多个角色。
当内置角色授予的权限过多或不足时,创建并使用用户定义的角色。
还可以通过 T-SQL 的 SQL 代理作业步骤或适用于 Azure 角色的 Azure PIM 暂时执行角色分配(也称为动态职责分离 (DSD))。
确保 DBA 无权访问加密密钥或密钥存储,而有权访问密钥的安全管理员无权访问数据库。
始终确保针对安全相关的操作提供审核线索。
可以检索 Azure 内置角色的定义以查看所用的权限,并通过 PowerShell 根据这些信息的摘录和累积创建自定义角色。
由于 db_owner 数据库角色的任何成员都可以更改透明数据加密 (TDE) 等安全设置或更改 SLO,因此,应谨慎地授予此成员身份。 但是,许多任务要求使用 db_owner 特权。 例如,更改数据库选项等任何数据库设置的任务。 在任何解决方案中,审核都发挥着关键的作用。
无法限制 db_owner 的权限,因此应阻止管理帐户查看用户数据。 如果数据库中包含高度敏感的数据,可以使用 Always Encrypted 来安全阻止 db_owners 或任何其他 DBA 查看这些数据。
注意
对安全相关的任务或故障排除任务实现职责分离 (SoD) 会有难度。 其他方面(例如开发和最终用户角色)更易于分离。 当其他解决方案不可行时,大多数合规性相关的控制措施允许使用替代的控制功能,例如审核。
对于想要深入了解 SoD 的读者,建议阅读以下资源:
对于 Azure SQL 数据库和 SQL 托管实例:
对于 Azure 资源管理:
执行定期代码评审
内容来源:PCI:6.3.2,SOC:SDL-3
职责分离不局限于数据库中的数据,它还包括应用程序代码。 恶意代码可能会绕过安全控制。 在将自定义代码部署到生产环境之前,必须评审要部署的内容,这一点至关重要。
如何实现
使用支持源代码管理的数据库工具,例如 Azure Data Studio。
实现分离的代码部署过程。
在提交到主分支之前,必须由某个人员(代码本身的作者除外)检查代码是否存在提升特权的风险,以及是否存在恶意的数据修改,以防止出现欺诈和恶意访问。 可以使用源代码管理机制实现此目的。
最佳实践
标准化:实现每次更新代码时都要遵循的标准过程会很有帮助。
漏洞评估中的规则可以检查是否存在过多的权限、是否使用了旧加密算法,以及数据库架构中是否存在其他安全问题。
可以在 QA 或测试环境中使用高级威胁防护来执行更多的检查,此技术将扫描容易受到 SQL 注入攻击的代码。
要注意的方面的示例:
- 从自动化 SQL 代码更新部署内部创建用户或更改安全设置。
- 某个存储过程根据提供的参数以不一致的方式更新单元格中的货币值。
确保执行评审的人员是除原始代码作者以外的个人,且熟悉代码评审和安全编码。
确保知道所有代码更改来源。 代码可能位于 T-SQL 脚本中。 它可能是要以视图、函数、触发器和存储过程形式执行或部署的即席命令。 它可能是 SQL 代理作业定义(步骤)的一部分。 它还可能从 SSIS 包、Azure 数据工厂和其他服务的内部执行。
数据保护
数据保护是通过加密或模糊处理来防止重要信息遭到透露的一组功能。
注意
Microsoft 的 Azure SQL 数据库和 SQL 托管实例已通过 FIPS 140-2 级别 1 合规认证。 认证过程中已确认它严格使用 FIPS 140-2 级别 1 可接受的算法,以及这些算法的、经 FIPS 140-2 级别 1 验证的实例,包括符合所需密钥长度、密钥管理、密钥生成和密钥存储的要求。 此项认证意味着,我们的客户在处理数据或者交付系统或应用程序的过程中,可以满足使用 FIPS 140-2 级别 1 验证实例的需求或要求。
加密传输中的数据
内容来源:OSA 做法 #6,ISO 控制系列:Cryptography
当数据在客户端与服务器之间移动时为其提供保护。 请参阅网络安全性。
静态数据加密
内容来源:OSA 做法 #6,ISO 控制系列:Cryptography
静态加密是指对数据库、日志和备份文件中保存的数据进行加密保护。
如何实现
- 对于 2017 年后在 Azure SQL 数据库和 SQL 托管实例中创建的任何数据库,默认将启用通过服务托管密钥进行透明数据加密 (TDE)。
- 在托管实例中,如果数据库是使用本地服务器从还原操作创建的,则会遵循原始数据库的 TDE 设置。 如果未为原始数据库启用 TDE,则我们建议手动为托管实例启用 TDE。
最佳实践
不要将需要静态加密的数据存储在
master
数据库中。 无法使用 TDE 加密master
数据库。如果需要提高透明度并精细控制 TDE 保护,请使用 Azure Key Vault 中客户管理的密钥。 Azure Key Vault 允许随时撤销权限,使数据库不可访问。 可以集中管理 TDE 保护器及其他密钥,或使用 Azure Key Vault 按自己的计划轮换 TDE 保护器。
如果使用 Azure Key Vault 中客户管理的密钥,请参阅文章有关使用 Azure Key Vault 配置 TDE 的指导原则和如何使用 Azure Key Vault 配置异地灾难恢复。
注意
有些被视为客户内容的项(例如,表名、对象名称和索引名称)可能会在日志文件中传输,以供 Azure 提供支持和排查问题。
防止未经授权的高特权用户查看使用中的敏感数据
使用中的数据是指在执行 SQL 查询期间存储在数据库系统内存中的数据。 如果数据库存储敏感数据,则组织可能需要确保防止高特权用户查看数据库中的敏感数据。 高特权用户(例如组织中的 Microsoft 操作员或 DBA)应该能够管理数据库,但不能通过查询数据库来查看并潜在地透露 SQL 进程内存中的敏感数据。
需要确定哪些数据是敏感的,以及敏感数据是否必须在内存中加密并且不可供管理员以明文形式访问,用于确定这些事项的策略特定于你的组织以及你需要遵守的合规性规定。 请参阅相关要求:识别并标记敏感数据。
如何实现
- 使用 Always Encrypted 来确保不会以纯文本形式公开 Azure SQL 数据库或 SQL 托管实例中的敏感数据,即使是内存中/使用中的数据。 Always Encrypted 可以防止数据库管理员 (DBA) 和云管理员(或者可以仿冒未经授权的高特权用户的恶意行动者)查看数据,并使你能够以更高的力度控制谁可以访问数据。
最佳实践
Always Encrypted 不能取代静态数据加密 (TDE) 或传输中数据加密 (SSL/TLS)。 为了尽量减轻对性能和功能的影响,请不要将 Always Encrypted 用于非敏感数据。 建议将 Always Encrypted 与 TDE 和传输层安全性 (TLS) 结合使用,以全面保护静态数据、传输中的数据和使用中的数据。
在生产数据库中部署 Always Encrypted 之前,请先评估对所识别出的敏感数据列进行加密会带来的影响。 通常情况下,Always Encrypted 会降低对加密列的查询功能,并具有其他限制,如 Always Encrypted - 功能详细信息中所列。 因此,你可能需要在客户端重构你的应用程序来重新实现查询不支持的功能,或者/并且重构你的数据库架构,包括存储过程、函数、视图和触发器的定义。 如果现有应用程序未遵守 Always Encrypted 的限制,则可能无法使用加密列。 虽然支持 Always Encrypted 的 Microsoft 工具、产品和服务的生态系统在不断增长,但它们中还是有许多不能使用加密列。 加密列还可能会影响查询性能,具体取决于工作负荷的特征。
如果使用 Always Encrypted 来防止恶意 DBA 查看数据,请通过角色分离来管理 Always Encrypted 密钥。 安全管理员可以使用角色分离来创建物理密钥。 DBA 在数据库中创建用于描述物理密钥的列主密钥和列加密密钥元数据对象。 在此过程中,安全管理员不需要访问数据库,且 DBA 不需要访问纯文本形式的物理密钥。
- 有关详细信息,请参阅使用角色分离管理密钥一文。
将列主密钥存储在 Azure Key Vault 中,以方便管理。 避免使用会使密钥管理变得困难的 Windows 证书存储(以及一般的分布式密钥存储解决方案,而不是集中式密钥管理解决方案)。
仔细考虑使用多个密钥(列主密钥或列加密密钥)的利弊。 保留少量的密钥以减小密钥管理成本。 在稳定态的环境中(而不是在密钥轮换的中途),为每个数据库准备一个列主密钥和一个列加密密钥通常已足够。 如果有不同的用户组,而每个组使用不同的密钥并访问不同的数据,则可能需要更多的密钥。
根据合规要求轮换列主密钥。 如果还需要轮换列加密密钥,请考虑使用在线加密来尽量减少应用程序停机时间。
- 请参阅性能和可用性注意事项一文。
如果需要支持数据计算(相等性),请使用确定性加密。 否则请使用随机加密。 避免将确定性加密用于低熵数据集或采用众所周知分布形式的数据集。
如果你担心第三方在未经你同意的情况下以合法方式访问你的数据,请确保有权访问纯文本形式的密钥和数据的所有应用程序与工具都在 Azure 云外部运行。 如果第三方无权访问密钥,则除非绕过加密,否则他们无法解密数据。
Always Encrypted 无法轻松支持授予对密钥(和受保护数据)的临时访问权限。 例如,如果需要与 DBA 共享密钥,使 DBA 能够对敏感数据和加密的数据执行一些清理操作。 可靠撤销 DBA 的数据访问权限的唯一方法是,同时轮换用于保护数据的列加密密钥和列主密钥,而这是一项开销较高的操作。
若要访问已加密列中的纯文本值,用户需要有权访问用于保护列的列主密钥 (CMK)(在保存 CMK 的密钥存储中进行配置)。 用户还需要拥有“查看任何列主密钥定义”和“查看任何列加密密钥定义”数据库权限。
通过加密控制应用程序用户对敏感数据的访问
可以使用加密来确保只有有权访问加密密钥的特定应用程序用户才能查看或更新数据。
如何实现
- 使用单元级加密 (CLE)。 有关详细信息,请参阅加密数据列一文。
- 使用 Always Encrypted,但要注意其限制。 下面列出了限制。
最佳做法:
使用 CLE 时:
通过 SQL 权限和角色控制对密钥的访问。
使用 AES (推荐 AES 256) 进行数据加密。 由于存在已知漏洞,RC4、DES 和 TripleDES 等算法已遭弃用,请不要使用它们。
使用非对称密钥/证书(而不是密码)来保护对称密钥,以避免使用 3DES。
通过导出/导入(bacpac 文件)使用单元级加密迁移数据库时请小心。
- 有关在迁移数据时如何防止丢失密钥以及其他最佳做法指导,请参阅有关在 Azure SQL 数据库中使用单元级加密的建议。
请记住,Always Encrypted 主要用于防止 Azure SQL 数据库的高特权用户(云操作员、DBA)查看使用中的敏感数据 - 请参阅防止防止未经授权的高特权用户查看使用中的敏感数据。 使用 Always Encrypted 防止应用程序用户查看数据时,请注意以下难点:
- 默认情况下,支持 Always Encrypted 的所有 Microsoft 客户端驱动程序都会维护列加密密钥的全局缓存(每个应用程序一个缓存)。 在客户端驱动程序通过联系保存列主密钥的密钥存储获取纯文本列加密密钥后,将会缓存纯文本列加密密钥。 这使得将数据与多用户应用程序的用户相隔离变得困难。 如果应用程序在与密钥存储交互(例如 Azure Key Vault)时模拟最终用户,则在用户的查询使用列加密密钥填充缓存之后,需要同一个密钥但由其他用户触发的后续查询将使用缓存的密钥。 驱动程序不会调用密钥存储,也不会检查第二个用户是否有权访问列加密密钥。 因此,即使用户无权访问密钥,也可以查看加密的数据。 若要在多用户应用程序中实现用户隔离,可以禁用列加密密钥缓存。 禁用缓存会导致性能开销增大,因为驱动程序需要联系密钥存储来完成每个数据加密或解密操作。
在保留数据格式的同时防止应用程序用户在未经授权的情况下查看数据
防止未经授权的用户查看数据的另一种方法是对数据进行模糊处理或掩码,同时保留数据类型和格式,以确保用户应用程序可以继续处理和显示数据。
如何实现
- 使用动态数据掩码来模糊处理表列。
注意
Always Encrypted 不能与动态数据掩码配合工作。 无法加密和掩码同一个列,这意味着,需确定是要优先保护使用中的数据,还是通过动态数据掩码来对应用用户掩码数据。
最佳实践
注意
动态数据掩码不可用于防止高特权用户查看数据。 掩码策略不适用于拥有管理访问权限的用户,例如 db_owner。
不要允许应用用户运行即席查询(因为他们也许可以克服动态数据掩码)。
- 有关详细信息,请参阅使用推理或暴力破解技术绕过掩码一文。
使用适当的访问控制策略(通过 SQL 权限、角色、RLS)来限制用户在掩码列中进行更新的权限。 对列进行掩码不会阻止对该列进行更新。 如果查询掩码列时收到掩码数据的用户拥有写入权限,则他们可以更新这些数据。
动态数据掩码不会保留掩码值的统计属性。 这可能会影响查询结果(例如,包含筛选谓词的查询或者对掩码数据的联接)。
网络安全性
网络安全性是指用于保护传输到 Azure SQL 数据库的数据的访问控制和最佳做法。
配置客户端以安全连接到 SQL 数据库/SQL 托管实例
有关如何防范存在已知漏洞(例如,使用早期 TLS 协议和密码套件)的客户端计算机和应用程序连接到 Azure SQL 数据库和 SQL 托管实例的最佳做法。
如何实现
- 确保连接到 Azure SQL 数据库和 SQL 托管实例的客户端计算机使用最新传输层安全性 (TLS) 版本。
最佳实践
使用最低 TLS 版本设置,在 Azure 中的逻辑服务器或 SQL 托管实例级别强制实施最低 TLS 版本。 建议将最低 TLS 版本设置为 1.2,前提是在测试后确认应用程序支持它。 TLS 1.2 包含对以前版本中发现的漏洞的修复。
配置所有应用和工具以连接到启用了加密的 SQL 数据库
- Encrypt = On,TrustServerCertificate = Off(或者在非 Microsoft 驱动程序中配置相应的设置)。
如果应用使用的驱动程序不支持 TLS 或者支持早期版本的 TLS,请尽可能地更换驱动程序。 如果无法做到这一点,请认真评估安全风险。
- 减少通过 SSL 2.0、SSL 3.0、TLS 1.0 和 TLS 1.1 中的漏洞发起的攻击途径:根据传输层安全性 (TLS) 注册表设置,在连接到 Azure SQL 数据库的客户端计算机上禁用相关的途径。
- 检查客户端上的密码套件:TLS/SSL (Schannel SSP) 中的密码套件。 具体而言,根据配置 TLS 密码套件顺序禁用 3DES。
尽量减少受攻击面
尽量减少恶意用户可以攻击的特征数。 对 Azure SQL 数据库实现网络访问控制。
内容来源:OSA 做法 #5
如何实现
在 SQL 数据库中:
- 在服务器级别将“允许访问 Azure 服务”设置为“关闭”
- 使用 VNet 服务终结点和 VNet 防火墙规则。
- 使用专用链接。
在 SQL 托管实例中:
- 遵循网络要求中的指导原则。
最佳实践
通过连接到专用终结点(例如,使用专用数据路径)来限制对 Azure SQL 数据库和 SQL 托管实例的访问:
- 可将托管实例隔离在虚拟网络内,防止外部访问。 位于同一区域的相同或对等虚拟网络中的应用程序和工具可以直接访问它。 位于不同区域的应用程序和工具可使用虚拟网络到虚拟网络连接,或使用 ExpressRoute 线路对等互连来建立连接。 客户应使用网络安全组 (NSG) 来仅限通过端口 1433 访问需要访问托管实例的资源。
- 对于 SQL 数据库,请使用专用链接功能,该功能可为虚拟网络中的服务器提供专用 IP。 还可使用配置了虚拟网络防火墙规则的虚拟网络服务终结点来限制对服务器的访问。
- 移动用户应使用点到站点 VPN 连接,通过数据路径进行连接。
- 连接到本地网络的用户应使用站点到站点 VPN 连接或 ExpressRoute,通过数据路径进行连接。
可以通过连接到公共终结点(例如,使用公共数据路径)来访问 Azure SQL 数据库和 SQL 托管实例。 应考虑以下最佳做法:
- 对于 SQL 数据库中的服务器,请使用 IP 防火墙规则,仅限访问已授权的 IP 地址。
- 对于 SQL 托管实例,请使用网络安全组 (NSG),仅限通过端口 3342 访问所需的资源。 有关详细信息,请参阅在公共终结点中安全使用托管实例。
注意
SQL 托管实例公共终结点默认未启用,必须显式启用它。 如果公司政策禁止使用公共终结点,请首先使用 Azure Policy 来防止启用公共终结点。
设置 Azure 网络组件:
- 按照 Azure 网络安全最佳做法进行操作。
- 根据 Azure 虚拟网络常见问题解答 (FAQ) 和计划中所述的最佳做法规划虚拟网络配置。
- 将虚拟网络划分为多个子网,并将类似角色的资源(例如,前端与后端资源)分配到同一子网。
- 使用网络安全组 (NSG) 来控制 Azure 虚拟网络边界范围内子网之间的流量。
- 为订阅启用 Azure 网络观察程序,以监视入站和出站网络流量。
配置 Power BI 以安全连接到 SQL 数据库/SQL 托管实例
最佳实践
对于 Power BI Desktop,请尽可能地使用专用数据路径。
根据传输层安全性 (TLS) 注册表设置在客户端计算机上设置注册表项,确保 Power BI Desktop 使用 TLS1.2 进行连接。
通过 Power BI 行级安全性 (RLS) 限制特定用户的数据访问权限。
配置应用程序服务以安全连接到 SQL 数据库/SQL 托管实例
最佳实践
对于简单的 Web 应用,通过公共终结点进行连接需要将“允许 Azure 服务”设置为“打开”。
将应用与 Azure 虚拟网络集成,以通过专用数据路径连接到托管实例。 (可选)还可以部署采用应用程序服务环境 (ASE) 的 Web 应用。
对于连接到 SQL 数据库中的数据库的、采用 ASE 的 Web 应用或者与虚拟网络集成的 Web 应用,可以使用虚拟网络服务终结点和虚拟网络防火墙规则来限制从特定虚拟网络和子网的访问。 然后,将“允许 Azure 服务”设置为“关闭”。 还可以通过专用数据路径将 ASE 连接到 SQL 托管实例中的托管实例。
确保 Web 应用按照使用 Azure 应用程序服务保护平台即服务 (PaaS) Web 和移动应用程序的最佳做法一文进行了配置。
安装 Web 应用程序防火墙 (WAF),以防止 Web 应用遭到常见的恶意利用和出现漏洞。
配置 Azure 虚拟机以安全连接到 SQL 数据库/SQL 托管实例
最佳实践
在 Azure 虚拟机的 NSG 中结合使用“允许”和“拒绝”规则,以控制可从 VM 访问哪些区域。
确保 VM 根据 Azure 中 IaaS 工作负载的安全性最佳做法一文进行了配置。
确保所有 VM 与特定的虚拟网络和子网相关联。
根据关于强制隧道中的指导,评估是否需要默认路由 0.0.0.0/Internet。
- 如果需要(例如在前端子网中),请保留默认路由。
- 如果不需要(例如在中间层或后端子网中),请启用强制隧道,使流量不会通过 Internet 抵达本地(即跨界)。
如果使用对等互连或者连接到本地,请实现可选默认路由。
如果需要将虚拟网络中的所有流量发送到网络虚拟设备进行数据包检查,请实现用户定义的路由。
使用虚拟网络服务终结点通过 Azure 主干网络安全访问 Azure 存储等 PaaS 服务。
监视、日志记录和审核
本部分所述的功能可帮助你检测异常活动,这些活动指示非同寻常或者潜在有害的访问或恶意利用数据库的企图。 本部分还将提供有关配置数据库审核来跟踪和捕获数据库事件的最佳做法。
防范数据库遭到攻击
高级威胁防护可在发生异常活动时提供安全警报,让我们检测潜在威胁并做出响应。
如何实现
- 使用适用于 SQL 的高级威胁防护来检测异常情况或者可能有害的试图访问或恶意利用数据库的行为,包括:
- SQL 注入攻击。
- 凭据盗窃/泄露。
- 特权滥用。
- 数据透露。
最佳实践
为特定服务器或托管实例配置 Microsoft Defender for SQL。 还可以通过启用 Microsoft Defender for Cloud,为订阅中的所有服务器和托管实例配置 Microsoft Defender for SQL。
若要获得完整的调查体验,建议启用 SQL 数据库审核。 使用审核可以跟踪数据库事件,并将这些事件写入到 Azure 存储帐户或 Azure Log Analytics 工作区中的审核日志。
审核关键安全事件
跟踪数据库事件有助于了解数据库活动。 可以洞察可能指示业务关注点或可疑安全违规的差异与异常。 此措施还有助于遵守法规标准。
如何实现
启用 SQL 数据库审核或托管实例审核以跟踪数据库事件,并将这些事件写入到 Azure 存储帐户、Log Analytics 工作区(预览版)或事件中心(预览版)中的审核日志。
可将审核日志写入 Azure 存储帐户、写入 Log Analytics 工作区(供 Azure Monitor 日志使用),或写入事件中心(供事件中心使用)。 可以将这些选项随意组合起来进行配置,审核日志会写入到每一个之中。
最佳实践
- 在服务器上配置 SQL 数据库审核或配置托管实例审核以审核事件后,该服务器上所有现有的和新建的数据库都会被审核。
- 审核策略默认包括对数据库执行的所有操作(查询、存储过程,以及成功和失败的登录),这可能会导致生成大量的审核日志。 建议客户使用 PowerShell 对不同类型的操作和操作组配置审核。 此项配置有助于控制审核的操作数量,并将事件丢失的风险降到最低。 自定义审核配置可让客户仅捕获所需的审核数据。
- 可以在 Azure 门户中直接使用审核日志,或者从配置的存储位置使用。
注意
启用在 Log Analytics 中进行审核会根据引入速率产生成本。 请注意,使用此选项会产生相关的成本;或者,可以考虑将审核日志存储在 Azure 存储帐户中。
其他资源
保护审核日志
限制对存储帐户的访问,以支持职责分离,并将 DBA 与审核员区分开来。
如何实现
- 将审核日志保存到 Azure 存储时,请确保按照最低安全原则来限制对存储帐户的访问。 控制谁有权访问存储帐户。
- 有关详细信息,请参阅授权访问 Azure 存储。
最佳实践
控制对审核目标的访问是将 DBA 与审核员相区分时使用的重要概念。
审核对敏感数据的访问时,请考虑使用数据加密来保护数据,以免向审核员透露信息。 有关详细信息,请参阅防止未经授权的高特权用户查看使用中的敏感数据部分。
安全管理
本部分介绍有关管理数据库安全态势的各个方面和最佳做法。 其中提供了有关确保根据安全标准配置数据库、发现漏洞,以及分类和跟踪对数据库中潜在敏感数据的访问的最佳做法。
确保根据安全最佳做法配置数据库
通过发现并修正潜在数据库漏洞来主动改善数据库的安全性。
如何实现
- 启用 SQL 漏洞评估 (VA) 来扫描数据库的安全问题,并使其定期对数据库自动运行。
最佳实践
对数据库运行首次 VA,在补救不符合安全最佳做法的失败检查后反复运行 VA。 设置可接受配置的基线,直到扫描结果全部正常,或所有检查均已通过。
将定期的重复扫描配置为每周运行一次,并配置相关人员来接收摘要电子邮件。
完成每周扫描后查看 VA 摘要。 对于发现的任何漏洞,评估与前一次扫描结果的偏差,并确定是否应解决本次检查发现的问题。 查看配置发生更改是否有合理的原因。
解决检查发现的问题并更新相关的基线。 为解决措施创建票证项,并在解决问题之前跟踪这些项。
其他资源
识别并标记敏感数据
发现可能包含敏感数据的列。 什么数据是敏感数据在很大程度上取决于客户、合规性规定等,并且需要由负责该数据的用户进行评估。 将列分类以使用基于敏感性的高级审核和保护方案。
如何实现
- 使用 SQL 数据发现和分类来发现、分类、标记和保护数据库中的敏感数据。
- 在 SQL 数据发现和分类仪表板中查看自动发现创建的分类建议。 接受相关的分类,以使用分类标签来持久标记敏感数据。
- 对于未被自动机制发现的任何其他敏感数据字段,请手动添加分类。
- 有关详细信息,请参与 SQL 数据发现和分类。
最佳实践
定期监视分类仪表板,以准确评估数据库的分类状态。 可以导出或打印有关数据库分类状态的报告,以使在合规与审核措施中共享。
持续监视 SQL 漏洞评估中建议的敏感数据的状态。 跟踪敏感数据发现规则,识别建议列中的任何分类偏差。
跟踪对敏感数据的访问
在审核日志中监视谁访问了敏感数据,并捕获对敏感数据运行的查询。
如何实现
- 结合使用 SQL 审核和数据分类。
- 在 SQL 数据库审核日志中,可以专门跟踪对敏感数据的访问。 还可以查看访问的数据及其敏感性标签等信息。 有关详细信息,请参阅数据发现和分类和审核对敏感数据的访问。
最佳实践
可视化安全性与合规性状态
使用统一的基础结构安全管理系统来增强数据中心(包括 SQL 数据库中的数据库)的安全态势。 查看有关数据库安全性与合规性状态的建议列表。
如何实现
- 在 Microsoft Defender for Cloud 中监视与 SQL 相关的安全建议和活动威胁。
常见安全威胁和潜在缓解措施
本部分帮助你找到用于防范特定攻击途径的安全措施。 遵循上述一条或多条安全指导原则预期可以实现大部分缓解措施。
安全威胁:数据透露
Data 透露是指在未经授权的情况下,从计算机或服务器复制、传输或检索数据。 查看维基百科中的数据透露定义。
通过公共终结点连接到服务器会带来数据透露的风险,因为这需要客户向公共 IP 打开其防火墙。
场景 1:Azure VM 上的某个应用程序连接到 Azure SQL 数据库中的某个数据库。 恶意行动者获取 VM 的访问权限并入侵到其中。 在此场景中,数据透露表示使用恶意 VM 的外部实体连接到数据库,复制个人数据,并将这些数据存储在 Blob 存储中或者不同订阅内的不同 SQL 数据库中。
场景 2:恶意 DBA。 这种场景通常出现在受管制行业的安全敏感型客户那里。 在此场景中,高特权用户可将 Azure SQL 数据库中的数据复制到不受数据所有者控制的其他订阅。
潜在缓解措施
Azure SQL 数据库和 SQL 托管实例目前提供以下技术来缓解数据透露威胁:
- 在 Azure VM 的 NSG 中结合使用“允许”和“拒绝”规则,以控制可从 VM 访问哪些区域。
- 如果在 SQL 数据库中使用服务器,请设置以下选项:
- 将“允许 Azure 服务”设置为“关闭”。
- 设置 VNet 防火墙规则,仅允许来自包含你的 Azure VM 的子网的流量。
- 使用专用链接
- 对于 SQL 托管实例,使用专用 IP 访问默认可以解决恶意 VM 的首要数据透露隐患。 在子网中启用子网委托功能,以在 SQL 托管实例子网中自动设置最严格的策略。
- 恶意 DBA 隐患主要出现在 SQL 托管实例上,因为 SQL 托管实例的受攻击面较大,而网络要求对客户是可见的。 此问题的最佳缓解措施是首先应用本安全指南中的所有做法,以防止出现恶意 DBA 的情景(不仅可以解决数据透露)。 Always Encrypted 是保护敏感数据的一种方法,它可以加密敏感数据,并使 DBA 无法访问密钥。
业务连续性和可用性的安全性方面
大多数安全标准在操作连续性方面解决数据可用性问题,实现此效果的方式是实施冗余和故障转移功能来避免单一故障点。 对于灾难恢复方案,常见的做法是保留数据和日志文件的备份。 以下部分概述了 Azure 中内置的功能。 此外,提供了可根据具体需求进行配置的其他选项:
Azure 提供内置的高可用性:SQL 数据库和 SQL 托管实例的高可用性
“业务关键”层包括故障转移组、完整和差异日志备份,以及默认已启用的时间点还原备份:
可配置其他业务连续性功能,例如,区域冗余配置和跨不同的 Azure 地理区域的故障转移组: