1
0

【AWS CDK】CDKを用いたALB mTLS認証の実装

Last updated at Posted at 2024-03-07

はじめに

re:invent2023でALBがmTLS認証をサポートすることが発表されました。
Application Load Balancer での TLS を使用した相互認証

ALBのmTLS認証を実装し、mTLS認証のログを出力する場合は、以下3点を実装する必要があります。

  • CA証明書をトラストストアにあげる
  • ALB Listenerの設定
  • Connections Logsの有効化
    ※Connections Logsの有効化は必須ではありません

今回は、CDKを用いたALBのmTLS認証の実装を上記3つのポイントに分けてご紹介させて頂きます。
※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。

CA証明書をトラストストアにあげる

ALBのListenerでmTLS認証を有効化するために、検証先としてトラストストアを指定します。
そのために、CA証明書が格納されたトラストストアを作成する必要があります。
このトラストストアを作成するために以下3ステップ踏む必要があります。

  • CA証明書格納用のS3バケットの作成
  • 作成したCA証明書格納用のS3バケットにCA証明書を格納
  • CA証明書格納用のS3バケットをCA証明書のソースとしたトラストストアを作成

それぞれのパーツでサンプルと共にご紹介します。

CA証明書格納用のS3バケットの作成

これは普通にS3バケットを作成すれば大丈夫です。

