Port forwarding is a useful way to redirect network traffic from one IP address and port number combination to another. With port forwarding, you can access an EC2 instance located in a private subnet from your workstation.

In this post, we walk through a use case where customers have a strict security requirement for their Amazon Elastic Compute Cloud (Amazon EC2) instance to allow only private connectivity within Amazon Virtual Private Cloud (Amazon VPC): the Amazon EC2 instance only has a private IP address, with no access to NAT gateway or bastion host.

As shown in the diagram below, the Amazon EC2 instance is serving an internal application with a web interface that must be accessed securely by employees working remotely. To support this use case, we use an Interface VPC endpoint for AWS Systems Manager to facilitate private connectivity between a AWS Systems Manager agent on the Amazon EC2 instance and the Systems Manager service endpoints. We configure AWS Systems Manager Session Manager to enable port forwarding between the employee’s local workstation and the private Amazon EC2 instance so that the web application can be accessed securely.

Diagram showing Amazon EC2 instance port forwarding with AWS Systems Manager

Figure 1 – Accessing a private Amazon EC2 instance with AWS Systems Manager port forwarding

Prerequisites

For the purposes of this walkthrough, we assume the following about your AWS environment:

About this blog post
Time to read10 minutes
Learning levelIntermediate (300)
Services used Amazon VPC, AWS PrivateLink, AWS Systems Manager

Creating an Amazon VPC with a private subnet

A VPC is an isolated portion of the AWS cloud populated by AWS objects, such as Amazon EC2 instances. Follow the getting started with Amazon VPC guide to use the Amazon VPC wizard in the Amazon VPC console to create a VPC. In our use case, we only need the private subnet to launch our Amazon EC2 instance.

To use AWS private network connectivity to the Systems Manager service while making requests to its default public endpoint DNS name, ensure that the attributes Enable DNS hostnames and Enable DNS support are enabled for your VPC.

Launch an Amazon EC2 instance inside a private Amazon VPC

You can launch a Linux instance using the AWS Management Console as described in the launching Amazon EC2 instance guide. In this post, we use the Amazon Linux 2 Amazon Machine Image (AMI) to have a Systems Manager agent preinstalled by default. Refer to the Systems Manager agent overview to see the list of AMIs that have Systems Manager agent preinstalled.

Create an Amazon EC2 instance in a public subnet and install the web server of your choice. This first web server installation needs a public internet connection. In our scenario, we need the Amazon EC2 instance to be in a private subnet. Follow the instructions to move an Amazon EC2 instance to another subnet to migrate your Amazon EC2 instance into a private subnet.

Configure a interface VPC endpoint for AWS Systems Manager

Follow the steps in creating an interface endpoint to create the following interface endpoints:

  • com.amazonaws.region.ssm: The endpoint for the Systems Manager service.
  • com.amazonaws.region.ec2messages: Systems Manager uses this endpoint to make calls from the Systems Manager agent to the Systems Manager service.
  • com.amazonaws.region.ec2: If you’re using Systems Manager to create VSS-enabled snapshots, you must ensure that you have an endpoint to the EC2 service. Without the EC2 endpoint defined, a call to enumerate attached EBS volumes fails. This causes the Systems Manager command to fail.
  • com.amazonaws.region.ssmmessages: This endpoint is required for connecting to your instances through a secure data channel using Session Manager, in this case our port forwarding requirement.

Enable private DNS for interface endpoints

Private DNS for interface endpoints feature associates a private hosted zone with the Amazon VPC that contains a record set. This feature also enables you to use AWS private network connectivity to the Systems Manager service while making requests to the Systems Manager default public endpoint DNS name. To use this feature, ensure that the attributes Enable DNS hostnames and Enable DNS support are enabled for your Amazon VPC. Private DNS is enabled by default on endpoints created for AWS services.

The following example shows a ssm.us-east-1.amazonaws.com service endpoint resolved to a private IP address, allowing this Amazon EC2 instance to be managed by Systems Manager even though it’s located inside a private subnet.

[[email protected] ~]$ nslookup ssm.us-east-1.amazonaws.com
Server: 10.100.0.2
Address: 10.100.0.2#53
Non-authoritative answer:
Name: ssm.us-east-1.amazonaws.com
Address: 10.100.254.180
Name: ssm.us-east-1.amazonaws.com
Address: 10.100.1.176

Region parameter

Region represents the identifier for an AWS Region supported by AWS Systems Manager, such as us-east-2 for the US East (Ohio) Region. For a list of supported Region values, refer to the Region column in the AWS Systems Manager endpoints documentation.

The following picture shows all required interface VPC endpoints for the port forwarding requirements, using the us-east-1 Region as an example.

List of interface VPC endpoints for AWS Systems Manager

Figure 2 – Interface VPC endpoints for AWS Systems Manager

Set up AWS Systems Manager

By default, AWS Systems Manager doesn’t have permission to perform actions on your instances. You grant access by using an IAM instance profile, a container that passes IAM role information to an Amazon EC2 instance at launch.

