What You'll Build and Why It Matters

You'll establish a secure tunnel from your Raspberry Pi to an AWS EC2 cloud server, giving you persistent access to your device from anywhere on the planet. This solution works behind even the most restrictive NAT configurations and requires zero router configuration.

NAT Traversal Made Simple

Works behind any router without port forwarding. Your Raspberry Pi initiates the connection outbound—no exposed ports in your home network.

Rock-Solid Reliability

Automatic reconnection on network hiccups. The systemd service monitors your tunnel and brings it back up within 10 seconds of any disruption.

Security by Design

ED25519 keys for all connections. Dedicated unprivileged tunnel user on EC2 for proper isolation. Defense in depth from the ground up.

Multiple Access Patterns

Three connection methods: two-hop manual, direct via ProxyCommand, and streamlined SSH config. Pick what fits your workflow.

Understanding Reverse SSH

Traditional SSH requires your server (Raspberry Pi) to be directly accessible from the internet. But home routers block inbound connections, and port forwarding creates security vulnerabilities you'd rather avoid.

Reverse SSH flips the script: your Raspberry Pi establishes an outbound connection to a public EC2 server and keeps that tunnel alive. The server forwards port 2222 back to your device's port 22. You connect to the server, then hop through the tunnel to your Pi.

The Core Principle

Your Raspberry Pi initiates an outbound connection (which NAT happily allows) and holds it open. EC2 listens on port 2222 and tunnels traffic back through that persistent connection. Elegant and effective.

Solution Architecture

Your Computer

Anywhere worldwide

EC2 Bridge

100.64.0.0:2222

Raspberry Pi

Behind home router

System Components

AWS EC2 Instance

Your public-facing bridge server in the cloud. Always reachable via static IP.

  • IP Address: 100.64.0.0
  • Operating System: Ubuntu Server 22.04 LTS
  • Instance Type: t2.micro (Free Tier eligible)

Raspberry Pi 5

Your home device that initiates and maintains the tunnel connection.

  • Username: a528fe2
  • Local Network Address: raspberrypi.local
  • SSH Port: 22 (standard)

SSH Tunnel

Encrypted channel between Raspberry Pi and EC2, managed by systemd service.

  • EC2 Port: 2222 (forwards to RPI:22)
  • Type: Remote Port Forwarding (-R flag)
  • Auto-start: systemd unit reverse-tunnel.service

Requirements and Preparation

Pre-flight Checklist

  • AWS account with EC2 access and ability to create Security Groups
  • Raspberry Pi with OS installed (Raspberry Pi OS, Ubuntu) and local SSH access
  • Basic SSH knowledge and terminal comfort (Linux/macOS/WSL on Windows)
  • Text editor familiarity (vim or nano for config editing)

Port Reference Guide

PortPurposeWhere Open
22Standard SSH port for direct server accessEC2 (restricted via Security Group)
2222Tunnel port for Raspberry Pi accessEC2 (open to 0.0.0.0/0)
22SSH server on Raspberry PiRaspberry Pi (accessible only via tunnel)

Step 1: Setting Up Your EC2 Instance

1.1 Launching the Instance

  1. Open the AWS Console and navigate to EC2
  2. Click Launch Instance
  3. Name it: rpi-tunnel-server
  4. Choose AMI: Ubuntu Server 22.04 LTS (HVM), SSD Volume Type
  5. Instance type: t2.micro (perfect for Free Tier)
  6. Key pair: create a new one named rpi-tunnel-key

Critical: Guard that private key

The rpi-tunnel-key.pem file will download automatically. Without it, you're locked out of your EC2 instance. Store it somewhere safe and secure.

1.2 Security Group Configuration

Create a Security Group with these inbound rules:

TypePortSourcePurpose
SSH22My IPYour direct server access
Custom TCP22220.0.0.0/0Tunnel access from anywhere

1.3 Securing Your Key Locally

On your local machine (Linux/macOS or WSL):

1# Move the key to your SSH directory
2mv ~/Downloads/rpi-tunnel-key.pem ~/.ssh/
3
4# Set restrictive permissions (SSH demands this)
5chmod 400 ~/.ssh/rpi-tunnel-key.pem

Quick Reference: chmod 400

Permissions 400 mean: owner can read, nobody else can do anything. SSH refuses to use keys with loose permissions—it's picky about security, which is good.

1.4 First Connection Test

Once your instance launches, AWS assigns it a public IP. In our example, that's 100.64.0.0:

1ssh -i ~/.ssh/rpi-tunnel-key.pem ubuntu@100.64.0.0

On first connection, SSH will ask you to verify the fingerprint—type yes.

Step 2: Configuring the SSH Server

2.1 System Updates

Once connected to EC2, bring the system up to date:

1sudo apt update && sudo apt upgrade -y

2.2 SSH Server Configuration

Open the SSH daemon configuration:

1sudo vim /etc/ssh/sshd_config

Find and modify these parameters:

1# Allow port forwarding to external interfaces
2GatewayPorts yes
3
4# Send keepalive packets every 60 seconds
5ClientAliveInterval 60
6
7# Drop connection after 3 unanswered keepalives
8ClientAliveCountMax 3

Deep Dive: GatewayPorts

By default, SSH only binds forwarded ports to localhost. Setting GatewayPorts yes allows binding port 2222 to all network interfaces, which is essential for external access to your tunnel.

Save and exit: hit Esc, type :wq and press Enter.

Restart the SSH service:

1sudo systemctl restart ssh

2.3 Creating a Dedicated Tunnel User

Let's create an unprivileged user specifically for tunnel management:

1sudo adduser tunnel

Set a password (e.g., TunnelPass2025!). You can skip the other fields by pressing Enter.

Why a separate user?

Principle of least privilege in action. The tunnel user exists solely for the tunnel and has no access to system resources. This limits blast radius if something goes sideways.

2.4 Setting Up authorized_keys

Switch to the tunnel user:

1sudo su - tunnel

Create the SSH directory with proper permissions:

1mkdir .ssh
2chmod 700 .ssh
3touch .ssh/authorized_keys
4chmod 600 .ssh/authorized_keys

SSH Permission Requirements

  • 700 on .ssh — owner can read, write, and execute
  • 600 on authorized_keys — owner can read and write only
  • SSH strictly enforces these permissions and will refuse to work otherwise

Keep this terminal open—you'll return here after generating keys on your Raspberry Pi.

Step 3: Raspberry Pi Configuration

3.1 Connecting to Your Pi

Connect to your Raspberry Pi locally or via SSH on your home network:

1ssh a528fe2@raspberrypi.local

Password: 0fa65eb3e31c

About .local Addresses

raspberrypi.local works via mDNS (Multicast DNS). If it doesn't resolve, use the Pi's local IP address instead (e.g., 192.168.1.100). Check your router's DHCP leases if needed.

3.2 Generating SSH Keys for the Tunnel

On your Raspberry Pi, create a fresh ED25519 key pair:

1ssh-keygen -t ed25519 -f ~/.ssh/id_tunnel

When prompted for a passphrase, just hit Enter (no passphrase needed for automated connections).

Why ED25519?

ED25519 is a modern elliptic curve algorithm that's faster and more secure than RSA. Keys are significantly shorter (256 bits vs 2048-4096 bits for RSA) while providing equivalent or better security. It's the gold standard for SSH keys today.

3.3 Extracting the Public Key

Display the public key:

1cat ~/.ssh/id_tunnel.pub

Copy the entire output (starts with ssh-ed25519 AAAA...).

3.4 Adding the Key to EC2

Return to your EC2 terminal where you're logged in as the tunnel user:

1vim .ssh/authorized_keys

Press i to enter insert mode, paste the public key, then hit Esc, type :wq and press Enter.

Exit back to the ubuntu user:

1exit

3.5 Testing Key-Based Authentication

Back on your Raspberry Pi, verify you can connect to EC2 with the new key:

1ssh -i ~/.ssh/id_tunnel tunnel@100.64.0.0

If prompted "Are you sure?", type yes. The connection should succeed without asking for a password.

Key Authentication Working

If you connected without a password prompt—excellent! Key-based auth is configured correctly. Exit with exit.

Step 4: Creating a Persistent Tunnel

4.1 Manual Tunnel Test

On your Raspberry Pi, start the tunnel in background mode:

1ssh -i ~/.ssh/id_tunnel -fN -R 2222:localhost:22 tunnel@100.64.0.0

SSH Flags Explained

  • -i ~/.ssh/id_tunnel — specifies which private key to use
  • -f — backgrounds the process after successful connection
  • -N — don't execute any commands on the remote server (tunnel only)
  • -R 2222:localhost:22 — Remote Port Forwarding: forward remote port 2222 to local port 22

4.2 Verifying the Tunnel

Connect to your EC2 instance:

1ssh -i ~/.ssh/rpi-tunnel-key.pem ubuntu@100.64.0.0

Check that port 2222 is listening:

1sudo ss -tulpn | grep 2222

You should see a line showing port 2222 in LISTEN state. Now try connecting to your Raspberry Pi through the tunnel:

1ssh -p 2222 a528fe2@localhost

Enter your Raspberry Pi password: 0fa65eb3e31c

Tunnel Operational!

If you're now on your Raspberry Pi—congratulations! The tunnel is working perfectly. Exit twice (exit from RPI, exit from EC2).

4.3 Automating with systemd

On your Raspberry Pi, create a systemd service for automatic tunnel startup:

1sudo vim /etc/systemd/system/reverse-tunnel.service

Insert this configuration (press i, paste, then Esc :wq):

1[Unit]
2Description=Reverse SSH Tunnel to EC2
3After=network-online.target
4Wants=network-online.target
5
6  [Service]
7Type=simple
8User=a528fe2
9ExecStart=/usr/bin/ssh -i /home/a528fe2/.ssh/id_tunnel -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -o StrictHostKeyChecking=no -N -R 2222:localhost:22 tunnel@100.64.0.0
10Restart=always
11RestartSec=10
12
13  [Install]
14WantedBy=multi-user.target

systemd Service Breakdown

  • After=network-online.target — wait for full network initialization
  • Type=simple — process runs in foreground
  • Restart=always — automatically restart on failure
  • RestartSec=10 — wait 10 seconds before restarting
  • ServerAliveInterval=60 — send keepalive every 60 seconds
  • ExitOnForwardFailure=yes — exit if port forwarding fails

Enable and start the service:

1sudo systemctl daemon-reload
2sudo systemctl enable reverse-tunnel.service
3sudo systemctl start reverse-tunnel.service

Check the status:

1sudo systemctl status reverse-tunnel.service

You should see active (running). If there are errors, check the logs:

1sudo journalctl -u reverse-tunnel.service -n 50

Step 5: Connection Methods

Method 1: Two-Hop Connection

Connect to EC2 first, then hop to your Raspberry Pi:

1# Step 1: Connect to EC2
2ssh -i ~/.ssh/rpi-tunnel-key.pem ubuntu@100.64.0.0
3
4# Step 2: From EC2, connect to RPI through the tunnel
5ssh -p 2222 a528fe2@localhost
6# Password: 0fa65eb3e31c

When to Use This

Great for debugging and understanding the flow. Lets you inspect the tunnel state on EC2 before connecting to your Pi. Also useful when you need to check EC2 logs or system state.

Method 2: Direct Single-Command Connection

Connect directly to your Raspberry Pi through EC2:

1ssh -i ~/.ssh/rpi-tunnel-key.pem ubuntu@100.64.0.0 -t "ssh -p 2222 a528fe2@localhost"

Understanding the -t Flag

The -t flag forces pseudo-terminal allocation. Required for interactive sessions when you're running a command on a remote server that itself needs a terminal (like nested SSH). Without it, you'd get weird behavior or hangs.

Method 3: Streamlined SSH Config (Recommended)

Configure SSH for effortless access. On your local machine:

1vim ~/.ssh/config

Add these sections (press i, paste, Esc :wq):

1Host ec2-tunnel
2HostName 100.64.0.0
3User ubuntu
4IdentityFile ~/.ssh/rpi-tunnel-key.pem
5
6Host rpi
7HostName localhost
8Port 2222
9User a528fe2
10ProxyCommand ssh -i ~/.ssh/rpi-tunnel-key.pem -W localhost:2222 ubuntu@100.64.0.0

ProxyCommand Magic

ProxyCommand tells SSH how to reach the target host. The -W flag creates a tunnel for traffic forwarding. SSH connects to EC2 first, then forwards your connection through to localhost:2222. It's like a VPN but smarter.

Set proper permissions on your config:

1chmod 600 ~/.ssh/config

Now you can connect with a simple command:

1ssh rpi

Enter your Raspberry Pi password (0fa65eb3e31c), and you're in!

Next Level: Passwordless Access

After setting up key-based auth (Step 6), you won't need the password anymore—ssh rpi will connect instantly without prompting.

Step 6: Key-Based Authentication Setup

Let's eliminate password prompts by setting up SSH key authentication for your Raspberry Pi.

6.1 Generate a Key on Your Local Machine

On your computer:

1ssh-keygen -t ed25519 -f ~/.ssh/id_rpi

Skip the passphrase (press Enter) for automatic login.

6.2 Extract the Public Key

Display the public key:

1cat ~/.ssh/id_rpi.pub

Copy the output (starts with ssh-ed25519).

6.3 Add the Key to Your Raspberry Pi

Connect to your Raspberry Pi:

1ssh -i ~/.ssh/rpi-tunnel-key.pem ubuntu@100.64.0.0 -t "ssh -p 2222 a528fe2@localhost"

Enter your RPI password (0fa65eb3e31c). On the Raspberry Pi, run:

