Edit Template

How to Access an EC2 Machine in a Private Subnet from Your Local Machine

Introduction

Working with AWS, you'll often encounter EC2 instances tucked away in private subnets. This architecture follows security best practices by isolating critical resources from direct internet access, but it creates a challenge: how do you access these instances from your local machine?

Whether you need to perform maintenance, troubleshoot issues, or deploy applications, connecting to private EC2 instances is an essential skill for DevOps engineers and cloud practitioners. In this guide, we'll explore four proven methods to securely access your private EC2 instances without compromising your AWS security posture.

Understanding Private Subnets in AWS

Before diving into the solutions, let's clarify why EC2 instances often reside in private subnets:

  • Enhanced security: No direct internet exposure means reduced attack surface
  • Network segmentation: Separating application tiers (web, application, database)
  • Compliance requirements: Many standards require isolating sensitive data

A typical AWS VPC architecture includes both public subnets (with internet access via Internet Gateway) and private subnets (with optional outbound-only internet access via NAT Gateway).

image_1

Method 1: SSH via Bastion Host (Jump Server)

The most traditional approach involves setting up a bastion host (also called a jump server) in a public subnet that acts as a gateway to your private instances.

How It Works

  1. You SSH into the publicly accessible bastion host
  2. From the bastion, you SSH into the private EC2 instance
  3. SSH agent forwarding allows you to use your local machine's private key without storing it on the bastion

Setup Instructions

1. Configure Your Bastion Host

First, launch an EC2 instance in a public subnet with the following settings:

  • Use a minimal, hardened AMI (Amazon Linux 2 is a good choice)
  • Configure a security group allowing SSH (port 22) from your IP address only
  • Assign a public IP address or Elastic IP

2. Configure Your Private Instance Security Group

Ensure your private instance's security group allows SSH access from the bastion host's security group:

Type: SSH
Protocol: TCP
Port: 22
Source: Bastion's security group ID (sg-xxxxxxxx)

3. Set Up SSH Agent Forwarding

On your local machine:

# Start the SSH agent (if not already running)
eval "$(ssh-agent -s)"

# Add your private key to the agent
ssh-add ~/.ssh/your-private-key.pem

# Verify the key was added
ssh-add -L

4. Connect Through the Bastion

Now you can connect to your private instance through the bastion:

# Connect to the bastion with agent forwarding enabled (-A flag)
ssh -A ec2-user@bastion-public-ip

# From the bastion, connect to the private instance
ssh ec2-user@private-instance-ip

Pros and Cons

Pros:

  • Works with any SSH client
  • No need to store private keys on the bastion
  • Simple to understand and implement

Cons:

  • Requires maintaining a bastion host
  • Additional cost for the bastion instance
  • Potential security risks if the bastion is compromised

Method 2: AWS Systems Manager Session Manager

AWS Systems Manager Session Manager provides a browser-based shell or CLI-based connection to your EC2 instances without requiring open inbound ports, bastion hosts, or SSH keys.

image_2

How It Works

  1. The EC2 instance runs the SSM Agent and has an IAM role that allows Systems Manager connections
  2. You initiate a session through the AWS console or CLI
  3. The connection is established through AWS's service endpoints

Setup Instructions

1. Configure IAM Role for the EC2 Instance

Create or attach an IAM role with the following policies:

  • AmazonSSMManagedInstanceCore (managed policy)

2. Install SSM Agent on the EC2 Instance

The SSM Agent comes pre-installed on many Amazon AMIs. To verify or install:

# Check if agent is running
sudo systemctl status amazon-ssm-agent

# If not installed, install it (Amazon Linux 2)
sudo yum install -y amazon-ssm-agent
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent

3. Connect via AWS Console

  1. Navigate to the AWS Systems Manager console
  2. Select "Session Manager" from the left menu
  3. Click "Start session"
  4. Select your private EC2 instance and click "Start session"

4. Connect via AWS CLI

# Start a session to your instance
aws ssm start-session --target i-0123456789abcdef0

# For port forwarding (e.g., to access a web server on port 80)
aws ssm start-session \
--target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["80"],"localPortNumber":["8080"]}'

After running the port forwarding command, you can access the web server at http://localhost:8080 from your local machine.

Pros and Cons

Pros:

  • No need for bastion hosts or open inbound ports
  • No SSH key management
  • Activity logged in AWS CloudTrail
  • Supports port forwarding for web applications
  • Works through the AWS console (no SSH client needed)

Cons:

  • Requires IAM permissions
  • SSM Agent must be running on the instance
  • Network path to AWS SSM endpoints required

Method 3: EC2 Instance Connect

EC2 Instance Connect allows you to connect to your instances using your IAM credentials without storing SSH keys on the instance long-term.

How It Works

  1. You generate an SSH key pair or use an existing one
  2. AWS temporarily pushes your public key to the instance (valid for 60 seconds)
  3. You connect using your private key

Setup Instructions

1. Install EC2 Instance Connect on Your EC2

For Amazon Linux 2:

sudo yum install -y ec2-instance-connect

For Ubuntu:

sudo apt-get update
sudo apt-get install -y ec2-instance-connect

2. Configure IAM Permissions

Create a policy allowing users to push SSH keys:

{
"Version": "2012-10-17",
"Statement": [
  {
    "Effect": "Allow",
    "Action": "ec2-instance-connect:SendSSHPublicKey",
    "Resource": "arn:aws:ec2:region:account-id:instance/instance-id"
  }
]
}

3. Connect Using EC2 Instance Connect CLI

Install the EC2 Instance Connect CLI:

pip install ec2instanceconnectcli

Connect to your instance:

mssh ec2-user@i-0123456789abcdef0

4. Connect Using AWS CLI and SSH Client

Push your public key to the instance:

aws ec2-instance-connect send-ssh-public-key \
--instance-id i-0123456789abcdef0 \
--availability-zone us-east-1a \
--instance-os-user ec2-user \
--ssh-public-key file://~/.ssh/id_rsa.pub

Then connect within 60 seconds using your SSH client:

ssh -i ~/.ssh/id_rsa ec2-user@private-ip-address

Pros and Cons

Pros:

  • No permanent SSH keys stored on instances
  • Integrates with IAM permissions
  • Available through AWS console

Cons:

  • Requires network connectivity to the EC2 Instance Connect API endpoint
  • For private instances, requires connectivity to the private IP (VPN, Direct Connect, etc.)
  • EC2 Instance Connect package must be installed on the instance

Method 4: EC2 Instance Connect Endpoint

EC2 Instance Connect Endpoint (EICE) is a newer service that allows secure connections to instances in private subnets without requiring bastion hosts, public IPs, or direct VPN connectivity.

image_3

How It Works

  1. You create an EC2 Instance Connect Endpoint in your VPC
  2. The endpoint acts as a secure tunnel between your local machine and the private instances
  3. Authentication is handled through IAM

Setup Instructions

1. Create an EC2 Instance Connect Endpoint

In the AWS Console:

  1. Navigate to the EC2 console
  2. Select "EC2 Instance Connect Endpoint" from the left menu
  3. Click "Create EC2 Instance Connect Endpoint"
  4. Select your VPC and subnet
  5. Configure security groups allowing traffic to your instances

Or using AWS CLI:

aws ec2 create-instance-connect-endpoint \
--subnet-id subnet-0123456789abcdef0 \
--security-group-ids sg-0123456789abcdef0

2. Configure IAM Permissions

Ensure users have the following permissions:

{
"Version": "2012-10-17",
"Statement": [
  {
    "Effect": "Allow",
    "Action": [
      "ec2-instance-connect:OpenTunnel",
      "ec2:DescribeInstances",
      "ec2:DescribeInstanceConnectEndpoints"
    ],
    "Resource": "*"
  }
]
}

3. Connect via AWS CLI

# Connect using SSH
aws ec2-instance-connect ssh \
--instance-id i-0123456789abcdef0 \
--private-key-file ~/.ssh/my-key.pem

# Connect using RDP (for Windows instances)
aws ec2-instance-connect open-tunnel \
--instance-id i-0123456789abcdef0 \
--remote-port 3389 \
--local-port 13389

For RDP connections, after running the open-tunnel command, connect to localhost:13389 using your RDP client.

Pros and Cons

Pros:

  • No bastion hosts or public IPs required
  • No VPN or Direct Connect needed
  • Works through IAM authentication
  • Supports both SSH and RDP

Cons:

  • Currently only supports SSH (port 22) and RDP (port 3389)
  • Limited to CLI-based connections
  • Additional cost for EC2 Instance Connect Endpoint ($0.01 per hour)

Security Best Practices

Regardless of which method you choose, follow these security best practices:

  1. Limit access – Restrict who can connect using IAM policies and security groups
  2. Use strong keys – Generate 4096-bit RSA or ED25519 keys
  3. Implement logging – Enable CloudTrail and VPC Flow Logs to monitor connections
  4. Rotate credentials – Regularly update SSH keys and IAM credentials
  5. Use multi-factor authentication – Enable MFA for AWS console access
  6. Consider dedicated VPN – For teams requiring frequent access, set up AWS Client VPN

Choosing the Right Method

Each method has its use cases:

  • Bastion Host: Good for organizations with existing SSH workflows and when you need access to multiple ports
  • Systems Manager Session Manager: Ideal for organizations prioritizing security and auditability
  • EC2 Instance Connect: Useful for temporary access without managing long-term SSH keys
  • EC2 Instance Connect Endpoint: Best for modern environments needing secure access without bastion hosts or VPNs

Conclusion

Accessing EC2 instances in private subnets doesn't have to be complex or compromise security. AWS provides multiple options to fit various requirements and security postures.

For most DevOps teams at DevOps Horizon, we recommend Systems Manager Session Manager for day-to-day operations and EC2 Instance Connect Endpoint for environments where maximum security is required.

If you're looking to enhance your AWS skills, check out our AWS certification guides and DevOps roadmap to accelerate your cloud career!

Got questions about AWS networking, security, or other DevOps topics? Drop them in the comments below, and our team will help you out!

Leave a Reply

Your email address will not be published. Required fields are marked *

Most Recent Posts

Category

content created for you!

Company

About Us

FAQs

Contact Us

Terms & Conditions

Features

Copyright Notice

Mailing List

Social Media Links

Help Center

Products

Sitemap

New Releases

Best Sellers

Newsletter

Help

Copyright

Mailing List

© 2023 DevOps Horizon