Session Manager allows you to open a shell environment (e.g., Bash on Linux hosts, PowerShell on Windows hosts) to instances running the SSM Agent via a web browser or the AWS CLI. These connections are authenticated with IAM credentials. Because instances are running the SSM agent, there is no need to put instances in a public subnet or open security group ports to outside traffic. All that is required is for the instance to have a connection to the SSM service (either through an internet route or a VPC endpoint) and an IAM role that gives the instance proper permissions to the SSM service. This eliminates the need for bastion hosts and management of SSH keys. As an added bonus, all Session Manager sessions are logged with which IAM user/role initiated the session and what time they connected.
Having CLI access to instances in private subnets without a bastion host is a huge benefit. However, what if you needed GUI access to a Windows EC2 (Elastic Cloud Compute) instance? PowerShell is great and all, but there are some things that can’t be done as easily via the CLI. This is where port forwarding comes in. With port forwarding, you can forward a port on a remote instance to a port on your local machine. This allows a user to forward the traditional Remote Desktop Protocol (RDP) port (3389/tcp) to an available port on their local machine (e.g., 58212/tcp). The user can then use any RDP client to connect to the forwarded port on their local machine to access the instance in AWS (e.g., connect to localhost:58212 in the RDP client). You can also use this same concept to forward any service that uses a tcp port on your remote instance to a local port on your machine.
Traditionally port forwarding has been done with SSH tunneling. However, AWS has made the feature available through Session Manager’s
AWS-StartPortForwardingSession document. Let’s walk through how to make an RDP connection to a Windows instance over a forwarded port.
Prerequisites for this include:
- An EC2 instance with internet connectivity (via NAT gateway is fine) OR in a subnet that has VPC endpoints for SSM configured.
- An IAM instance profile assigned to the instance that has the
AmazonSSMManagedInstanceCoremanaged policy attached (or similar permissions).
- The Amazon SSM Agent installed and running on the instance.
- The AWS CLI installed and configured on your local machine.
- The latest version of the Session Manager Plugin for the AWS CLI installed on your local machine.
Once you have verified the above prerequisites have been met, choose an unused port on your machine for the port forward. Generally it’s best to use an ephemeral port between 1025 and 65535. Personally I usually choose a port somewhere in the 8000-9999 range. Once you have decided on a port, obtain the EC2 instance ID (either in the console or via the CLI). The default port for RDP is 3389, so we will forward that port on the remote machine to our chosen port on our local machine. We can do so by running the following command (don’t forget to add
--profile <your profile name> if you configured the AWS CLI with a profile):
$ aws ssm start-session --target <instance-id> --document-name AWS-StartPortForwardingSession --parameters "localPortNumber=<chosen port number>,portNumber=3389"
If the command is successful, you will see output similar to the following in your terminal (in my example, I used local port 8000):
$ aws ssm start-session --target i-01234567890abcdef --document-name AWS-StartPortForwardingSession --parameters "localPortNumber=8000,portNumber=3389"
Starting session with SessionId: <session id name>
Port 8000 opened for sessionId <session id name>.
Congratulations! You’ve just forwarded a port from your remote EC2 instance to your local machine! As long as you keep the terminal window open with the command running, the port will continue to be forwarded. Let’s check to see if we can get an RDP connection.
If all has worked properly up to this point, we should have port 3389 on our EC2 instance forwarded to the port we chose earlier on our local machine. The next step is to connect to an RDP session. Simply open your RDP client of choice and enter
localhost:<your chosen port> as the remote machine address. In my example, I used
localhost:8000. Make any desired adjustments to your connection settings (e.g., forwarding folders, printers, etc.) and hit the “Connect” button.
You will now be prompted to enter a username and password for authentication for your Windows instance. This could be the default Administrator user account and decrypted password from the AWS console if using a vanilla Amazon provided Windows AMI, or if your EC2 instance is joined to an Active Directory domain, this will be your Active Directory credentials. Once successfully authenticated, you should be presented with the Windows desktop of your EC2 instance.
When you look back at your terminal window running the
aws ssm start-session command you will notice some new output.
Connection accepted for session <session id name>.
Once you’ve completed your work on the EC2 instance, you can safely disconnect from the RDP session. You can then go to your terminal window and hit
Ctrl+C to cancel the session manager command. This will close the connection to your EC2 instance and remove any forwarded ports from the instance on your local machine.
AWS Systems Manager Session Manager provides a secure solution to access your EC2 instances in private subnets without the use of bastian hosts or open ports. Using port forwarding we can extend the basic CLI functionality of Systems Manager to include accessing Windows instances with RDP.
If you’d like help with AWS Systems Manager, EC2, or any other service, please reach out to firstname.lastname@example.org and have one of our experts help you.