Manage permissions with access control lists (ACLs) on VMs
Consul service mesh provides secure communication across your services within and across your infrastructure, including on-premises and cloud environments. In a service mesh scenario, you configure the single service instances to listen on the loopback interface and, using the upstreams in the service definition, Envoy sidecar proxies permit communication with other services by adding listeners locally. These communication are protected via an mTLS layer that prevents unauthorized services, inside or outside the mesh, to access them.
Consul provides one extra layer of security, Access Control Lists (ACLs), to prevent malicious actors to register services and hijack communications in your datacenter. A Consul datacenter with ACLs enabled and with default-deny policy, will require a valid token for every operation, including service registration.
In this tutorial you will learn how to create credentials required to join an existing Consul datacenter and register a service to the Consul catalog. After an introductory section about the different tokens available for Consul agents' configuration, you will generate tokens for the Consul node using the node-identiy
template policy, and for a Consul service using the service-identity
policy. You will also learn how to reuse an existing policy to generate a token for the Consul DNS interface, to allow service resolution locally.
You will use the generated credentials to create a service configuration for the API service, and to add a new Consul agent to Consul service mesh. After the agent joins the Consul service mesh, you will verify the service is correctly registered in the mesh using all the interfaces provided by Consul: CLI, API, DNS, and web UI.
Tutorial scenario
This tutorial uses HashiCups, a demo coffee shop application made up of several microservices running on VMs.
At the beginning of the tutorial, you will deploy Consul service mesh, with Envoy sidecar proxies running alongside each service and an API Gateway configured to permit access to the NGINX service.
In addition, you will deploy an extra node that hosts another HashiCups API instance that you want to add to your datacenter.
In this tutorial, you will use ACLs to add the API service to the Consul service mesh.
Once you have registered the service in Consul, it will automatically appear in Consul DNS results and Consul will automatically load balance traffic across the different instances of the service.
Note
All operations in this tutorial, after the scenario deployment, will be performed from an additional node, a bastion host, that will be deployed as part of the scenario. The tutorial provides instructions on how to connect to the bastion host at the end of the deployment.
Prerequisites
This tutorial assumes you are already familiar with Consul service mesh and its core functionalities. If you are new to Consul refer to the Consul Getting Started tutorials collection.
For this tutorial, you will need:
Clone GitHub repository
Clone the GitHub repository containing the configuration files and resources.
Enter the directory that contains the configuration files for this tutorial.
Create infrastructure
With these Terraform configuration files, you are ready to deploy your infrastructure.
Issue the terraform init
command from your working directory to download the
necessary providers and initialize the backend.
Then, deploy the resources. Confirm the run by entering yes
.
Tip
The Terraform deployment could take up to 15 minutes to complete. Feel free to explore the next sections of this tutorial while waiting for the environment to complete initialization.
After the deployment is complete, Terraform returns a list of outputs you can use to interact with the newly created environment.
The Terraform outputs provide useful information, including the bastion host IP address. The following is a brief description of the Terraform outputs:
- The
ip_bastion
provides IP address of the bastion host you use to run the rest of the commands in this tutorial. - The
remote_ops
lists the bastion host IP, which you can use access the bastion host. - The
retry_join
output lists Consul'sretry_join
configuration parameter. The next tutorial uses this information to generate Consul server and client configuration. - The
ui_consul
output lists the Consul UI address. The Consul UI is not currently running. You will use the Consul UI in a later tutorial to verify that Consul started correctly. - The
ui_grafana
output lists the Grafana UI address. You will use this address in a future tutorial. - The
ui_hashicups
output lists the HashiCups UI address. You can open this address in a web browser to verify the HashiCups demo application is running properly.
List AWS instances
The scenario deploys eight virtual machines.
After deployment six virtual machines, consul_server[0]
, database[0]
, frontend[0]
, api[0]
, nginx[0]
, and gateway-api[0]
are configured in a Consul datacenter with service mesh enabled.
The two remaining nodes are:
bastion
- the bastion host that you will use to perform the tutorial steps.api[1]
- a virtual machine to host a second instance of thehashicups-api
service.
Login into the bastion host VM
Login to the bastion host using ssh
.
Configure CLI to interact with Consul
Configure your bastion host to communicate with your Consul environment using the two, dynamically generated, environment variable files.
After loading the needed variables, verify you can connect to your Consul datacenter.
Notice that bastion
and hashicups-api-1
are not part of the datacenter.
Create ACL token for ACL management
A management token is required to manage Consul's ACLs system. We recommend creating a new Consul management token for this purpose instead of using the ACL bootstrap token.
That will produce an output similar to the following.
Set your newly generated management token as the CONSUL_HTTP_TOKEN
environment variable. This will allow you to perform ACL system operations in the next steps using the new token.
Create ACL configuration for Consul agent
Consul provides a fine grained set of permissions to manage your Consul nodes and services. In this section you will create the ACL tokens required to register a new Consul client node in a Consul datacenter. You will then register a service in the Consul service mesh with these ACL tokens.
The initial tutorial environment includes an empty VM named hashicups-api-1
for you. You will create ACLs token to register this Consul client node to the Consul datacenter, and register the service in Consul.
Consul has a section in the configuration to specify all the ACL tokens to be used by the agent.
The different tokens are used for different operation performed by the Consul agent:
agent
- Used for clients and servers to perform internal operations. This token must have write access to the node name it will register as in order to set any of the node-level information in the catalog.default
- Used for the default operations whenagent
token is not provided and for the endpoints that do not permit a token being passed. This will be used for the DNS interface of the Consul agent.config_file_service_registration
- Specifies the ACL token the agent uses to register services and checks. This token needs write permission to register all services and checks defined in this agent's configuration.
You will generate the ACL configuration section after these three tokens are generated.
Generate default
token
Each token must be associated with a policy providing the desired permissions. The scenario already contains a policy used to generate the default token for the other nodes that is already suitable for the node default token. The policy is named acl-policy-dns
.
Read the policy using the consul acl policy
command.
The acl-policy-dns
policy, used to generate the default
token, grants read access to all services and nodes so DNS query can work. It also grants read permissions for prepared queries and agent metrics endpoints.
Generate a new token using the acl-policy-dns
policy.
That will produce an output similar to the following.
Generate agent
token
In order for the agent to set any node-level information in Consul catalog, the agent
token must have write
access to the node name it will register as. One minimal example for such a policy is the following.
You can use node-identity
to help you generate agent
tokens for Consul nodes. Node identities let you to quickly construct policies for nodes, rather than manually creating identical polices for each node. Generate a new token for hashicups-api-1
using node-identity
.
That will produce an output similar to the following.
Generate config_file_service_registration
token
The config_file_service_registration
token needs write permission to register all services and checks defined in this agent's configuration. For Consul service mesh, the token also needs permissions to register the Envoy sidecar proxy for the service as an independent service in Consul catalog. One minimal example for such a policy is the following.
You can use service-identity
to help you generate config_file_service_registration
tokens for Consul nodes. Service identities let you to quickly construct policies for services, rather than manually creating identical polices for each service instance and for their companion sidecar proxy. Generate a new token for hashicups-api-1
using service-identity
.
That will produce an output similar to the following.
Verify you have created the three tokens and the files containing the tokens are present in the assets/
folder.
Generate Consul agent ACL configuration section
With the three tokens you created, generate the Consul agent ACL configuration.
Generate hashicups-api service configuration
Generate hashicups-api
service configuration.
The tutorial shows an example of how to configure a service in Consul service mesh. The same concepts apply to a Consul service discovery. If you are trying to register a new service for service discovery, remove the connect
section in the service configuration file.
Add new service to Consul service mesh with ACLs
In the previous paragraphs, you created agent-acl-tokens.hcl
, containing token configuration for the Consul agent, and svc-hashicups-api.hcl
, containing service configuration for the hashicups-api
service instance. The bastion host already contains the remaining configuration needed to configure Consul on the hashicups-api-1
node. Review the full configuration.
Copy the configuration on the remote node.
Start Consul process
Login to hashicups-api-1
from the bastion host.
Verify the VM contains the files required for Consul configuration.
Start Consul agent.
The command starts the Consul server in the background to not lock the terminal.
You can access the Consul server log through the /tmp/consul-server.log
file.
Start Envoy sidecar proxy
To make the API service instance join Consul service mesh, your node requires an Envoy proxy acting as a sidecar for the service. You need a valid token with the permission to register the sidecar as a service in Consul catalog to start the proxy process.
Use the token created previously using the service-identity
policy.
That will produce an output similar to the following.
Start Envoy sidecar proxy for hashicups-api
service.
The command starts the Envoy sidecar proxy in the background to not lock the
terminal. You can access the Envoy log through the /tmp/sidecar-proxy.log
file.
Start the API service instance
Once the Consul node joined the Consul datacenter and the Envoy sidecar is configured and ready to route traffic to and from your service, start the hashicups-api
service to listen on the local network interface.
The output of the command will show some Docker output while the Docker images that compose the services are being pulled on the node.
To continue with the tutorial, exit the ssh session to return to the bastion host.
Verify service registration
After you registered the service, it will start appearing among the results when Consul catalog is queried.
Tip
To simplify tests all services already present in the Consul service mesh had a tag assigned, inst_0
while the new instance got registered using a different tag, inst_1
.
Verify it using the different interfaces exposed by Consul.
Use the consul catalog
command to query the Consul catalog and show all available services.
The command will produce an output similar to the following.
Notice that the hashicups-api
and hashicups-api-sidecar-proxy
instances present two different tags, inst_0
and inst_1
, that indicate that both instances are registered within Consul.
Destroy the infrastructure
Now that the tutorial is complete, clean up the infrastructure you created.
From the ./self-managed/infrastruture/aws
folder of the repository, use terraform
to destroy the infrastructure.
Next steps
In this tutorial you learned the necessary steps to generate Access Control Lists' tokens to add a new Consul agent to your Consul datacenter and to register a new service to your Consul service mesh.
Specifically you:
- Generated a new management token used the built-in global-management policy.
- Generated a new token from a pre-existing policy
- Generated a new token using the
node-identity
policy - Generated a new token using the
service-identity
policy - Verified the successful node and service registration using all the different interfaces provided by Consul: CLI, API, DNS, and UI
For more information about the topics covered in this tutorial, refer to the following resources:
To learn more about other security features provided by Consul service mesh refer to: