静态加密概念和配置指南

重要

Microsoft SQL Server 2019 大数据群集附加产品将停用。 对 SQL Server 2019 大数据群集的支持将于 2025 年 2 月 28 日结束。 具有软件保障的 SQL Server 2019 的所有现有用户都将在平台上获得完全支持,在此之前,该软件将继续通过 SQL Server 累积更新进行维护。 有关详细信息,请参阅公告博客文章Microsoft SQL Server 平台上的大数据选项

从MICROSOFT SQL Server 2019 CU8 大数据群集开始,静态加密功能可用于向平台中存储的所有数据提供应用程序级加密。 本指南介绍大数据群集静态加密功能集的概念、体系结构和配置。

SQL Server 大数据群集将数据存储在以下位置:

  • SQL Server 主实例。
  • HDFS。 由存储池和 Spark 使用。

有两种方法可以透明加密 SQL Server 大数据群集中的数据:

  • 卷加密。 Kubernetes 平台支持此方法。 这是大数据群集部署的最佳做法。 本文不涉及卷加密。 请参阅 Kubernetes 平台或设备文档,了解如何正确加密用于 SQL Server 大数据群集的卷。
  • 应用程序级加密。 此体系结构是指应用程序在将数据写入磁盘之前处理数据的加密。 如果卷公开,攻击者将无法在其他位置还原数据项目,除非目标系统也配置了相同的加密密钥。

SQL Server 大数据群集的静态加密功能集支持 SQL Server 和 HDFS 组件应用程序级加密的核心方案。

此功能提供以下功能:

  • 系统管理的静态加密。 此功能在 CU8+ 中可用。
  • 用户管理的静态加密,也称为自带密钥(BYOK)。 SQL Server 2019 CU8 中引入了由服务管理的集成。 SQL Server 2019 CU11+ 中引入了外部密钥提供程序集成。

有关详细信息,请参阅 SQL Server 大数据群集中的密钥版本

密钥定义

  • SQL Server 大数据群集密钥管理服务 (KMS)

    负责管理 SQL Server 大数据群集静态加密功能的密钥和证书的控制器托管服务。 该服务支持以下功能:

    • 安全管理和存储用于静态加密的密钥和证书。
    • Hadoop KMS 兼容性。 KMS 充当大数据群集上的 HDFS 组件的密钥管理服务。
    • SQL Server 透明数据加密 (TDE) 证书管理。
  • 系统管理的密钥

    大数据群集 KMS 服务管理 SQL Server 和 HDFS 的所有密钥和证书

  • 用户定义的密钥

    要由大数据群集 KMS 管理的用户定义的密钥,通常称为自带密钥。 SQL Server 大数据群集支持用于 SQL Server 和 HDFS 组件加密的密钥的自定义定义。 大数据群集 KMS 管理这些密钥。

    谨慎

    SQL Server 主实例继承 SQL Server TDE 功能。 但是,不支持将自定义密钥从文件手动加载到 Pod 中,在 SQL Server 上注册这些密钥并将其用于 TDE。 大数据群集 KMS 不会管理这些密钥。 这种情况可能导致数据库不可读。 若要正确使用外部提供的密钥,请使用本文中所述的“外部提供程序”功能。

  • 外部供应商

    支持将加密操作委托给与大数据群集 KMS 兼容的外部密钥解决方案。 SQL Server 2019 CU11+ 支持此功能。 启用此功能后,加密的根密钥托管在大数据群集控制器外部。

SQL Server 大数据群集上的静态加密

大数据群集 KMS 控制器服务为系统管理的密钥和外部提供程序控制的密钥提供支持,以实现 SQL Server 和 HDFS 上的静态数据加密。

这些密钥和证书由服务管理。 本文提供有关如何与服务交互的操作指导。

此功能集引入了大数据群集 KMS 控制器服务,为 SQL Server 和 HDFS 上的静态数据加密提供系统管理的密钥和证书。 这些密钥和证书由服务管理。 本文提供有关如何与服务交互的操作指导。

  • SQL Server 实例使用已建立的 透明数据加密(TDE) 功能。
  • HDFS 在每个 Pod 中使用本机 Hadoop KMS 来与控制器上的大数据群集 KMS 交互。 此方法支持 HDFS 加密区域,这些区域在 HDFS 上提供安全路径。

