迁移到 AES-256 GCM 加密

Looker 使用 AES-256 伽罗瓦/计数器模式 (GCM) 加密来加密内部存储的敏感数据,包括:

  • Looker 内部数据库的备份
  • 数据库和服务连接信息
  • 用户身份验证信息
  • 用户属性值
  • 已缓存或准备好传送的客户数据

如需详细了解 Looker 会加密哪些数据,请提交支持请求

系统使用唯一的数据密钥对数据进行加密,并包含经过签名且具有版本号的加密信封,以保证验证。此模式需要使用外部客户主密钥 (CMK)。CMK 用于派生、加密和解密密钥加密密钥 (KEK),而 KEK 则用于派生、加密和解密数据密钥。

加密仅适用于 Looker 的内部数据库和缓存。客户数据库不会受到 Looker 加密的影响。此外,只有静态数据(存储在磁盘上的数据)会以这种方式加密。

客户托管的安装可以使用自己的 AWS KMS 账号或自己的自定义密钥管理系统。所有数据密钥和 KEK 均已加密,并在客户托管的 Looker 安装中内部使用。如果不使用 AWS KMS,则应妥善保管外部 CMK。

想要使用 GCM 加密的现有客户托管安装需要从旧版加密迁移到新的 GCM 加密。新的客户托管安装需要进行额外的配置才能使用 GCM 加密。

请依次按照以下部分中的步骤操作。

停止 Looker 并创建完整备份

如果您要从现有 Looker 实例迁移到 GCM 加密,请务必创建完整备份,以防加密迁移出现问题。如果您要安装新的 Looker 实例,请跳过本部分。

如果您使用的是 Looker 的内部数据库:

cd looker
./looker stop
tar -zcvf /tmp/looker-pre-encrypt.tar.gz  /home/lookerops/looker --exclude=.cache --exclude=log --exclude=.tmp --exclude=.snapshots --exclude=looker.jar --exclude=authorized_keys --exclude=dr-log --exclude=core

如果您运行的是用于存储 Looker 应用数据的外部 MySQL 数据库,请单独备份该数据库。如果数据库是 MySQL 实例,请截取快照。数据库相对较小,因此应该只需几分钟时间。然后停止 Looker。

如果 Looker 是集群的,请务必先停止每个节点,然后再继续操作:

cd looker
./looker stop

如果您稍后发出迁移命令时仍有任何节点在运行,该命令将会失败,并显示以下消息:“有其他实时节点连接到此后端 Looker 数据库。If Looker was shutdown within the last minute, try again shortly, otherwise verify all nodes in the cluster are shut down."

生成 CMK

如果您使用的是 AWS KMS,请使用 AWS 管理控制台或 API 创建 CMK

如果您不使用 AWS KMS,请生成一个 Base64 格式的 32 字节 CMK。您可以将 CMK 存储在环境变量或文件中。

  • 如需生成 CMK 并将其存储在环境变量中,您可以使用以下命令生成 CMK:

    openssl rand -base64 32
    

    生成 CMK 后,将其复制,然后使用以下命令将 CMK 存储在 LKR_MASTER_KEY_ENV 环境变量中(其中 <CMK_value> 是您使用上一个命令生成的 CMK):

    export LKR_MASTER_KEY_ENV=<CMK_value>
    

    如果 Looker 是集群的,请在集群中的每个节点上运行上述命令。

  • 如需生成 CMK 并将其存储在文件中,您可以使用以下命令(其中 <path_to_CMK_file> 是存储 CMK 的路径和文件名):

    openssl rand -base64 32 > <path_to_key_file>
    

生成 CMK 文件后,将密钥文件权限设为当前用户只读:

chmod 0400 <path_to_key_file>

生成 CMK 后,请务必将其存储在安全且永久的位置,然后再继续操作!在对内部数据库进行加密后丢失 CMK 可能会导致实例丢失。

创建 AWS IAM 角色

如果您不使用 AWS KMS,请跳过此部分。

如果您使用的是 AWS KMS,Looker 建议您为您的 CMK 创建新的 IAM 角色,并将其附加到您的 Looker 实例

以下 IAM 角色示例包含您的 CMK 所需的最低权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "kms:GenerateRandom",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:Encrypt",
                "kms:Generate*",
            ],
            "Resource": "arn:aws:kms:*:*:key/*"
        }
    ]
}

设置环境变量

如果您使用的是 AWS KMS,请将 AWS_REGION 环境变量设置为您的 AWS 区域,并将 LKR_AWS_CMK 环境变量设置为您的 CMK 别名:

export AWS_REGION=<AWS_region>
export LKR_AWS_CMK=alias/<CMK_alias>

您还可以选择设置 LKR_AWS_CMK_EC 环境变量,以设置自定义 AWS 加密上下文。如果您未设置此环境变量,Looker 将使用默认加密上下文,即字符串 Looker_Encryption_Context

export LKR_AWS_CMK_EC=<My_Encryption_Context>

如果您不使用 AWS KMS,而是将 CMK 存储在文件中,请将 LKR_MASTER_KEY_FILE 环境变量设置为 CMK 文件的路径:

export LKR_MASTER_KEY_FILE=<path_to_key_file>

如果您不使用 AWS KMS,并且将 CMK 存储在环境变量中,请将 LKR_MASTER_KEY_ENV 环境变量设置为 CMK 的值:

export LKR_MASTER_KEY_ENV=<CMK_value>

如果 Looker 是集群,请在集群中的每个节点上运行上述命令。

加密内部数据库

如果您要将现有 Looker 实例迁移到 GCM 加密,请迁移 Looker 的内部数据库并启动 Looker:

java -jar looker.jar migrate_encryption
./looker  start

如果您的 Looker 实例以 -d <db.yaml>--internal-db-creds=<db.yaml> 启动选项开头(这些选项提供包含数据库凭据的 YAML 文件的路径),您需要在 java -jar looker.jar migrate_encryption 命令中添加相同的选项。

例如 java -jar looker.jar migrate_encryption -d /path/file

如果您要安装新的 Looker 实例,则在启动新的 Looker 实例时,加密流程将随之开始。

加密过程通常只需不到一分钟的时间。Looker 启动后,您可以在 Looker 日志中搜索 GCM 来验证新的加密方式:

grep GCM log/looker.log

2018-10-29 22:42:20.279 +0000 [INFO|007d0|crypt] :: Starting migration from AES-128-CBC Legacy to AES-GCM-256
2018-10-29 22:42:20.468 +0000 [INFO|007d0|db:looker] :: (0.000152s) INSERT INTO "SETTING" ("KEY", "VALUE") VALUES

问题排查

本部分列出了一些常见错误及其解决方法:

  • 找不到任务“migrate_encryption”:请将您的 Looker 实例更新为 Looker 6.4。

  • Looker 无法启动,原因是:缺少后备密钥库:Looker 找不到 CMK。检查 LKR_MASTER_KEY_FILE 环境变量中的 CMK 路径是否正确。

  • Looker 无法启动,原因是:主密钥的大小无效,必须为 32 字节,但为 X:CMK 的长度必须为 32 字节。

  • Looker 无法启动,原因如下: 后备密钥文件的权限必须为 0400,但为 XXX:CMK 文件必须是只读的,且 chmod 值为 0400