How to connect Amazon EC2 using SSH Local Port Forwarding
Use Case
Accessing services not available on the public internet: By tunneling traffic through an SSH connection, you can access internal services or websites that are not exposed to the public internet for security reasons.
SSH (Secure Shell) port forwarding(SSH tunneling) is a technique that allows you to securely access and forward traffic from one network to another through an encrypted tunnel. It enables you to connect to a server or service on a remote network, while keeping the actual connection details (such as IP address and port number) private and secure.
SSH Local Port Forwarding
SSH local port forwarding is used to forward a port from the SSH client to the SSH server. The SSH client listens for connections on a configured port, and when it receives a connection, it tunnels the connection to the SSH server. The SSH server connects to the configured host with the destination port.
Here’s how it works:
- You establish a secure SSH connection between your local machine and Amazon EC2 instance using a SSH client.
- Once connected, you can request a “tunnel” or “forwarded connection” to a specific host and port on the remote network. This is done by specifying the -L option followed by the local port number and the remote host and port number, separated by a colon.
Syntax: ssh -L <LOCAL_PORT>:<REMOTE_HOST>:<REMOTE_PORT> <GATEWAY>
Breaking Down SSH Local Port Forwarding for AWS
Let’s break down SSH local port forwarding for AWS with the following sample command.
# SSH Command
ssh -i "us-east-1-key.pem" -N -L 8888:localhost:8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
- -i “us-east-1-key.pem”: specifies the identity key for public key authentication
# Remaining Command
-N -L 8888:localhost:8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
- -N: disables remote commands. Because we are portforwarding port 8888 to localhost, we don’t care about remote commands.
# Remaining Command
-L 8888:localhost:8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
👉 The key command is -L.
- -L: Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side.
Formatting Specification for -L Parameter
- -L [bind_address:]port:host:hostport
- -L [bind_address:]port:remote_socket
- -L local_socket:host:hostport
- -L local_socket:remote_socket
Note: an explicit bind_address may be used to bind the connection (port) to a specific address.
# Remaining Command
-L 8888:localhost:8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
We can finally break down the remaining portion of the `ssh`.
- ‘8888:localhost’ means that you bind the address 8888 to localhost. This is the local socket/port from which we forward. This of this portion of the command specifying the sender.
# Remaining Command
8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
- The remaining ‘8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com’ is the remote port of the remote connection to which we want to forward to. Think of this portion specifying the receiver.
Thus, we have completely broken down the ssh command!
Scenario: self-managed JupyterLab running on Amazon EC2 instance
You are running self-managed Jupyterlab on Amazon EC2 instance with DLAMI(Deep Learning AMI). Amazon EC2 Security Group only allows inbound SSH traffic.
Let’s establish a secure SSH connection to Amazon EC2 instance using SSH local port forwarding.
Step 1 — Establish ssh access to your Amazon EC2 instance and start JupyterLab service
# SSH connection to Amazon EC2 instance
ssh -i "us-east-1-key.pem" ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
# Start JupyterLab
jupyter lab --notebook-dir=/home/ubuntu
Step 2 — Establish SSH local port forwarding from your machine in a separate SSH connection
# SSH local port forwarding for JupyterLab
ssh -i "us-east-1-key.pem" -N -L 8888:localhost:8888 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
This command will forward traffic from your local machine’s port 8888 to Amazon EC2’s localhost port 8888, allowing you to access the JupyterLab service through your local browser.
[Note] “-N” option: Do not execute a remote command. This is useful for just forwarding ports.
Step 3 — From your local browser, get access to JupyterLab service running on Amazon EC2 using localhost
http://localhost:8888/lab
Creating SSH local port forwarding for multiple ports
# SSH local port forwarding for JupyterLab(8888)/Gradio(7860)/Streamlit(8501)
ssh -i "us-east-1-key.pem" -N -L 8888:localhost:8888 -L 7860:localhost:7860 -L 8501:localhost:8501 ubuntu@ec2-###-##-##-###.compute-1.amazonaws.com
Creating SSH local port forwarding using PuTTY in Windows
Prerequisites
Connect to your instance using PuTTY
Category: Session
- Host Name (or IP address):
instance-user-name
@instance-public-dns-name
- Port: 22
- Connection type: SSH
Category: Connection > SSH > Auth > Credentials
- Private key file for authentication > Browse > Select private key file (.ppk)
- Save the session information: Category > Session > Save Sessions > Save
Reference: Connect to your Linux instance from Windows with PuTTY
PuTTY SSH Local Port Forwarding
Category > Connection > SSH > Tunnels
- Local ports accept connections from other hosts: Check
- Remote ports do the same (SSH-2 only): Check
- Add new forwarded port with source port and destination port