[アップデート] Amazon CloudFront がオリジン間の相互 TLS をサポートしました

[アップデート] Amazon CloudFront がオリジン間の相互 TLS をサポートしました

2026.02.03

はじめに

これまで、CloudFront からオリジンへの通信を保護する方法としては、以下のような手段が一般的でした。

  • カスタムヘッダーによるオリジンアクセス制限
  • AWS WAF による IP 制限
  • OAC (Origin Access Control) による S3 アクセス制限

これまでの手法は『CloudFront からのリクエストであること』を間接的に検証する方式でしたが、新たに CloudFront でオリジン間の相互 TLS がサポートされ、TLS ハンドシェイクレベルでの相互認証が可能になりました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/01/amazon-cloudfront-mutual-tls-for-origins/

やってみた

ということで試してみます。構成図としては以下のようになります。

alt text

今回は、カスタムドメインで相互 TLS 認証を有効にした API Gateway をオリジンとして試してみました。

証明書の作成

証明書を準備するため、まずルート CA を作成します。

# ルート CA の秘密鍵を生成
openssl genrsa -out RootCA.key 4096

# ルート CA の証明書を生成 (有効期間: 10 年)
openssl req -new -x509 -days 3650 -key RootCA.key -out RootCA.pem -subj "/C=JP/ST=Tokyo/O=MyOrg/CN=MyRootCA"

続いて、クライアント証明書を作成します。CSR 作成時に EKU 拡張領域の設定を忘れないようにしましょう。

# クライアントの秘密鍵を生成
openssl genrsa -out my-client.key 2048

# CSR を生成
openssl req -new -key my-client.key -out my-client.csr \
    -subj "/C=JP/ST=Tokyo/O=MyOrg/CN=my-client" \
    -addext "basicConstraints = CA:FALSE" \
    -addext "keyUsage = digitalSignature" \
    -addext "extendedKeyUsage = clientAuth"

# ルート CA で署名 (有効期間: 1 年)
openssl x509 -req -days 365 \
    -in my-client.csr \
    -CA RootCA.pem \
    -CAkey RootCA.key \
    -CAcreateserial \
    -copy_extensions copyall \
    -out my-client.pem

トラストストアの準備と S3 へのアップロード

API Gateway の mTLS では、信頼する CA 証明書をまとめたトラストストアを S3 に配置する必要があります。今回は中間証明書などはないので、ルート CA 証明書をトラストストアにしてアップロードします。

# ルート CA 証明書をトラストストアとしてコピー
cp RootCA.pem truststore.pem

# S3 にアップロード
aws s3 cp truststore.pem s3://<your-bucket-name>/truststore.pem

ACM へのクライアント証明書インポート

CloudFront がオリジンに提示するクライアント証明書を ACM に登録します。リージョンは、CloudFront と同じ us-east-1 にしましょう。

aws acm import-certificate \
    --certificate fileb://my-client.pem \
    --private-key fileb://my-client.key \
    --certificate-chain fileb://RootCA.pem \
    --region us-east-1 \
    --query 'CertificateArn' \
    --output text

API Gateway の mTLS 設定

ここでは今回の本筋ではないのでスキップしますが、以下のような設定にしておきました。ターゲットはサンプル API (PetStore) にしています。

alt text

補足として、API Gateway のデフォルトエンドポイントの無効化についても、合わせて設定しておくと良さそうですね。

CloudFront の設定

では、CloudFront ディストリビューションのオリジン設定で mTLS を有効にしていきましょう。

alt text

オリジンタイプにはカスタムオリジン (Other) を選択し、オリジン設定から mTLS を有効にします。

alt text

クライアント証明書のフォームをクリックすると、ACM にインポートした証明書が選べるようになります。

動作確認

CloudFront 経由でアクセスし、オリジンへの mTLS 接続が成功することを確認しましょう。

$ curl https://XXXXXXXXXXXXX.cloudfront.net/pets
[
  {
    "id": 1,
    "type": "dog",
    "price": 249.99
  },
  {
    "id": 2,
    "type": "cat",
    "price": 124.99
  },
  {
    "id": 3,
    "type": "fish",
    "price": 0.99
  }
]

クライアント証明書を指定せずに API Gateway のカスタムドメインに直接アクセスすると、

$ curl -v --http1.1 https://<カスタムドメイン>/pets
* Host <カスタムドメイン>:443 was resolved.
* IPv6: (none)
* IPv4: xxx.xxx.xxx.xxx
*   Trying xxx.xxx.xxx.xxx:443...
* Connected to <カスタムドメイン> (xxx.xxx.xxx.xxx) port 443
* ALPN: curl offers http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Request CERT (13):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Certificate (11):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted http/1.1
* Server certificate:
*  subject: CN=<カスタムドメイン>
*  start date: Oct 10 00:00:00 2025 GMT
*  expire date: Nov  8 23:59:59 2026 GMT
*  subjectAltName: host "<カスタムドメイン>" matched cert's "<カスタムドメイン>"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M04
*  SSL certificate verify ok.
* using HTTP/1.x
> GET /pets HTTP/1.1
> Host: <カスタムドメイン>
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
* Empty reply from server
* Closing connection
curl: (52) Empty reply from server

というように、何も返ってきません。想定通りですね。

注意点

CloudFront は TLS ハンドシェイク時にクライアント証明書を提示しますが、その証明書の有効性検証(署名検証、失効確認など)はオリジン側で実装する必要があります。
API Gateway の mTLS 機能はこの検証を自動で行いますが、他のオリジンタイプを使用する場合はこの点に注意しましょう。

おわりに

CloudFront の mTLS 機能により、CloudFront とオリジン間の通信を TLS ハンドシェイクレベルで相互認証できるようになりました。

これまでカスタムヘッダーや IP 制限に頼っていたオリジン保護に、証明書ベースの認証という選択肢が加わったことで、ハイブリッド / マルチクラウド環境でのセキュリティ要件に、よりスマートに対応できるようになったかなと思います。

構成や要件に応じて従来の方式と使い分けていきましょう。

この記事をシェアする

FacebookHatena blogX

関連記事