AWS offers a way to access EC2 in private subnet without needing outbound connection to the internet with AWS Systems Manager Session Manager. This is useful for situation where a bastion server is needed for accessing databases / cache.
Some of the benefits in using Session Manager:
- Access using IAM policies
- No opening of inbound ports to EC2 needed
- No management of SSH keys needed
- Easy access through AWS Console / AWS CLI
- Logging and auditing sessions through AWS CloudTrail / S3 / CloudWatch Logs
Below is an example of an architecture showing how user access the instance which is in the intra subnet (without internet access).
Architecture
Figure 1. EC2 private access with SSM Session Manager
We will assume us-east-1 as the preferred region in this article.
Requirements
For EC2 instance in a private subnet without internet access, these 3 VPC endpoints are needed:
- ssm
- ec2messages
- ssmmessages
SSM agent must be present in the EC2 instance (this is already bundled in Amazon Linux AMIs)
EC2 IAM role needs to have the IAM policy
AmazonSSMManagedInstanceCore
Things to take note
By default, sessions are launched using user with administrative access; ssm-user
. There are a couple of ways to prevent launching users with administrative roles:
- Tagging IAM user or role by specifying an OS user name in Session Manager preference.
Use the tag keySSMSessionRunAS
in the IAM user or role. - Configuring the Session Manager preference operating system user name.
Create the AWS SSM Document with the following nameSSM-SessionManagerRunShell
and the values accordingly:
|
|
- Disable the
ssm-user
account sudo permission by adding the following user-data to the EC2 instance.
Hands on
Let’s try to create the following architecture in AWS and accessing the EC2 via Sessions Manager. You can clone the terraform code from sparrow-bork/aws-lambda-post to follow along.
Note that you will incur some cost for running of the resources. The bulk of the cost is mostly from the VPC endpoint which is billed per hour.
*Figure 2. Our Imaginary Infrastructure
The terraform code creates a simple architecture consisting of an EC2 instance, lambda, and 3 VPC endpoint in the intra subnet with the ElastiCache Redis in its own dedicated subnet. Note that this is not meant to be production ready, just an example to show how a user would access the EC2 instance that is on a subnet without internet access.
EC2 AMI
Before spinning up the infra, we will need to create the AMI needed for the EC2 instance with the redis-cli and session manager plugin binary. The base image is based on Amazon Linux 2.
This is necessary as the bastion host will not have internet access and thus, will be unable to install those packages with user-data input when we launch the EC2 instance.
Output:
|
|
Take note of the ami id in the output. We will be using it in the terraform values file.
Spinning up the Infra
|
|
Once the terraform applied successfully, you should be able to see the resources in the us-east-1 region.
Validate default Session Manager Preferences
Figure 3. Custom Session Manager default preferences
The custom values should be applied to the default session manager preferences as shown in figure 3. This allows us to enforce the default preferences to the users.
Access EC2 with Session Manager
Go to the ElastiCache Redis page in the AWS Console and take note of the host endpoint.
To connect to the EC2 instance, go to AWS Systems Manager page in the AWS console followed by the Session Manager. Click on Start a session button and the EC2 instance should show up in the Target instances.
Figure 4. Connecting to EC2 instance via Session Manager
Figure 5. EC2 access via Session Manager and Connected to Redis
Figure 6. Session Manager Session History
We have successfully connected to the EC2 instance and ran a couple of redis commands on the ElastiCache Redis as shown in Figure 5. The history of the past sessions will be shown in the Session history tab and session activity logging will be in CloudWatch / S3 (if this is set) respectively.
Before you go
Don’t forget to clean the resources so you don’t incur additional billing. 😉 The AMI resource created by Packer needs to be manually deleted after terraform destroy
command successfully completed.