SQL Server 实例

  • 系统生成的证书安装在要用于 TDE 命令的 SQL Server Pod 上。 系统管理的证书命名标准为 TDECertificate + timestamp。 例如,TDECertificate2020_09_15_22_46_27
  • 主实例大数据群集预配的数据库和用户数据库不会自动加密。 数据库管理员可以使用已安装的证书来加密任何数据库。
  • 使用系统生成的证书自动加密计算池和存储池。
  • 尽管从技术上可以使用 T-SQL EXECUTE AT 命令进行数据池加密,但目前不建议使用和不支持数据池加密。 使用此方法加密数据池数据库可能无效,加密可能未在所需状态下发生。 此方法还会为下一版本创建不兼容的升级路径。
  • SQL Server 密钥轮换是使用标准 T-SQL 管理命令实现的。 有关详细信息,请参阅 SQL Server 大数据群集透明数据加密(TDE)静态使用指南
  • 加密监视通过适用于 TDE 的现有标准 SQL Server DMV 进行。
  • 支持将启用 TDE 的数据库备份和还原到集群中。
  • 支持高可用性。 如果 SQL Server 的主实例上的数据库已加密,则数据库的所有次要副本也会加密。

HDFS 加密区域

  • 需要 Active Directory 集成才能为 HDFS 启用加密区域。
  • 在 Hadoop KMS 中预配系统生成的密钥。 键名称为 securelakekey. 在 CU8 上,默认密钥为 256 位,我们支持 256 位 AES 加密。
  • 在名为 /securelake 的路径上使用上述系统生成的密钥预配默认加密区域。
  • 用户可以使用本指南中提供的特定说明创建其他密钥和加密区域。 用户能够在创建密钥期间选择密钥大小 128、192 或 256。
  • HDFS 加密区域的密钥轮换操作是通过使用 azdata 来实现的。 有关详细信息,请参阅 SQL Server 大数据群集 HDFS 加密区域使用指南
  • 不支持在加密区域顶部装载 HDFS 分层。

静态加密管理

以下列表包含静态加密的管理功能:

  • SQL Server TDE 管理是使用标准 T-SQL 命令执行的。
  • HDFS 加密区域 和 HDFS 密钥管理是使用 azdata 命令执行的。
  • 以下管理功能是使用 运作笔记本执行的:
    • HDFS 密钥备份和恢复
    • HDFS 密钥删除

配置指南

SQL Server 大数据群集的新部署期间,从 CU8 起,默认情况下会启用和配置数据静态加密。 也就是说:

  • 大数据群集 KMS 组件部署在控制器中,并生成一组默认密钥和证书。
  • SQL Server 已启用 TDE 部署,并且由控制器安装证书。
  • Hadoop KMS for HDFS 配置为与大数据群集 KMS 对接,以便进行加密操作。 HDFS 加密区域已配置并可供使用。

上一部分所述的要求和默认行为适用。

如果执行 SQL Server 大数据群集 CU8 的全新部署或直接升级到 CU9,则无需执行其他步骤。

升级方案

在现有群集上,升级过程不会对尚未加密的用户数据强制实施新的加密或重新加密。 此行为是设计造成的,每个组件需要考虑以下问题:

  • SQL Server

    • SQL Server 主实例。 升级过程不会影响任何主实例数据库和已安装的 TDE 证书。 建议在升级过程之前备份数据库和手动安装的 TDE 证书。 我们还建议将这些工件存储在大数据群集之外。
    • 计算和存储池。 这些数据库是系统管理的、易失性的,在群集升级时重新创建并自动加密。
    • 数据池。 升级不会影响数据池的 SQL Server 实例中的数据库。
  • HDFS(Hadoop分布式文件系统)

    升级过程不会接触加密区域外的 HDFS 文件和文件夹。

从 CU8 或更早版本升级到 CU9

无需执行其他步骤。

从 CU6 或更早版本升级到 CU8

谨慎

在升级到 SQL Server 大数据群集 CU8 之前,请执行数据的完整备份。

不会配置加密区域。 Hadoop KMS 组件不会配置为使用大数据群集 KMS。 若要在升级后配置和启用 HDFS 加密区域,请按照下一部分中的说明进行作。

升级到 CU8 后启用 HDFS 加密区域

如果将群集升级到 CU8(azdata upgrade)并且想要启用 HDFS 加密区域,有两个选项:

要求:

  • Active Directory 集成群集。
  • 在 AD 模式下配置并记录到群集中的 Azure Data CLI (azdata)。

