HashiCorp Boundary - Make Sure Your Human To Machine Access Is Secure
Are the days of VPNs numbered? Explore this new product by HashiCorp. It's an exciting new way to secure human to machine access.
In this post, we discuss and demo secure sessions management for human to machine access using HashiCorp Boundary. HashiCorp Boundary is one of two recent products announced at the latest HashiConf Digital in October 2020. The other product is HashiCorp Waypoint which we demo in this separate blog post.
Below is a video explanation and demo.
You can skip to the relevant chapters below:
- 00:00 Introduction
- 02:18 Traditional Human to Machine Access Workflow
- 05:00 Boundary's Workflow
- 07:55 Boundary's Structure
- 09:48 Architecture of a Production Deployment
- 13:03 Demo Diagram
- 14:36 References
- 15:18 Roadmap
- 16:48 Demo Starts Start Boundary in Dev Mode
- 19:23 Run Terraform to Configure Boundary
- 23:00 SSH Connect to Linux Server
- 29:20 SSH Connection and Wireshark
- 33:03 RDP Connect to Windows Server
- 34:27 RDP Connection and Wireshark
- 35:39 Conclusion
The following is required to follow along:
Traditional Workflow for Human to Machine Access
Let's take a look at the traditional workflow for secure access to machines. If you are an operator using your computer from home and you want to access your corporate network for example or a data center; below is your workflow:
- You probably have a VPN that you need to use to connect
- From there you typically land on an SSH bastion host or a jump box
- Then from the jump box, you SSH through a firewall
- Finally, you get to the machine you want to access. This target machine could be anything. It could be a Linux server or a Windows server or a network device such as a switch or a router.
Traditional Workflow for Human to Machine Access
Traditional Workflow Challenges
There are a number of issues with this workflow.
- The onboarding and offboarding processes are not straightforward when it comes to VPN concentrators. I used to work as a network engineer getting VPN access requests quite often. These requests were for employees, third-party vendors, or contractors. It's a complicated request as you need to figure out the routing, access-lists, and so on. Many times when an employee or contractor leaves, nobody remembers to submit a request to remove access from these individuals. If an offboarding request is submitted, it's pretty complicated to remove the user.
- There is a need to maintain the SSH jump boxes. Moreover, your user now has network access. Once they've authenticated through the VPN, they're inside your network. This increases the attack surface.
- Now we need to put a firewall in front of the target hosts to only allow access from the jump box. This firewall operates based on IP and port identities. This is pretty brittle in a dynamic environment such as a public cloud where IPs are ephemeral.
- Finally, the user needs to know the credentials of the end target host that they want to access. If this target is a database, then the user needs to have a username and password to the database. That's also a concern from a security point of view because the credentials are exposed to the user.
HashiCorp Boundary's Workflow
Now let's see what the boundary workflow looks like. Below is a diagram of the HashiCorp Boundary workflow.
- Once again the user here needs to access a host or a set of hosts, The user now logs in with a trusted identity such as Okta, GitHub, or Active Directory. This is outside of Boundary. The identity provider would integrate with Boundary. From an onboarding and offboarding perspective it's pretty easy since it's tied to a trusted identity provider. Once a user is no longer part of the company, you can take them out of Okta and you're good to go.
- The next step is authorizing who gets to do what. This is achieved by using roles and logical services making authorization robust in dynamic environments.
- The third step is that the user has a catalog to select different applications and hosts that they have access to. The user most importantly does not have access to the entire network because Boundary is brokering the connection.
- Finally, the user will have access to the target host but the application credentials themselves are not exposed to the user. This can be done dynamically by creating short-lived credentials through Vault and passing them to the user. Taking this even further, a user would end up directly on the target host without having any credentials seen at all. Integration with Vault and identity providers is not yet available in this 0.1 release but is on the roadmap.
HashiCorp Boundary's Structure and Hierarchy
Below is an image showing the general structure within Boundary.
- At the top level is a Global.
- An Organization is a child of Global.
- Within an Organization, there are auth methods, users, groups, and projects.
- Within each project, you define roles, targets, and host catalogs.
- Inside a host catalog are host sets.
- Inside of host sets live the end target hosts.
You can create host sets that contain application infrastructure such as App Host Set 1 shown below. You can also create host sets based on function such as the database host set also shown in the image below. This way, database admins can have access to all databases in the organization.
Boundary Structure and Hierarchy
HashiCorp Boundary's Architecture for a Production Deployment
Below is a production deployment architectural diagram. Boundary has controllers and workers. In dev mode, they are on the same machine, but in production they're separate. In short, controllers expose the management plane via an API, whereas workers are the brokers or proxies of the secure sessions. You can find more information in the documentation.
Boundary's Architecture in a Production Environment
Consider a user/client on the Internet somewhere who wants to access different targets. For example, this user wants to access a Virtual Private Cloud (VPC) in AWS. The following describes the architecture and Boundary components to support this use case:
- A region
- A VPC
- Availability zones
- Public subnets
- Boundary workers. They are connection brokers that allow connections to target hosts so they have to be in the public subnet to be accessible from the Internet.
- Private subnets
- Boundary controllers. This is where the API lives. The controllers sit securely inside the private subnet and the application load balancer is what exposes them through the public subnet to the Internet.
- Target hosts. They live securely inside of the private subnets and don't have access to the Internet
- PostgreSQL Database
- Key Management Service (KMS)
Demo of HashiCorp Boundary
In this demo we SSH and RDP to 2 different target hosts and witness the packets in Wireshark. We'll see how HashiCorp Boundary proxies the connections and how the target hosts are not visible in our Wireshark captures. One thing to note here is that we use the HashiCorp Boundary Terraform Provider to configure Boundary.
HashiCorp Boundary in Dev Mode
Once you have Boundary installed as per these instructions. You can start Boundary in dev mode by simply running the command below.
boundary dev -api-listen-address=0.0.0.0 -cluster-listen-address=0.0.0.0 -proxy-listen-address=0.0.0.0 -worker-public-address=192.168.1.80
Terraform to Configure HashiCorp Boundary
As usual, my preferred method of configuring infrastructure is to use Terraform. We've seen this before when we used Terraform to configure Vault. With this first release of HashiCorp Boundary, you'll find a Terraform Boundary Provider ready to go. This is what we use to configure Boundary. You can find that our configuration is a simple
main.tf file along with a
variables.tf file. Please refer to the boundary intro repo for the code.
Authenticate to HashiCorp Boundary
Configure the Boundary address using the
BOUNDARY_ADDR environment variable. Then authenticate by creating a token and adding it to the
BOUNDARY_TOKEN environment variable as shown below:
export BOUNDARY_ADDR=http://192.168.1.80:9200 boundary authenticate password -auth-method-id=ampw_1234567890 -login-name=admin -password=password -token-name=none -format=json | jq -r ".token" > boundary_token.txt export BOUNDARY_TOKEN=$(cat boundary_token.txt)
SSH Connect to Linux Server
Log into Boundary's UI at
http://192.168.1.80:9200 (replace the host IP with yours) to retrieve the
target-id and the
host-id as shown in the two images below. To log into Boundary, the default username is
admin and the default password is
Target IDs Screenshot
Host IDs Screenshot
Run the following command to connect to the target host via SSH:
boundary connect ssh -target-id ttcp_tP3Uoe7X2d -host-id hst_uFcRGR4FCF
The SSH Connection with Wireshark
I ran a Wireshark capture during the SSH session to see the connection to Boundary from my client Windows machine. Below are some screenshots with a few points worth mentioning. The numbers on the screenshots correspond to the numbered points below.
Wireshark SSH Connection Overview
- The capture is filtered on
ip.addr == 192.168.1.80which is the Boundary server IP. If you filter on the end target IP, you get no packets. This confirms that there is no direct connection between my client machine and the target host.
- The source IP address is for my Linux VM and the destination IP address is for the Boundary Worker
- The first connection is to the Boundary controller on port 9200 for authentication. You can see the 3-way handshake for authentication to the controller.
- HTTP POST call providing the authentication token to the controller.
- The second connection is to the Boundary worker on port 9202 for SSH. You can see the 3-way handshake to connect to the worker
- The SSH protocol in action.
Wireshark Authentication in Cleartext
- Boundary running in dev mode by default uses the HTTP protocol which is insecure. We are able to view the authentication token over the wire. In production, you need to enable HTTPS.
- The host id is visible in the JSON payload.
Boundary Logs for SSH
- In the Boundary logs, you can see the IP of the end target is
192.168.1.90on port 22.
- Notice that there are 0 connections left because we only configured 1 allowed connection.
- I’m using the Windows Subsystem for Linux (WSL). This is why in the Wireshark capture, you see the source IP is
192.168.154.181, which is the IP of the Linux VM. Whereas in the Boundary logs, the source IP is
192.168.1.141, which is the actual IP on the LAN.
RDP Connect to Windows Server
Make sure you increase the connection count to at least 2 for RDP to work. The Terraform configuration already takes care of this for you. Run the command below replacing the
host-id with the one you retrieved when going through the SSH section above. If you're on Windows, the default RDP client opens up for you to enter your credentials to log into the Windows Server.
boundary connect rdp -target-id ttcp_nqhPabGuma -host-id hst_WB9GVkJe8L
Wireshark the RDP Connection
Once again, I ran the Wireshark capture during the RDP connection. You see similar behaviour as we saw earlier with the SSH session. One thing to note here is the necessity for 2 connections for RDP. You can view this in the Boundary logs screenshot that 2 connections are created and destroyed.
Wireshark RDP Connection to Windows Server
Boundary Logs for RDP
Conclusion and Future Roadmap of HashiCorp Boundary
I was very impressed by this initial 0.1 release of Boundary by the HashiCorp team. Boundary was built to solve the workflow issues around traditional human to machine access which are:
- Onboarding and Offboarding Difficulty at Scale
- Network Access Increasing Attack Surface
- Difficulty Managing IPs and Ports for Firewalls in Dynamic Environments
- Exposure of Application Credentials to Users
I look forward to seeing where this product goes in the future. If you're looking for a secure access management system and a secure sessions management system, then take a look at HashiCorp Boundary. Also, take a look at the future roadmap that the HashiCorp team has in store.