ECS Service Connect でサービス間通信の自動暗号化を試してみた
昨年、Amazon ECS Service Connect が TLS 証明書を利用したトラフィックの自動暗号化に対応しました。
こちらの設定を行うことで、送信時の暗号化が求められる際にアプリケーション側の対応不要で要件を満たすことが可能です。
やってみる
下記手順に従って、実際に試してみます。
ネットワーク周りや ECS は下記構成で事前に作成しておき、後から ECS Service B の自動 TLS を有効化してみます。
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
キーアルゴリズムとしては、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 へ権限を付与する際に AWS マネージドポリシーである AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity を利用するのであれば、AmazonECSManaged
= true
のタグを付与しておく必要があります。
上記マネージドポリシーがタグベースの権限設定をしているので、タグを付与しないと ECS サービス更新時に権限エラーとなります。
Private CA 作成後、「CA 証明書をインストール」をクリックします。
こちらの作業が終わると、Private CA のステータスがアクティブになります。
ECS Service Connect 側の設定を行う
続いて、ECS Service Connect 側の設定を行います。
インフラストラクチャロールを選択しつつ、先程作成した Private CA を選択します。
インフラストラクチャロールの信頼ポリシーは下記のように設定しました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAccessToECSForInfrastructureManagement",
"Effect": "Allow",
"Principal": {
"Service": "ecs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
また、権限としては AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity のみを付与すれば問題ありません。
上記設定を行うことで、新しいデプロイメントが作成されて ECS タスクが再作成されます。
また、利用している名前空間を確認すると、検出名の所に TLSが有効になっています
と表示されます。
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 とポートが確認できます。
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 は未対応なのでこちらが必須なら他のサービスメッシュを利用する必要があります。