Once your AWS Systems Manager permission is configured, follow the AWS Systems Manager Quick Setup guide to quickly configure the required IAM roles and commonly used AWS Systems Manager capabilities in your Amazon EC2 instances.

The AmazonSSMRoleForInstancesQuickSetup role must be attached to the Amazon EC2 instances, so that AWS Systems Manager has permission to perform actions on your instances.

List of IAM Roles created by AWS Systems Manager Quick Setup

Figure 3 – IAM Roles created by AWS Systems Manager Quick Setup

Follow the AWS Sytems Manager instance profile guide to verify or create an IAM instance profile with Session Manager permissions.

Once AWS Systems Manager setup is completed, the Amazon EC2 instances are registered with the AWS Systems Manager service. Run the following command to verify setup completion. (In this example, there are two Amazon EC2 instances with private IP-only access that are managed by AWS Systems Manager.)

[email protected]:~$ aws ssm get-inventory
{ "Entities": [ { "Data": {}, "Id": "i-0006803bf97sgtsgt" }, { "Data": { "AWS:InstanceInformation": { "Content": [ { "ComputerName": "ip-10-100-1-52.ec2.internal", "InstanceId": "i-005cc2c4661sgtsgt", "IpAddress": "10.100.1.52", "AgentType": "amazon-ssm-agent", "ResourceType": "EC2Instance", "AgentVersion": "2.3.1319.0", "PlatformVersion": "2", "PlatformName": "Amazon Linux", "PlatformType": "Linux" } ], "TypeName": "AWS:InstanceInformation", "SchemaVersion": "1.0", "CaptureTime": "2020-07-03T19:29:40Z" } }, "Id": "i-005cc2c4661sgtsgt" }, { "Data": { "AWS:InstanceInformation": { "Content": [ { "ComputerName": "ip-10-100-1-110.ec2.internal", "InstanceId": "i-0cb65f68833sgtsgt", "IpAddress": "10.100.1.110", "AgentType": "amazon-ssm-agent", "ResourceType": "EC2Instance", "AgentVersion": "2.3.1319.0", "PlatformVersion": "2", "PlatformName": "Amazon Linux", "PlatformType": "Linux" } ], "TypeName": "AWS:InstanceInformation", "SchemaVersion": "1.0", "CaptureTime": "2020-07-03T19:23:25Z" } }, "Id": "i-0cb65f68833sgtsgt" } ]
}

Access an Amazon EC2 instance using Session Manager port forwarding

Note: Before attempting to start a session, ensure that you have completed the steps above to setup Session Manager. For more information, see getting started with Session Manager.

To use the AWS Systems Manager command line interface (AWS CLI) for port forwarding, the Session Manager plugin must be installed on your local machine. For more information, read the install the Session Manager plugin for the AWS CLI documentation.

aws ssm start-session \
--target instance-id \
--document-name AWS-StartPortForwardingSession \ --parameters '{"portNumber":["80"], "localPortNumber":["9090"]}'

The following snippet shows port forwarding AWS CLI execution for one of the Amazon EC2 instances:

[email protected]:~$ aws ssm start-session --target i-005cc2c4661sgtsgt --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["80"], "localPortNumber":["9090"]}' Starting session with SessionId: [email protected]
Port 9090 opened for sessionId [email protected]
Waiting for connections...

Open you web browser to access the Amazon EC2 instance web application on localhost:9090 :

Accessing web application on private Amazon EC2 instance using Session Manager port forwarding

Figure 4 – Accessing a web application on a private Amazon EC2 instance using Session Manager port forwarding

The Session Manager AWS CLI will log an accepted connection for the session:

[email protected]:~$ aws ssm start-session --target i-005cc2c4661sgtsgt --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["80"], "localPortNumber":["9090"]}' Starting session with SessionId: [email protected]
Port 9090 opened for sessionId [email protected]
Waiting for connections... Connection accepted for session [email protected]

Cleanup

Be sure to shut down any Amazon EC2 instances you launched to walk through this example.

Conclusion

In this post, we walked you through creating an Amazon VPC with a private subnet, and launching a private Amazon EC2 instance with a simple web server. We also walked through interface VPC endpoint configuration, AWS Systems Manager Quick Setup, and finally accessing the private web application using the Session Manager port forwarding feature.

Port forwarding works for Windows and Linux instances. It is available today in all AWS Regions where AWS Systems Manager is available. There is no additional cost when connecting to Amazon EC2 instances; you are charged for the outgoing traffic from your interface VPC endpoint.

About the Authors

Sigit Priyanggoro

Sigit Priyanggoro is a Sr Partner Solutions Architect for the Global System Integrator team. He works with partners and customers on AWS technologies in Management Tools, Telecom, and Mobile. In his spare time, he plays in a band as a guitarist and backup drummer. You can reach him via @sigitp on Dev.To.

 

 

 

Sruthi Maddineni

Sruthi Maddineni is a Software Development Engineer with AWS Systems Manager working mainly on Session Manager. Outside of work, Sruthi likes hiking, traveling and trying different cuisines.