按照此过程重新配置支持加密区域的群集。

  1. 在执行azdata升级后,请保存以下脚本。

    脚本执行要求:

    • 这两个脚本应位于同一目录中。
    • kubectl $HOME /.kube 文件夹中 Kubernetes 的 PATH 配置文件。

    此脚本应命名 为 run-key-provider-patch.sh

    #!/bin/bash
    
    if [[ -z "${BDC_DOMAIN}" ]]; then
      echo "BDC_DOMAIN environment variable with the ___domain name of the cluster is not defined."
      exit 1
    fi
    
    if [[ -z "${BDC_CLUSTER_NS}" ]]; then
      echo "BDC_CLUSTER_NS environment variable with the cluster namespace is not defined."
      exit 1
    fi
    
    kubectl get configmaps -n test
    
    diff <(kubectl get configmaps mssql-hadoop-storage-0-configmap -n $BDC_CLUSTER_NS -o json | ./updatekeyprovider.py) <(kubectl get configmaps mssql-hadoop-storage-0-configmap -n $BDC_CLUSTER_NS -o json | python -m json.tool)
    
    diff <(kubectl get configmaps mssql-hadoop-sparkhead-configmap -n $BDC_CLUSTER_NS -o json | ./updatekeyprovider.py) <(kubectl get configmaps mssql-hadoop-sparkhead-configmap -n $BDC_CLUSTER_NS -o json | python -m json.tool)
    
    # Replace the config maps.
    #
    kubectl replace -n $BDC_CLUSTER_NS -o json -f <(kubectl get configmaps mssql-hadoop-storage-0-configmap -n $BDC_CLUSTER_NS -o json | ./updatekeyprovider.py)
    
    kubectl replace -n $BDC_CLUSTER_NS -o json -f <(kubectl get configmaps mssql-hadoop-sparkhead-configmap -n $BDC_CLUSTER_NS -o json | ./updatekeyprovider.py)
    
    # Restart the pods which need to have the necessary changes with the core-site.xml
    kubectl delete pods -n $BDC_CLUSTER_NS nmnode-0-0
    kubectl delete pods -n $BDC_CLUSTER_NS storage-0-0
    kubectl delete pods -n $BDC_CLUSTER_NS storage-0-1
    
    # Wait for sometime for pods to restart
    #
    sleep 300
    
    # Check for the KMS process status.
    #
    kubectl exec -n $BDC_CLUSTER_NS -c hadoop nmnode-0-0 -- bash -c 'ps aux | grep kms'
    kubectl exec -n $BDC_CLUSTER_NS -c hadoop storage-0-0 -- bash -c 'ps aux | grep kms'
    kubectl exec -n $BDC_CLUSTER_NS -c hadoop storage-0-1 -- bash -c 'ps aux | grep kms'
    

    此脚本应命名 为 updatekeyprovider.py

    #!/usr/bin/env python3
    
    import json
    import re
    import sys
    import xml.etree.ElementTree as ET
    import os
    
    class CommentedTreeBuilder(ET.TreeBuilder):
        def comment(self, data):
            self.start(ET.Comment, {})
            self.data(data)
            self.end(ET.Comment)
    
    domain_name = os.environ['BDC_DOMAIN']
    
    parser = ET.XMLParser(target=CommentedTreeBuilder())
    
    core_site = 'core-site.xml'
    j = json.load(sys.stdin)
    cs = j['data'][core_site]
    csxml = ET.fromstring(cs, parser=parser)
    props = [prop.find('value').text for prop in csxml.findall(
        "./property/name/..[name='hadoop.security.key.provider.path']")]
    
    kms_provider_path=''
    
    for x in range(5):
        if len(kms_provider_path) != 0:
            kms_provider_path = kms_provider_path + ';'
        kms_provider_path = kms_provider_path + 'nmnode-0-0.' + domain_name
    
    if len(props) == 0:
        prop = ET.SubElement(csxml, 'property')
        name = ET.SubElement(prop, 'name')
        name.text = 'hadoop.security.key.provider.path'
        value = ET.SubElement(prop, 'value')
        value.text = 'kms://https@' + kms_provider_path + ':9600/kms'
        cs = ET.tostring(csxml, encoding='utf-8').decode('utf-8')
    
    j['data'][core_site] = cs
    
    kms_site = 'kms-site.xml.tmpl'
    ks = j['data'][kms_site]
    
    kp_uri_regex = re.compile('(<name>hadoop.kms.key.provider.uri</name>\s*<value>\s*)(.*)(\s*</value>)', re.MULTILINE)
    
    def replace_uri(match_obj):
        key_provider_uri = 'bdc://https@hdfsvault-svc.' + domain_name
        if match_obj.group(2) == 'jceks://file@/var/run/secrets/keystores/kms/kms.jceks' or match_obj.group(2) == key_provider_uri:
            return match_obj.group(1) + key_provider_uri + match_obj.group(3)
        return match_obj.group(0)
    
    ks = kp_uri_regex.sub(replace_uri, ks)
    
    j['data'][kms_site] = ks
    print(json.dumps(j, indent=4, sort_keys=True))
    

    使用相应的参数运行 run-key-provider-patch.sh

外部提供商的配置

如前几节所述,SQL Server 2019 CU8+ 大数据群集部署默认使用系统管理的密钥启用静态加密功能。 为了使外部密钥提供程序能够保护 SQL Server 和 HDFS 加密的根密钥,请参阅 SQL Server 大数据群集中的外部密钥提供程序

后续步骤

若要详细了解如何在 SQL Server 大数据群集上使用密钥版本,请参阅 SQL Server 大数据群集中的密钥版本

若要详细了解如何有效地使用静态加密 SQL Server 大数据群集,请参阅以下文章:

若要了解有关 SQL Server 大数据群集 的详细信息,请参阅以下概述: