Sitemap

Secure Access to MySQL Port via SSH Tunnel

5 min readSep 15, 2025
Press enter or click to view image in full size

What Is an SSH Tunnel?

In modern cloud environments, exposing databases directly to the internet is a serious security risk. For this reason, database servers are typically placed inside private subnets. However, this makes external access harder.

This is where SSH Tunnel (Port Forwarding) comes in. It lets us open a secure “tunnel” through a bastion host to reach resources in a private subnet. In other words, we establish an encrypted connection — via the bastion host — to a database without a public IP.

✅ Advantages

  • Provides access without assigning a public IP.
  • Encrypts traffic for better security.
  • Minimizes the attack surface.

In this lab, we will set up an SSH Tunnel from a bastion host to an RDS MySQL database and connect using both a GUI tool (like DBeaver) and the terminal.

🎯 Goal

  • Provide secure access to a MySQL instance in a Private Subnet via a bastion host.
  • Connect to the database without exposing it to the public network.

🛠 Steps

Architecture Components

  • Bastion EC2 (Public Subnet, SG: 22/tcp)
  • Database-1 (RDS MySQL) (Private Subnet, SG: 3306/tcp → allowed only from Bastion SG)
[Client PC]

│ SSH Tunnel (Port 22)

[Bastion Host - Public Subnet]

│ Internal Network (Port 3306)

[RDS MySQL - Private Subnet]

Creating the Bastion Host

EC2 → Instances → Launch an instance

  • Name: Bastion Host
  • Instance type: t2.micro
Press enter or click to view image in full size
Press enter or click to view image in full size

Key Pair

  • Create a new key pair: ec2_ssh_key
  • Type: RSA
  • Format: .pem
Press enter or click to view image in full size
  • Download the file to your computer.

Save the key file to your computer.

Network settings → Edit

  • VPC: default
  • Subnet: default
  • Availability Zone: default
  • Auto-assign public IP: Enable
  • Firewall (SG): Create a new security group
  • Security group name: Basiton_SG
  • Description: Security group for Basiton_SG
  • Rules:
  1. SSH → Source: Anywhere (0.0.0.0/0)
Press enter or click to view image in full size

Click Launch instances; your bastion server will be ready in a few minutes.

Press enter or click to view image in full size

Test connection to the bastion:

ssh -i ec2_ssh_key.pem ec2-user@<BastionPublicIP>
chmod 400 ec2_ssh_key.pem
ssh -i ec2_ssh_key.pem ec2-user@54.88.146.50
Press enter or click to view image in full size

Creating the MySQL Server (RDS)

Aurora and RDS → Create a database

Press enter or click to view image in full size
  • Choose a database creation method: Standard create
  • Engine options: MySQL
Press enter or click to view image in full size
  • Editions: MySQL Community
  • Templates: Dev/Test
Press enter or click to view image in full size
  • Availability and durability: Single-AZ DB instance deployment (1 instance)
Press enter or click to view image in full size

Settings

  • DB instance identifier: database-1
  • Credentials Settings
  • Master username: admin
  • Credentials management: Self managed
  • Password: Set your own password.
Press enter or click to view image in full size

Instance configuration

  • DB instance class → Burstable classes (includes t classes)
  • Instance type: db.t3.micro
Press enter or click to view image in full size

Storage

  • Storage type: default
  • Allocated storage: 20
Press enter or click to view image in full size

Connectivity → Connect to an EC2 compute resource

  • EC2 instance: Bastion host
  • Network type: IPv4
  • Virtual private cloud (VPC): default
Press enter or click to view image in full size
  • DB subnet group: Automatic setup
  • Public access: No
  • VPC security group (firewall): Create new
  • New VPC security group name: Mysql
Press enter or click to view image in full size

Accept all other default settings and click Create database.
👉 Wait until Database Status becomes Available.

Press enter or click to view image in full size

In the AWS Console, click database-1 to prepare for connection to the database:

Press enter or click to view image in full size

👉 Note the RDS endpoint address.

Connecting to MySQL via SSH Tunnel

You can connect to MySQL over an SSH tunnel using tools like DBeaver (https://dbeaver.io/download/) or MySQL Workbench (https://dev.mysql.com/downloads/workbench/).

🔹 With DBeaver

  • Connection Settings → SSH
  • Host/IP: Bastion Public IP
  • User Name: ec2-user
  • Authentication method: Public key
  • Add bastion host SSH key: ec2_ssh_key.pem
  • Click Test tunnel connection to verify.
Press enter or click to view image in full size

The SSH tunnel from the Bastion Host to RDS MySQL has been established successfully.

Press enter or click to view image in full size

Now let’s configure the RDS MySQL connection:

  • Connection Settings → Main
  • Server Host: RDS Endpoint
  • Username: admin
  • Password: your password
  • Click Test Connection to connect to RDS MySQL.
Press enter or click to view image in full size

Connection successful.

Press enter or click to view image in full size

We created a database named Hakan.

Press enter or click to view image in full size

🔹 From the Terminal

SSH Tunnel (local port forward):
Create an SSH tunnel from your local machine:

ssh -i ec2_ssh_key.pem -L 3306:<PrivateDBIP>:3306 ec2-user@<BastionPublicIP>
ssh -i ec2_ssh_key.pem -L \
3306:database-1.c4t40ua0c47v.us-east-1.rds.amazonaws.com:3306 \
ec2-user@54.88.146.50

Connect to MySQL:

mysql -h 127.0.0.1 -P 3306 -u admin -p
Press enter or click to view image in full size

🧹 Cleanup

To avoid ongoing costs after completing the lab:

  • Bastion Host → Terminate
  • RDS MySQL → Delete

--

--

No responses yet