mirror of https://github.com/hashicorp/consul
273 lines
10 KiB
Markdown
273 lines
10 KiB
Markdown
---
|
|
layout: docs
|
|
page_title: Secure Configuration - AWS ECS
|
|
description: >-
|
|
Manual Secure Configuration of the Consul Service Mesh on AWS ECS (Elastic Container Service).
|
|
---
|
|
|
|
# Secure Configuration
|
|
|
|
This topic describes how to enable Consul security features for your production workloads.
|
|
|
|
## Prerequisites
|
|
|
|
The following features must be configured for your Consul server cluster:
|
|
|
|
- [TLS encryption](/docs/security/encryption#rpc-encryption-with-tls) for RPC communication between Consul clients and servers.
|
|
- [Gossip encryption](/docs/security/encryption#gossip-encryption) for encrypting gossip traffic.
|
|
- [Access control lists (ACLs)](/docs/security/acl) for authentication and authorization for Consul clients and services on the mesh.
|
|
|
|
You should already have followed the [manual installation instructions](/docs/ecs/manual/install) to define the necessary components of the task definition for Consul on ECS.
|
|
|
|
You should be familiar with [specifying sensitive data](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html) on ECS.
|
|
|
|
You should be familiar with configuring Consul's secure features, including how to create ACL tokens and policies. Refer to the [ACL system documentation](/docs/security/acl) and [Day 1: Security tutorials](https://learn.hashicorp.com/collections/consul/security) for an introduction and additional information.
|
|
|
|
## ACL Tokens
|
|
|
|
Tokens are artifacts within the ACL system that authenticate users, services, and Consul agents. Tokens are linked to policies that specify the resources the token bearer has access to when making requests in the network.
|
|
|
|
You must create two types of ACL tokens for Consul on ECS:
|
|
|
|
* **Client tokens:** used by the `consul-client` containers to join the Consul cluster
|
|
* **Service tokens:** used by sidecar containers for service registration and health syncing
|
|
|
|
This section describes how to manually create ACL tokens. Alternatively, you can install the ACL controller to ease the burden of creating tokens. The ACL controller can automatically create ACL tokens for Consul on ECS. For additional details, refer to [ACL Controller](/docs/manual/acl-controller).
|
|
|
|
### Define policies
|
|
|
|
Configure the following ACL policy for the Consul client token:
|
|
|
|
```hcl
|
|
node_prefix "" {
|
|
policy = "write"
|
|
}
|
|
service_prefix "" {
|
|
policy = "read"
|
|
}
|
|
```
|
|
|
|
The policy allows `node:write` for any node name, which is necessary because the Consul node names on ECS are not known until runtime.
|
|
|
|
You can add the policy in Consul using the [`consul acl policy create`](/commands/acl/policy/create) command or the [`[PUT] /v1/acl/policy`](/api-docs/acl/policies#create-a-policy) API endpoint.
|
|
|
|
If you intend to create a gateway for connecting multiple Consul datacenters, you will need additional policies to specify the permission scope.
|
|
|
|
#### Mesh gateway policy
|
|
|
|
Mesh gateways must run in the default namespace.
|
|
|
|
```hcl
|
|
namespace "default" { ## If namespaces enabled
|
|
service "<Service Name>" {
|
|
policy = "write"
|
|
}
|
|
}
|
|
namespace_prefix "" { ## If namespaces enabled
|
|
service_prefix "" {
|
|
policy = "read"
|
|
}
|
|
node_prefix "" {
|
|
policy = "read"
|
|
}
|
|
}
|
|
agent_prefix "" {
|
|
policy = "read"
|
|
}
|
|
```
|
|
#### Terminating gateway policy
|
|
|
|
```hcl
|
|
partition "<partition>" { ## If partitions enabled
|
|
namespace "<namespace>" { ## If namespaces enabled
|
|
service "<service Name>" {
|
|
policy = "write"
|
|
}
|
|
node_prefix "" {
|
|
policy = "read"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Ingress gateway policy
|
|
|
|
```hcl
|
|
partition "<partition>" { ## If partitions enabled
|
|
namespace "<namespace>" { ## If namespaces enabled
|
|
service "<Service Name>" {
|
|
policy = "write"
|
|
}
|
|
node_prefix "" {
|
|
policy = "read"
|
|
}
|
|
service_prefix "" {
|
|
policy = "read"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
|
|
### Create service tokens
|
|
|
|
Create the Consul client token and the service tokens after adding the necessary policies. Service tokens should be associated with a service identity. The service identity includes `service:write` permissions for the service and sidecar proxy.
|
|
|
|
You can create tokens using the [`consul acl token create`](/commands/acl/token/create) command or the [`[PUT] /v1/acl/token`](/api-docs/acl/tokens#create-a-token) API endpoint.
|
|
The following example shows how to use the Consul CLI to create a service token for a service named `example-client-app`:
|
|
|
|
```shell-session
|
|
$ consul acl token create -service-identity=example-client-app ...
|
|
```
|
|
You need to create one service token for each registered Consul service in ECS. When you add new services to the service mesh, you must create new tokens for each service.
|
|
|
|
|
|
## Secret storage
|
|
|
|
You should securely store the following secrets in order to make them available to ECS tasks.
|
|
|
|
1. Consul Server CA certificate
|
|
2. Consul gossip encryption key
|
|
3. Consul client ACL token
|
|
4. Consul service ACL tokens (one per service)
|
|
|
|
These secrets can be securely stored and passed to ECS tasks using either of the following AWS secret services:
|
|
|
|
* [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-parameters.html)
|
|
* [AWS Secrets Manager](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data-secrets.html)
|
|
|
|
Once the secrets are stored they can be referenced using their ARN. The following shows
|
|
example secret ARNs when using AWS Secrets Manager:
|
|
|
|
| Secret | Sample Secret ARN |
|
|
| ---------------------- | ---------------------------------------------------------------------------------- |
|
|
| Consul Server CA Cert | `arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-ca-cert` |
|
|
| Gossip encryption key | `arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-gossip-key` |
|
|
| Client token | `arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-client-token` |
|
|
| Service token | `arn:aws:secretsmanager:us-west-2:000000000000:secret:my-example-client-app-token` |
|
|
|
|
## Configure `consul-client`
|
|
|
|
The following secrets must be passed to the `consul-client` container:
|
|
|
|
* Consul server CA certificate
|
|
* Gossip encryption key
|
|
* Consul client ACL token
|
|
|
|
The following example shows how to include these secrets in the task definition. The `secrets`
|
|
list specifies environment variable `name`s that will be set to the secret values for this container.
|
|
ECS automatically fetches the secret values specified in the `valueFrom` fields during task provisioning.
|
|
|
|
```json
|
|
{
|
|
"containerDefinitions": [
|
|
{
|
|
"name": "consul-client"
|
|
"image": "public.ecr.aws/hashicorp/consul:<CONSUL_VERSION>",
|
|
"secrets": [
|
|
{
|
|
"name": "CONSUL_CACERT",
|
|
"valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-ca-cert"
|
|
},
|
|
{
|
|
"name": "CONSUL_GOSSIP_ENCRYPTION_KEY",
|
|
"valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-gossip-key"
|
|
},
|
|
{
|
|
"name": "AGENT_TOKEN",
|
|
"valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-consul-client-token"
|
|
}
|
|
]
|
|
},
|
|
...
|
|
]
|
|
}
|
|
```
|
|
|
|
Next, update Consul configuration options to pass the secrets to the Consul client.
|
|
|
|
The following is an example of the *additional* content to include in the `consul-client` startup script. Refer to the [install
|
|
page](/docs/ecs/manual/install#consul-client-container) for the remainder of the startup script and how to pass this
|
|
script to the container.
|
|
|
|
<CodeBlockConfig highlight="3-4,10-29">
|
|
|
|
```shell
|
|
...
|
|
|
|
# Write the CA Cert to a file
|
|
echo "$CONSUL_CACERT" > /tmp/consul-ca-cert.pem
|
|
|
|
# Write the Consul agent configuration file.
|
|
cat << EOF > /consul/agent-defaults.hcl
|
|
...
|
|
|
|
# Configure gossip encryption key
|
|
encrypt = "$CONSUL_GOSSIP_ENCRYPTION_KEY"
|
|
|
|
# Configure TLS settings
|
|
auto_encrypt = {
|
|
tls = true
|
|
ip_san = ["$ECS_IPV4"]
|
|
}
|
|
tls {
|
|
defaults {
|
|
ca_file = "/tmp/consul-ca-cert.pem"
|
|
verify_outgoing = true
|
|
}
|
|
}
|
|
|
|
# Configure ACLs
|
|
acl {
|
|
enabled = true
|
|
default_policy = "deny"
|
|
down_policy = "async-cache"
|
|
tokens {
|
|
agent = "$AGENT_TOKEN"
|
|
}
|
|
}
|
|
|
|
EOF
|
|
```
|
|
|
|
</CodeBlockConfig>
|
|
|
|
The following table describes the additional fields that must be included in the Consul client configuration file.
|
|
|
|
| Field name | Type | Description |
|
|
| -------------------------------------------------------------------------------| ------- | ------------------------------------------------------------------------------------ |
|
|
| [`encrypt`](/docs/agent/config/cli-flags#_encrypt) | string | Specifies the gossip encryption key |
|
|
| [`tls.defaults.ca_file`](/docs/agent/config/config-files#tls_defaults_ca_file) | string | Specifies the Consul server CA cert for TLS verification. |
|
|
| [`acl.enabled`](/docs/agent/config/config-files#acl_enabled) | boolean | Enable ACLs for this agent. |
|
|
| [`acl.tokens.agent`](/docs/agent/config/config-files#acl_tokens_agent) | string | Specifies the Consul client token which authorizes this agent with Consul servers. |
|
|
|
|
## Configure `consul-ecs-mesh-init` and `consul-ecs-health-sync`
|
|
|
|
Both `consul-ecs-mesh-init` and `consul-ecs-health-sync` containers need to be configured with
|
|
the service ACL token. This allows these containers to make HTTP API requests to the local
|
|
Consul client for service registration and health syncing.
|
|
|
|
The following shows how to set the `CONSUL_HTTP_TOKEN` variable to the service token for the `example-client-app` service,
|
|
if the token is stored in AWS Secrets Manager.
|
|
|
|
<CodeBlockConfig highlight="5-8">
|
|
|
|
```json
|
|
{
|
|
"containerDefinitions": [
|
|
{
|
|
"secrets": [
|
|
{
|
|
"name": "CONSUL_HTTP_TOKEN",
|
|
"valueFrom": "arn:aws:secretsmanager:us-west-2:000000000000:secret:my-example-client-app-token"
|
|
}
|
|
]
|
|
},
|
|
...
|
|
],
|
|
...
|
|
}
|
|
```
|
|
|
|
</CodeBlockConfig>
|