From 8009b89934b6ec8ba69a550aad18e72dbf2a3876 Mon Sep 17 00:00:00 2001 From: Brian Celenza Date: Fri, 17 Jan 2020 09:54:35 -0800 Subject: [PATCH] Add client policy to ACM TLS example (#249) https://github.com/aws/aws-app-mesh-roadmap/issues/39 https://github.com/aws/aws-app-mesh-roadmap/issues/38 --- walkthroughs/tls-with-acm/README.md | 87 ++++++++++++++++++- .../infrastructure/ecs-cluster.yaml | 9 ++ .../tls-with-acm/mesh/colorgateway-vn.json | 19 +++- walkthroughs/tls-with-acm/mesh/mesh.sh | 1 + 4 files changed, 111 insertions(+), 5 deletions(-) diff --git a/walkthroughs/tls-with-acm/README.md b/walkthroughs/tls-with-acm/README.md index 60505752..46fa0c11 100644 --- a/walkthroughs/tls-with-acm/README.md +++ b/walkthroughs/tls-with-acm/README.md @@ -140,7 +140,9 @@ With managed certificates, ACM will automatically renew certificates that are ne ## Step 4: Create a Mesh with TLS enabled -This mesh will be a simplified version of the original Color App Example, so we'll only be deploying the gateway and one color teller service (white). We'll be encrypting traffic from the gateway to the color teller node. As such, our color teller white Virtual Node spec looks like this: +This mesh will be a simplified version of the original Color App Example, so we'll only be deploying the gateway and one color teller service (white). + +We'll be encrypting traffic from the gateway to the color teller node. Our color teller white Virtual Node will be terminating TLS with a certificate provided by ACM. The spec looks like this: ```json "listeners": [ @@ -174,6 +176,44 @@ This mesh will be a simplified version of the original Color App Example, so we' } ``` +Additionally, the gateway service will be configured to validate the certificate of the color teller node by specifying the CA that issued it. The spec for the gateway looks like this: + +```json +"listeners": [ + { + "portMapping": { + "port": 9080, + "protocol": "http" + } + } +], +"serviceDiscovery": { + "dns": { + "hostname": "colorgateway.${SERVICES_DOMAIN}" + } +}, +"backends": [ + { + "virtualService": { + "virtualServiceName": "colorteller.${SERVICE_DOMAIN}", + "clientPolicy": { + "tls": { + "validation": { + "trust": { + "acm": { + "certificateAuthorityArns": [ + "$ROOT_CA_ARN" + ] + } + } + } + } + } + } + } +] +``` + For more information on what TLS settings you can provide for a Virtual Node, see the [TLS Encryption](https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual-node-tls.html) documentation. Let's create the mesh. @@ -249,7 +289,7 @@ aws acm-pca delete-certificate-authority --certificate-authority-arn $ROOT_CA_AR ### 1. What permissions does the IAM role used by the Envoy need in order to retrieve a certificate and private key from ACM? -The IAM role used by the Envoy needs the ability to connect to App Mesh (`appmesh:StreamAggregatedResources`) and export certificates from ACM (`acm:ExportCertificate`). An example policy (as a CloudFormation role) is provided below and is available in `./infrastructure/ecs-cluster.yaml`: +The IAM role used by the Envoy needs the ability to connect to App Mesh (`appmesh:StreamAggregatedResources`) and export certificates from ACM (`acm:ExportCertificate`). An example policy is provided below and is available in `./infrastructure/ecs-cluster.yaml`: ```yaml TaskIamRole: @@ -288,6 +328,45 @@ In a production setting, you should set more specific policies to scope down wha Yes, App Mesh will export your certificate using the `ExportCerticate` API. See [AWS Certificate Manager Pricing](https://aws.amazon.com/certificate-manager/pricing/) for information on the cost associated with exporting a certificate. -### 3. How can I specify explicit TLS validation context on the client virtual node? +### 3. What permissions does the IAM role used by the Envoy need in order to retrieve a certificate authority certificate? + +When using an ACM Private Certificate Authority in a client policy for a Virtual Node's backend, the IAM role used by the Envoy needs the ability to connect to App Mesh (`appmesh:StreamAggregatedResources`) and retrieve certificate authority certificates from ACM (`acm-pca:GetCertificateAuthorityCertificate`). An example policy is provided below and is available in `./infrastructure/ecs-cluster.yaml`: + +```yaml +TaskIamRole: + Type: AWS::IAM::Role + Properties: + Path: / + AssumeRolePolicyDocument: | + { + "Statement": [{ + "Effect": "Allow", + "Principal": { "Service": [ "ecs-tasks.amazonaws.com" ]}, + "Action": [ "sts:AssumeRole" ] + }] + } + Policies: + - PolicyName: ACMCertificateAuthorityAccess + PolicyDocument: | + { + "Statement": [{ + "Effect": "Allow", + "Action": ["acm-pca:GetCertificateAuthorityCertificate"], + "Resource": ["*"] + }] + } + ManagedPolicyArns: + - arn:aws:iam::aws:policy/CloudWatchFullAccess + - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess + - arn:aws:iam::aws:policy/AWSAppMeshPreviewEnvoyAccess +``` + +The policy above uses the App Mesh managed policy `AppMeshPreviewEnvoyAccess` which provides permissions for the action `appmesh:StreamAggregatedResources` for all Virtual Nodes in the mesh. + +In a production setting, you should set more specific policies to scope down what Virtual Nodes and Certificate Authorities an Envoy has access to. + +### 4. What happens if I don't specify a client policy to enforce TLS, but the backend has TLS enabled? + +To preserve connectivity and provide for a smooth migration to TLS between services, App Mesh automatically distributes the certificate chain required to validate a TLS connection to all clients of a Virtual Node with TLS enabled when a client policy is not provided. This allows the backend to enable TLS termination, and ensures that the certificate offered by the backend is what was intended by the service owner. This is not meant to serve as sufficient configuration to support trust between services. When a client policy is provided, the default behavior is overridden with the specifications of the policy. -By default, App Mesh automatically distributes the certificate chain required to validate a TLS connection to all clients of a Virtual Node with TLS enabled. In a zero-trust environment, you may wish to explicitly set the certificate validation chain for a given Virtual Node's backends. This capability is coming soon. Follow [this GitHub issue](https://github.com/aws/aws-app-mesh-roadmap/issues/38) for status updates. +We recommend you specify client policies for backends when TLS is required between services so you can ensure the TLS certificate presented during TLS negotiation is from a certificate authority you trust. diff --git a/walkthroughs/tls-with-acm/infrastructure/ecs-cluster.yaml b/walkthroughs/tls-with-acm/infrastructure/ecs-cluster.yaml index 3df5333b..c292221f 100644 --- a/walkthroughs/tls-with-acm/infrastructure/ecs-cluster.yaml +++ b/walkthroughs/tls-with-acm/infrastructure/ecs-cluster.yaml @@ -81,6 +81,15 @@ Resources: "Resource": ["*"] }] } + - PolicyName: ACMCertificateAuthorityAccess + PolicyDocument: | + { + "Statement": [{ + "Effect": "Allow", + "Action": ["acm-pca:GetCertificateAuthorityCertificate"], + "Resource": ["*"] + }] + } ManagedPolicyArns: - arn:aws:iam::aws:policy/CloudWatchFullAccess - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess diff --git a/walkthroughs/tls-with-acm/mesh/colorgateway-vn.json b/walkthroughs/tls-with-acm/mesh/colorgateway-vn.json index 5a506a64..1e8fa771 100644 --- a/walkthroughs/tls-with-acm/mesh/colorgateway-vn.json +++ b/walkthroughs/tls-with-acm/mesh/colorgateway-vn.json @@ -14,7 +14,24 @@ } }, "backends": [ - {"virtualService": {"virtualServiceName": $COLOR_TELLER_VS }} + { + "virtualService": { + "virtualServiceName": $COLOR_TELLER_VS, + "clientPolicy": { + "tls": { + "validation": { + "trust": { + "acm": { + "certificateAuthorityArns": [ + $ROOT_CA_ARN + ] + } + } + } + } + } + } + } ] } } \ No newline at end of file diff --git a/walkthroughs/tls-with-acm/mesh/mesh.sh b/walkthroughs/tls-with-acm/mesh/mesh.sh index 6fe8d15d..d82a03f7 100755 --- a/walkthroughs/tls-with-acm/mesh/mesh.sh +++ b/walkthroughs/tls-with-acm/mesh/mesh.sh @@ -50,6 +50,7 @@ create_vnode() { vnode_name=$2 dns_hostname="$3.${SERVICES_DOMAIN}" cli_input=$( jq -n \ + --arg ROOT_CA_ARN "${ROOT_CA_ARN}" \ --arg CERTIFICATE_ARN "${CERTIFICATE_ARN}" \ --arg DNS_HOSTNAME "$3.${SERVICES_DOMAIN}" \ --arg COLOR_TELLER_VS "colorteller.${SERVICES_DOMAIN}" \