ACM for Nitro Enclaves が Apache でも利用出来るようになりました

2022.09.15

いわさです。

AWS Nitro Enclaves を使って Amazon EC2 インスタンスで実行されているウェブサーバーで、ACM 証明書を利用出来るようにする ACM for Nitro Enclaves という機能があります。
これまで Nginx のみサポートされていましたが、今回 Apache でも利用出来るようになりました。

AWS Nitro Enclaves を使ったことがなかったのですが、Apache で ACM を利用するくらいであればチャチャッと試せるかなと思いやってみました。

やってみる

前提となる EC2 での AWS Nitro Enclaves の有効化は以下を参考に構築しています。

ちなみに Nitro Enclaves 自体は Windows インスタンスでも利用出来ますが、ACM for Nitro Enclaves は Linux インスタンスでのみサポートされています。

流れとしては、EC2 のインスタンスプロファイルが以下を許可されている前提で、AWS Nitro Enclaves が有効化されている環境へ AWS Certificate Manager for Nitro Enclaves をインストールし構成します。

  • ec2:AssociateEnclaveCertificateIamRole
  • ec2:GetAssociatedEnclaveCertificateIamRoles
  • ec2:DisassociateEnclaveCertificateIamRole

マネジメントコンソール上での設定は特に変わった点はなくて ACM 証明書の作成と EC2 の作成、セキュリティグループの設定くらいであとはミドルウェアの設定となります。

ACM for Nitro Enclaves が Amazon EC2 インスタンスで実行されている Apache と連携して証明書のインストールや更新を行い、証明書の秘密鍵と証明書は Enclaves 内に分離されたまま安全に保存されるという形です。

事前準備

EC2 は AWS Nitro Enclaves の前提条件を満たすインスタンスタイプを選択し、Nitro Enclaves を有効化します。
この機能は無効化状態で作成したインスタンスでも停止状態であればあとから有効化も出来ます。

EC2 は 前述の許可ポリシーを設定したIAM ロールをアタッチしておきます。
IAM ロールの ARN を後ほどミドルウェアの設定時に使用します。

ACM は普通に発行します。
ACM for Nitro Enclaves ではパブリックもプライベートもサポートされています。今回はパブリック証明書を使いたいと思います。
ACM の ARN を後ほどミドルウェアの設定時に使用します。

パブリック証明書を構成後に外部から HTTPS リクエストを送信して動作確認を行うためにセキュリティグループを開放しました。
また、パブリックサブネットのポートに SSH 経路でアクセスして ACM for Nitro Enclaves のセットアップやらをしているので SSH のポートも開放していますが、フルオープンになってしまっていることに気がつきました。これは雑でまずかったですね、真似しないでください...

ACM for Nitro Enclaves と Apache のセットアップ

手順は以下を参考に進めています。
今回は Apache で構成していますが、Nginx の手順もこちらに記載されていました。

yum で Nitro CLI、Apache、ACM for Nitro Enclaves をインストールしていきます。

[ec2-user@ip-172-31-36-113 ~]$ nitro-cli --version
Nitro CLI 1.2.0

:

[ec2-user@ip-172-31-36-113 ~]$ sudo yum -y install httpd mod_ssl
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.54-1.amzn2 will be installed
--> Processing Dependency: httpd-tools = 2.4.54-1.amzn2 for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: httpd-filesystem = 2.4.54-1.amzn2 for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: system-logos-httpd for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: mod_http2 for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: httpd-filesystem for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.54-1.amzn2.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.54-1.amzn2.x86_64
---> Package mod_ssl.x86_64 1:2.4.54-1.amzn2 will be installed
--> Processing Dependency: sscg >= 2.2.0 for package: 1:mod_ssl-2.4.54-1.amzn2.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.7.0-9.amzn2 will be installed
---> Package apr-util.x86_64 0:1.6.1-5.amzn2.0.2 will be installed
--> Processing Dependency: apr-util-bdb(x86-64) = 1.6.1-5.amzn2.0.2 for package: apr-util-1.6.1-5.amzn2.0.2.x86_64
---> Package generic-logos-httpd.noarch 0:18.0.0-4.amzn2 will be installed
---> Package httpd-filesystem.noarch 0:2.4.54-1.amzn2 will be installed
---> Package httpd-tools.x86_64 0:2.4.54-1.amzn2 will be installed

:

[ec2-user@ip-172-31-36-113 ~]$ sudo yum install aws-nitro-enclaves-acm -y
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package aws-nitro-enclaves-acm.x86_64 0:1.2.0-1.amzn2 will be installed
--> Processing Dependency: openssl-pkcs11 for package: aws-nitro-enclaves-acm-1.2.0-1.amzn2.x86_64
--> Running transaction check
---> Package openssl-pkcs11.x86_64 0:0.4.10-3.amzn2.0.1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

:

Dependency Installed:
  openssl-pkcs11.x86_64 0:0.4.10-3.amzn2.0.1                                                                                                                                                            

Complete!

AWS CLI のec2 associate-enclave-certificate-iam-roleコマンドを使って IAM ロールと ACM 証明書の関連付けを行います。

% aws ec2 associate-enclave-certificate-iam-role --certificate-arn arn:aws:acm:ap-northeast-1:123456789012:certificate/0463825a-0650-4c93-837c-723bc4f8d62f --role-arn arn:aws:iam::123456789012:role/hoge0915ec2 --profile hoge
{
    "CertificateS3BucketName": "aws-ec2-enclave-certificate-ap-northeast-1-prod",
    "CertificateS3ObjectKey": "arn:aws:iam::123456789012:role/hoge0915ec2/arn:aws:acm:ap-northeast-1:123456789012:certificate/0463825a-0650-4c93-837c-723bc4f8d62f",
    "EncryptionKmsKeyId": "dc261490-9211-4476-a870-a63fbab8988d"
}

