使用 Cloud HSM 密钥处理 Apache 流量

本指南介绍了如何设置 Apache 服务器,以使用 Cloud HSM 密钥在 Debian 11 (Bullseyes) 上进行 TLS 签名。您可能需要修改这些命令,才能在您的操作系统或 Linux 发行版中使用。

您可以在 kms-solutions GitHub 代码库中找到本教程基于 Terraform 的蓝图版本。

准备工作

前提条件是完成 OpenSSL 设置中记录的配置。

OpenSSL 设置完成后,请确保安装了最新版本的 Apache:

sudo apt-get update
sudo apt-get install apache2

配置

创建 Cloud KMS 托管的签名密钥

在您的Google Cloud 项目内,在您之前为 OpenSSL 配置的密钥环中创建 Cloud KMS EC-P256-SHA256 签名密钥:

gcloud kms keys create "KEY_NAME" --keyring "KEY_RING" \
  --project "PROJECT_ID" --location "LOCATION" \
  --purpose "asymmetric-signing" --default-algorithm "ec-sign-p256-sha256" \
  --protection-level "hsm"

使用 OpenSSL 创建自签名证书

使用 Cloud KMS 托管的签名密钥生成自签名证书。您可以使用 OpenSSL 使用 PKCS #11 URI(而非文件路径),并通过其标签标识密钥。在 Cloud KMS PKCS #11 库中,密钥标签是 CryptoKey 名称。

openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \
  DIGEST_FLAG -engine pkcs11 -keyform engine \
  -key PKCS_KEY_TYPE=KEY_IDENTIFIER > PATH_TO_CERTIFICATE

替换以下内容:

  • CERTIFICATE_NAME:证书的名称。
  • DIGEST_FLAG:非对称签名密钥使用的摘要算法。请根据键使用 -sha256-sha384-sha512
  • PKCS_KEY_TYPE:用于标识键的标识符类型。如需使用最新的密钥版本,请将 pkcs11:object 与密钥的名称搭配使用。如需使用特定密钥版本,请将 pkcs11:id 与密钥版本的完整资源 ID 搭配使用。
  • KEY_IDENTIFIER:密钥的标识符。如果您使用的是 pkcs11:object,请使用键的名称,例如 KEY_NAME。如果您使用的是 pkcs11:id,请使用密钥或密钥版本的完整资源 ID,例如 projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION
  • PATH_TO_CERTIFICATE:您要保存证书文件的路径。

如果此命令失败,则 PKCS11_MODULE_PATH 可能设置不正确,或者您可能没有使用 Cloud KMS 签名密钥的适当权限。

您现在应该有一个如下所示的证书:

-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----

设置 Apache 服务器

  1. /etc/apache2 中创建一个目录,以将自签名证书存储在以下位置:

    sudo mkdir /etc/apache2/ssl
    sudo mv ca.cert /etc/apache2/ssl
    
  2. 修改位于 /etc/apache2/sites-available000-default.conf 虚拟主机配置文件,以提供证书文件路径并确保 SSLEngine 处于开启状态。

    以下是侦听端口 443 的示例配置:

      <VirtualHost *:443>
            ServerAdmin webmaster@localhost
            DocumentRoot /var/www/html
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
            SSLEngine on
            SSLCertificateFile /etc/apache2/ssl/ca.cert
            SSLCertificateKeyFile "PKCS_KEY_TYPE=KEY_IDENTIFIER"
      </VirtualHost>
    
  3. 使用您选择的文本编辑器将环境变量添加到 /etc/apache2/envvars 文件,确保 Apache 正确导出环境变量。您可能需要使用 sudo 以 root 身份修改文件。将以下代码行添加到文件末尾:

    export PKCS11_MODULE_PATH="<var>PATH_TO_LIBKMSP11</var>"
    export KMS_PKCS11_CONFIG="<var>PATH_TO_PKCS11_CONFIG</var>"
    export GRPC_ENABLE_FORK_SUPPORT=1
    

    替换以下内容:

    • PATH_TO_LIBKMSP11libkmsp11.so 的路径。
    • PATH_TO_PKCS11_CONFIGpkcs11-config.yaml 的路径。

    gRPC 需要 GRPC_ENABLE_FORK_SUPPORT 才能添加分支支持,并作为 Apache 服务器的一部分正确运行 Cloud KMS PKCS #11 库。

    如果您想使用服务账号密钥进行身份验证,还必须为 GOOGLE_APPLICATION_CREDENTIALS 环境变量导出一个值。

运行服务器

启用 Apache SSL 模块,启用虚拟主机配置,并在 DocumentRoot 文件夹中添加测试网页:

sudo a2enmod ssl
sudo a2ensite 000-default.conf
echo '<!doctype html><html><body><h1>Hello World!</h1></body></html>' | \
  sudo tee /var/www/html/index.html

重启 Apache 服务器并使用 curl 测试配置是否按预期工作。如需忽略自签名证书检查,则需要使用 --insecure 标志。

sudo systemctl restart apache2
curl -v --insecure https://127.0.0.1

如果遇到任何错误,最好先查看 Apache 错误日志,看看发生了什么问题。身份验证问题是导致错误的常见原因。如果您看到 PERMISSION_DENIED 错误,请确保您已完成身份验证,并且凭据文件具有正确的权限。为确保您已完成身份验证,请运行以下命令:

gcloud auth application-default login

如需确认身份验证是否成功,输出应包含 Credentials saved to file: [/path/to/credentials.json] 行。