Apr 3, 2024
5 Min read

How to SSH into EC2 instances in private subnets

Cover image. EC2 instance in a private subnet.

In this tutorial, we will SSH into an EC2 instance in a private subnet using two methods.

  1. SSH via a bastion host in a public network (without copying the SSH keys to the bastion host)
  2. SSH via EC2 Instance Connect Endpoint

Prerequisites

You can do this tutorial on a Linux, Mac, or Windows workstation. If you are on Windows, use WSL to run the terminal commands.

You need an AWS account with privileges to create the resources used in this tutorial.

Being familiar with AWS networking concepts is essential for this tutorial. You also should know how to provision resources like VPC, Subnets, EC2, Security groups, etc., via AWS GUI or the CLI. Check out this tutorial on AWS networking for further details.

Building the cloud infra

Cloud infra for this tutorial.

Build this cloud infra using AWS GUI or the CLI in your preferred AWS region. Check out this tutorial on AWS networking for step-by-step instructions of provisioning a similar setup via AWS GUI.

This cloud infra consists of two EC2 instances, ec2-private in a private subnet and ec2-public in a public subnet. ec2-public has a public IPv4 address.

ec2-public is configured with a security group that allows SSH from any IP address on the Internet. The security group of ec2-private allows SSH from ec2-public.

Connecting to EC2 in private subnet

Now, we will SSH into ec2-private using these two methods.

  1. SSH via a bastion host in a public network (without copying the SSH keys to the bastion host)
  2. SSH via EC2 Instance Connect Endpoint

#1: SSH via a bastion host in a public network

We can directly SSH into ec2-public via its public IPv4 address. So, ec2-public can act as a bastion host to connect to ec2-private.

We can first SSH into ec2-public and then SSH into ec2-private from there. To do so we must copy the SSH keys of ec2-private into ec2-public. But keeping the SSH keys of ec2-private in ec2-public is a security risk. If ec2-public is compromised, an attacker could easily gain access to ec2-prvate as well.

So, we use SSH ProxyJump to directly SSH into ec2-private from our laptop.

  1. Copy EC2 SSH keys to ~/.ssh/my-keys path on your laptop. Use WSL if you are on a Windows workstation.

  2. Change the file permissions so that only the owner can read the SSH key files.

chmod 600 .ssh/my_keys/ec2-public.pem
chmod 600 .ssh/my_keys/ec2-private.pem

Here we are using two separate keys for ec2-public and ec2-private. You can also use the same key for both.

  1. Create file ~/.ssh/config with below configurations for ec2-public and ec2-private.
HOST ec2-public
   hostname a.b.c.d
   user ubuntu
   IdentityFile ~/.ssh/my-keys/ec2-public.pem

HOST ec2-private
   hostname e.f.g.h
   user ubuntu
   IdentityFile ~/.ssh/my-keys/ec2-private.pem
   ProxyJump ec2-public

Make sure to replace a.b.c.d with the public IP address of ec2-public. Replace e.f.g.h with the private IP address of ec2-private.

  1. open new SSH session.
$ ssh ec2-private

You would be connected to ec2-private.

If you cannot successfully connect, here’s a three-step troubleshooting guide.

  1. Check the security groups of both ec2-public and ec2-private. The security group of ec2-public must allow SSH in the inbound direction from any IP address on the Internet. The security group of ec2-private must allow SSH in the inbound direction from the private IP address of ec2-public.
  2. Check that network ACLs are not blocking SSH ports.
  3. SSH into ec2-public using the public IP address and make sure you can connect to ec2-public.

#2: SSH via EC2 Instance Connect Endpoint

Create an EC2 Instance Connect Endpoint.

  1. Log in to the AWS GUI console and select VPC from the Services menu.
  2. On the left-navigation menu click on Endpoints under Virtual Private Cloud section.
  3. Enter my-ec2-endpoint for Name.
  4. Select EC2 instance connect endpoint for the Service category.
  5. From the VPC drop-down list, select the VPC my-vpc.
  6. Select a security group that allows SSH protocol in the outbound direction. If you do not have a security group that allows SSH in the outbound direction, create a new security group for this purpose.

    An EC2 Instance Connect Endpoint needs to be configured with a security group that allows SSH in the outbound direction. If not you will not be able to SSH into an EC2 via the endpoint.

  7. Select a subnet from the Subnet drop-down list. The subnet need not be the same subnet that your EC2 instance is connected to.
  8. Click on Create endpoint. Wait till the new endpoint status becomes Available. It could take about one minute.

Connect to ec2-private via the endpoint.

  1. Go to EC2 console and click on Instances.
  2. Select the ec2-private and click on Connect button in the top menu.
  3. Select option Connect using EC2 instance connect endpoint in the Connection type.
  4. Since we have only one EC2 instance connect endpoint, it will be selected by default.
  5. The username ubuntu is also populated automatically.
  6. Scroll down and click on Connect.

You’ll get this SSH session to ec2-private in a new browser tab. Browser-based SSH session via EC2 Instance connect endpoint.

Wrapping up

In this tutorial, we connected to an EC2 in a private subnet using two different methods. And we did it all without copying the SSH keys to the bastion host.

It’s a security risk to store SSH keys on a bastion host. Now you can avoid that by following one of these methods to SSH into EC2 in private subnets.