ACM for Nitro Enclaves のサンプル構成ファイルが/etc/nitro_enclaves/acm-httpd.example.yamlにあるので/etc/nitro_enclaves/acm.yamlにコピーして編集を行います。
以下ハイライト部分に ACM の ARN を設定しています。

/etc/nitro_enclaves/acm.yaml

# Copyright 2020-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
---
# ACM for Nitro Enclaves Apache HTTPD configuration
#
# This is an example of setting up ACM, with Nitro Enclaves and Apache Httpd.
# You can take this file and then:
# - Copy it to /etc/nitro_enclaves/acm.yaml
# - Fill in your ACM certificate ARN in the `certificate_arn` field below
# - Make sure `/etc/httpd/conf/httpd.conf` is set up to have the `IncludeOptional`
#   or `Include` directives to point to the virtual host configuration entries
# - Set the target `Conf` directive below to point to a virtual host
#   configuration location
# - Start the nitro-enclaves-acm service
#
# Enclave general configuration
enclave:
  # Number of vCPUs to be assigned to the enclave
  cpu_count: 2
  # Memory (in MiB) to be assigned to the enclave
  memory_mib: 256

# General options
options:
  # Service to manage
  service: "httpd"
  # If HTTPD is not running, force restart it
  force_start: true
  # The HTTPD reload timeout period (milliseconds)
  reload_wait_ms: 0
  # Certificate renewal check period (seconds)
  sync_interval_secs: 600

# Tokens general configuration
tokens:
  # A label for this PKCS#11 token
  - label: httpd-acm-token
    # Configure a managed token, sourced from an ACM certificate.
    source:
      Acm:
        # The certificate ARN
        # Note: this certificate must have been associated with the
        #       IAM role assigned to the instance on which ACM for
        #       Nitro Enclaves is run.
        certificate_arn: "arn:aws:acm:ap-northeast-1:123456789012:certificate/0463825a-0650-4c93-837c-723bc4f8d62f"
    target:
      Conf:
        # Path to the server configuration file to be written by
        # the ACM service whenever the certificate configuration changes
        # (e.g. after a certificate renewal). The SSLCertificateKeyFile and
        # optionally the SSLCertificateFile directives shall be populated.
        path: /etc/httpd/conf.d/httpd-acm.conf
        # Configuration file owner (i.e. the user httpd is configured to run as).
        user: apache
    # Attestation period (seconds)
    refresh_interval_secs: 43200

# - label: httpd-acm-token-2
#   # Configure a managed token, sourced from an ACM certificate.
#   source:
#     Acm:
#       # The certificate ARN
#       # Note: this certificate must have been associated with the
#       #       IAM role assigned to the instance on which ACM for
#       #       Nitro Enclaves is run.
#       certificate_arn: ""
#   target:
#     Conf:
#       # Path to the server configuration file to be written by
#       # the ACM service whenever the certificate configuration changes
#       # (e.g. after a certificate renewal). The SSLCertificateKeyFile and
#       # optionally the SSLCertificateFile directives shall be populated.
#       path: /etc/httpd/confi.d/httpd-acm-2.conf
#       # Configuration file owner (i.e. the user httpd is configured to run as).
#       user: apache
#   # Attestation repeat period (seconds)
#   refresh_interval_secs: 43200

/etc/httpd/conf.d/ssl.confから/etc/httpd/conf.d/httpd-acm.confへコピーし以下を追加します。

/etc/httpd/conf.d/httpd-acm.conf

:
<VirtualHost *:443>
ServerName hoge.tak1wa.com
SSLEngine on
SSLProtocol -all +TLSv1.2
SSLCertificateKeyFile "/etc/pki/tls/private/localhost.key"
SSLCertificateFile "/etc/pki/tls/certs/localhost.crt"
</VirtualHost>
:

上記設定を行ったのちに以下のコマンドを実施します。

sudo systemctl start nitro-enclaves-acm.service

ここまでで設定は完了です。
適当な index.html などを Apache ドキュメントルートに配置し動作を確認してみます。

% curl -v https://hoge.tak1wa.com/
*   Trying 18.182.6.202:443...
* Connected to hoge.tak1wa.com (18.182.6.202) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=hoge.tak1wa.com
*  start date: Sep 14 00:00:00 2022 GMT
*  expire date: Oct 13 23:59:59 2023 GMT
*  subjectAltName: host "hoge.tak1wa.com" matched cert's "hoge.tak1wa.com"
*  issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: hoge.tak1wa.com
> User-Agent: curl/7.79.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 14 Sep 2022 22:53:29 GMT
< Server: Apache/2.4.54 () OpenSSL/1.0.2k-fips
< Upgrade: h2,h2c
< Connection: Upgrade
< Last-Modified: Wed, 14 Sep 2022 21:55:30 GMT
< ETag: "5-5e8aa2ff6b44a"
< Accept-Ranges: bytes
< Content-Length: 5
< Content-Type: text/html; charset=UTF-8
< 
hoge
* Connection #0 to host hoge.tak1wa.com left intact

良さそうですかね。

さいごに

本日は ACM for Nitro Enclaves が Apache でも利用出来るようになっていたので Apache で試してみました。

料金については通常の ACM を利用する際と変わらず無料で利用可能です。
Apahce 環境でサポートされていないために利用を見送っていた方は改めてご検討ください。