ECS Service Connect でサービス間通信の自動暗号化を試してみた

ECS Service Connect でサービス間通信の自動暗号化を試してみた

昨年、Amazon ECS Service Connect が TLS 証明書を利用したトラフィックの自動暗号化に対応しました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/01/amazon-ecs-service-connect-automatic-traffic-encryption-tls-certificates/

こちらの設定を行うことで、送信時の暗号化が求められる際にアプリケーション側の対応不要で要件を満たすことが可能です。

やってみる

下記手順に従って、実際に試してみます。

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-connect-tls.html

ネットワーク周りや ECS は下記構成で事前に作成しておき、後から ECS Service B の自動 TLS を有効化してみます。

ecs-arch.png

AWS Private Certificate Authority を作成する

まず、AWS Private Certificate Authority(以降 Private CA) を作成します。
Private CA には「汎用」モードと「有効期限の短い証明書」モードが存在します。
どちらのモードも利用できますが、コストを意識して「有効期限の短い証明書」モードを利用します。

Amazon ECS は両方のモードをサポートしていますが、有効期間の短い証明書を使用することをお勧めします。デフォルトでは、証明書は 5 日ごとにローテーションされ、短期モードで実行すると一般的な用途に比べてコストを大幅に節約できます。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/service-connect-tls.html

ecs-tls-1.png

ecs-tls2-1.png

キーアルゴリズムとしては、256-bit ECDSA および 2048-bit RSA 暗号化をサポートしているようなので、今回は 2048-bit RSA 暗号化を選択しておきます。

256-bit ECDSA および 2048-bit RSA 暗号化で AWS Private Certificate Authority TLS 証明書と暗号化をサポートしています。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/service-connect-tls.html

ecs-tls3.png

ECS へ権限を付与する際に AWS マネージドポリシーである AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity を利用するのであれば、AmazonECSManaged = true のタグを付与しておく必要があります。

ecs-tls4.png

上記マネージドポリシーがタグベースの権限設定をしているので、タグを付与しないと ECS サービス更新時に権限エラーとなります。
Private CA 作成後、「CA 証明書をインストール」をクリックします。

ecs-tls5.png

ecs-tls6.png

こちらの作業が終わると、Private CA のステータスがアクティブになります。

ecs-tls7.png

ECS Service Connect 側の設定を行う

続いて、ECS Service Connect 側の設定を行います。
インフラストラクチャロールを選択しつつ、先程作成した Private CA を選択します。

ecs-tls8.png

インフラストラクチャロールの信頼ポリシーは下記のように設定しました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAccessToECSForInfrastructureManagement",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

また、権限としては AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity のみを付与すれば問題ありません。
上記設定を行うことで、新しいデプロイメントが作成されて ECS タスクが再作成されます。
また、利用している名前空間を確認すると、検出名の所に TLSが有効になっています と表示されます。

ecs-tls9.png

TLS が有効になっていることを確認する

さっそく TLS 通信が有効なことを確認したいと思います。
とはいえ、サイドカーとして挿入された Service Connect エージェントが TLS 通信を開始して、宛先のエージェントが TLS 通信を終端します。

Service Connect は、Service Connect エージェントで TLS を開始し、宛先エージェントで TLS を終了します。その結果、アプリケーションコードが TLS のやりとりを認識することはありません。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/verify-tls-enabled.html

そのため、アプリケーションは TLS のことを意識しなくて良いですし、単純に HTTPS 通信を送って試すことはできません。
ECS Exec でコンテナ内に入ってリクエストを送る分には、普通に HTTP 通信を送ることで裏では勝手に暗号化される形となります。

curl -i http://app.masukawa-test-ecs-namespace
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
date: Sat, 15 Feb 2025 05:21:10 GMT
content-length: 26
x-envoy-upstream-service-time: 2
server: envoy

今回はタスクの IP に直接接続して証明書が正しく設定されていることを確認します。
サービスインスタンスの詳細から、タスクの IP とポートが確認できます。

ecs-tls10.png

opesssl コマンドを使うことで、下記のようにタスクに設定されている証明書を確認することができました。

root@ip-10-0-10-91:/app# openssl s_client -connect 10.0.10.242:80 < /dev/null 2> /dev/null | openssl x509 -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ff:50:b0:f2:6c:10:72:ac:3d:8c:b4:28:d0:93:09:4e
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, O = Org, OU = devision, ST = Tokyo, CN = sample, L = Minato-ku
        Validity
            Not Before: Feb 15 03:53:29 2025 GMT
            Not After : Feb 22 04:53:29 2025 GMT
        Subject: L = Minato-ku, CN = sample, ST = Tokyo, OU = devision, O = Org, C = JP
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:c5:67:4b:8e:35:63:3d:ac:29:dd:6d:b8:38:f5:
                    67:8e:04:b8:37:3b:9d:66:22:c1:ec:7d:58:23:7d:
                    37:2b:ad:1f:7a:50:8c:26:1a:ed:cf:b8:0b:e7:f2:
                    85:13:6d:d5:6d:84:cc:04:a4:4e:2a:61:e2:77:e9:
                    6e:02:e1:9f:65
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:app.masukawa-test-ecs-namespace
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Authority Key Identifier:
                28:5E:3E:F6:02:AE:7A:BD:EA:F6:0C:CD:08:EA:A2:D7:09:C9:9A:B1
            X509v3 Subject Key Identifier:
                7D:49:F0:E4:EE:20:99:AC:C9:CD:B1:77:E6:D6:17:12:99:3E:41:27
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        51:ea:e0:85:4f:b6:b0:00:e0:9b:1b:bb:aa:ed:8d:22:42:bc:
        d3:5f:de:6a:84:e3:43:53:6c:03:4c:f8:27:b2:72:97:a5:77:
        13:cb:9f:0a:70:02:b1:0c:b4:f8:ef:27:f1:6e:6b:80:12:41:
        25:24:fd:c7:cb:1e:4c:8f:e6:1c:d2:df:5c:9d:52:69:1f:04:
        72:55:05:6f:9c:01:98:bc:db:a6:65:bc:34:b6:0c:13:c6:68:
        9c:9c:51:7d:a1:df:20:82:40:b4:e6:ec:98:29:79:23:bc:40:
        a3:c4:8f:0e:c5:0f:72:22:7d:4a:dc:0e:1d:5a:71:36:74:9b:
        35:25:93:be:61:95:36:0d:79:f1:69:5b:b8:b0:fc:d6:8a:46:
        9f:06:0b:97:af:75:6e:b8:ac:0e:a8:36:66:2e:f3:f8:9b:06:
        ab:74:df:d5:ff:30:ae:32:bd:c4:64:b7:86:63:de:9c:9f:50:
        ca:b7:f5:32:93:2a:7e:2b:36:c4:09:7b:0f:6a:8c:f8:7f:3f:
        2d:14:b7:f3:ec:58:27:34:32:43:72:48:9a:be:9f:74:56:c5:
        ca:f5:d6:62:a3:72:11:d6:d7:d9:d0:e2:7a:4b:32:b4:5b:84:
        ff:54:f1:46:25:95:6b:ad:81:7e:ff:b4:e6:08:ac:5a:36:26:
        36:92:e5:7a

まとめ

ECS Service Connect を利用した自動 TLS 機能を試してみました。
アプリケーション側の対応不要でサービス間通信を簡単に暗号化できるので、セキュリティ要件次第では積極的に使っていきたいですね。
ちなみに、mTLS は未対応なのでこちらが必須なら他のサービスメッシュを利用する必要があります。

https://github.com/aws/containers-roadmap/issues/2150

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.