mtls-sample.ts
    const myCertBucket = new s3.Bucket(this, "certBucket", {
      bucketName: `cert-bucket-hogehoge`,
      enforceSSL: true,
      autoDeleteObjects: true,
      encryption: s3.BucketEncryption.S3_MANAGED,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

CA証明書格納用のS3バケットをCA証明書のソースとしたトラストストアを作成

S3にCA証明書を上げるのには、BucketDeployment Constructsを使用します。
このConstructsを利用するとCDK実行環境にあるファイルをDeployプロセスの中でアップロードしてくれます。

mtls-sample.ts
    const caCertupload = new s3deploy.BucketDeployment(this, "caCertupload", {
      sources:[ 
        s3deploy.Source.data(
          "CA_cert.pem",
          fs.readFileSync(path.join(__dirname, "../../ssl/CA_cert.pem"), "utf8")
          ),
          ],
          destinationBucket: myCertBucket,
    });

sourcesのところでS3にアップロードするファイルを指定しています。
s3deploy.Source.data()の第一引数でS3に配置する際のObject名を指定しています。
第二引数では、アップロードしたいファイルのローカル格納先を指定しています。
ここでは、Node.jsのfsとpathモジュールを活用しています。

path.join(__dirname, "../../ssl/CA_cert.pem")
__dirnameはこのコードが配置されているディレクトリパスとなります。ここからの相対パスとして、 ../../ssl/CA_cert.pemを結合し、最終的なファイルパスを生成しています。

fs.readFileSync(path, "utf8")
ファイルをutf8形式でテキストとして読み込んでいます。

CA証明書のソースをCA証明書格納用のS3バケットとしてトラストストアを作成

トラストストアは現在L1のみ提供されているため、L1 Constructsを利用します。
CDK Constructsに関して

mtls-sample.ts
    const trustStore = new elb.CfnTrustStore(this, "cATrustStore",{
      caCertificatesBundleS3Bucket: caCert.deployedBucket.bucketName,
      caCertificatesBundleS3Key: "cA_cert.pem",
      name :"CA-trust-store"
    });

CA証明書の格納されているS3をソースバケットとして、アップロードした際のobject名をkeyとして指定します。

以上で、「CA証明書をトラストストアにあげる」部分は完了です。

ALB Listenerの設定

mTLS認証の有効化は、Listener毎に行います。
そのうえで、現在mTLS認証の設定は、L1 Constructsのみの提供となります。
そのため、L2で作成したListenerをエスケープハッチで追加設定をしてきます。

設定には、以下2ステップを踏む必要があります。

  • ALB Listenerの作成
  • 作成したListenerにエスケープハッチで追加設定

それぞれのパーツでサンプルと共にご紹介します。

ALB Listenerの作成

これは普通にListenerを作成すれば大丈夫です。
今回のサンプルでは、前段にALBを構成していたため、addListener Methodを利用しています。

mtls-sample.ts
    const sListener = alb.addListener("HttpsListener",{
      port: 443,
      protocol: elb.ApplicationProtocol.HTTPS,
      certificates: [acmCert],
      sslPolicy: cdk.aws_elasticloadbalancingv2.SslPolicy.RECOMMENDED_TLS,
      defaultTargetGroups: [fargateTG],
    });

作成したListenerにエスケープハッチで追加設定

L2の「ApplicationListener」では現状mTLSに関連する設定はありません。
そのため、作成したListenerからL1 Constructsを取り出し(エスケープハッチ)、追加設定する必要があります。

mtls-sample.ts
    const cfnSListener = sListener.node.defaultChild as elb.CfnListener;
    cfnSListener.mutualAuthentication = {
      ignoreClientCertificateExpiry: true,
      mode: "verify",
      trustStoreArn: trustStore.ref,
    };

const cfnSLister = sListener.node.defaultChild as elb.CfnListener;
ListenerのdefaultchildをCfnListenerとして、取り出します。
これでL1 ConstructsのCfnListenerを活用出来ます。

cfnSLister.mutualAuthentication
CfnListenerのmutualAuthenticationを設定し、mTLS認証を実装します。
トラストストアは、L1 Constructsで作っているため、trustStoreArnはClouFormationのRef関数経由で設定します。

以上で、「ALB Listenerの設定」部分は完了です。

Connections Logsの有効化

必須ではありませんが、クライアント認証ログは欲しいですよね。
そのためのログが、Connections Logsです。
Connection LogsはALBの属性を編集することにより、実装されます。
ログの配信先も必要なので、以下2ステップを踏む必要があります。

  • Conndection Logs配信先バケットの作成
  • ALB属性の追加

それぞれのパーツでサンプルと共にご紹介します。

Conndection Logs配信先バケットの作成

これは普通にS3バケットを作成すれば大丈夫です。

mtls-sample.ts
    const albConnectionLogBucket = new s3.Bucket(this, "albConnectionLogBucket", {
      bucketName: `alb-connectionlog-bucket-hogehoge`,
      enforceSSL: true,
      autoDeleteObjects: true,
      encryption: s3.BucketEncryption.S3_MANAGED,
      objectLockEnabled: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

ALB属性の追加

追加する必要のある属性は以下3種類です。

Key Value
connection_logs.s3.enabled true
connection_logs.s3.bucket Conndection Logs配信先バケット名
connection_logs.s3.prefix prefix
mtls-sample.ts
    interface connnectionLogSet {
    Key: string,
    Value: string
    };
    const connnectionLogSets:connnectionLogSet[] = [
      {Key: "connection_logs.s3.enabled", Value: "true"},
      {Key: "connection_logs.s3.bucket", Value: albConnectionLogBucket.bucketName},
      {Key: "connection_logs.s3.prefix", Value: "hoge"}
      ];
      
    connnectionLogSets.forEach((param) => {
      alb.setAttribute(param.Key, param.Value)
    });

ALBの属性追加は、ALBのsetAttribute Methodを利用しています。

以上で、「Connections Logsの有効化」部分は完了です。

まとめ

ALBのmTLS認証はリリースされてから日が浅いこともあり、CDKでの実装はちょっとめんどくさいです。
トラストストア作成したり、L1 CfnListenerを使う必要があったり、ALBの属性いじったり。。。
Constructsなり、Methodなり早めにリリースされることを祈ります。

直近で、ALBのmTLS認証の実装をご検討の方は参考にして頂けると幸いです。
※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは全く関係ありません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0