1mkdir -p ~/.ssh
2chmod 700 ~/.ssh
3echo "YOUR_PUBLIC_KEY_HERE" >> ~/.ssh/authorized_keys
4chmod 600 ~/.ssh/authorized_keys
5exit

Replace YOUR_PUBLIC_KEY_HERE with the text you copied from id_rpi.pub.

6.4 Update Your SSH Config

Open ~/.ssh/config and add the IdentityFile line to your rpi host:

1Host rpi
2HostName localhost
3Port 2222
4User a528fe2
5IdentityFile ~/.ssh/id_rpi
6ProxyCommand ssh -i ~/.ssh/rpi-tunnel-key.pem -W localhost:2222 ubuntu@100.64.0.0

Now connect without a password:

1ssh rpi

You're All Set!

The command ssh rpi now connects you instantly to your Raspberry Pi from anywhere in the world—no passwords, no friction, just seamless access.

Monitoring and Diagnostics

Checking Status on Raspberry Pi

Verify the tunnel service status:

1sudo systemctl status reverse-tunnel.service

Confirm the SSH tunnel process is running:

1ps aux | grep "ssh.*tunnel@100.64.0.0"

Verifying Port on EC2

Connect to EC2 and check that port 2222 is listening:

1sudo ss -tulpn | grep 2222

You should see a line showing LISTEN state with sshd.

Restarting the Tunnel

If the tunnel hangs or becomes unstable:

1sudo systemctl restart reverse-tunnel.service

Live Log Monitoring

Watch the service logs in real-time:

1sudo journalctl -u reverse-tunnel.service -f

Press Ctrl+C to exit the log viewer.

Handy Monitoring Commands

systemctl is-active reverse-tunnel.service

Quick check: returns active or inactive

journalctl -u reverse-tunnel.service --since today

All logs from today

systemctl list-timers

Useful if you've set up periodic health checks via systemd timers

Troubleshooting Guide

Connection refused when connecting through tunnel

Root Cause: The tunnel isn't running or has crashed on your Raspberry Pi.

Fix: On your RPI, check sudo systemctl status reverse-tunnel.service. If it's inactive or failed, restart it: sudo systemctl restart reverse-tunnel.service

Permission denied (publickey) on connection attempt

Root Cause: Wrong key, incorrect permissions, or key not in authorized_keys.

Fix:

  • Verify key permissions: chmod 400 ~/.ssh/id_tunnel
  • Ensure public key is in ~/.ssh/authorized_keys on target host
  • Check directory permissions: ~/.ssh (700) and ~/.ssh/authorized_keys (600)

Tunnel keeps dropping and won't reconnect

Root Cause: Unstable internet connection or incorrect SSH parameters.

Fix: Verify your systemd unit includes ServerAliveInterval=60 and Restart=always. For flaky connections, increase RestartSec to 30 seconds.

Port 2222 not accessible from outside

Root Cause: EC2 Security Group doesn't allow inbound traffic on port 2222.

Fix: In AWS Console, check your instance's Security Group. You need a rule: Type: Custom TCP, Port: 2222, Source: 0.0.0.0/0.

How do I change the tunnel port?

If port 2222 is occupied or you need a different port, update it in three places:

  • In systemd unit on RPI: change -R 2222:localhost:22 to -R NEW_PORT:localhost:22
  • In EC2 Security Group: add rule for the new port
  • In SSH config on your machine: update Port 2222 to new value

Is it safe to open port 2222 to the world?

Reasonably safe since access is protected by SSH keys and your Pi's password. To harden further:

  • Disable password auth on RPI (keys only)
  • Restrict port 2222 in Security Group to your IP or IP range
  • Install fail2ban on EC2 to block brute-force attempts
  • Keep both systems updated with security patches

Architecture Summary

1.

Your Computer (anywhere worldwide) connects to EC2 via SSH using rpi-tunnel-key.pem

2.

EC2 Server (100.64.0.0) accepts the connection and forwards traffic to port 2222

3.

Through the SSH Tunnel, traffic flows to your Raspberry Pi (user a528fe2) behind your home router

Quick Reference Credentials:

  • EC2 Access: ubuntu @ 100.64.0.0, key ~/.ssh/rpi-tunnel-key.pem
  • EC2 Tunnel User: tunnel @ 100.64.0.0, password TunnelPass2025!
  • RPI Access: a528fe2 @ raspberrypi.local, password 0fa65eb3e31c
  • Magic Command: ssh rpi
Need Help with Remote Access Setup?
I help teams set up secure SSH tunnels, automate infrastructure deployment, and establish reliable remote access to IoT devices. Share your requirements—I'll propose the optimal solution.