DEV Community

OCI - Connecting to an OCI Always Free MySQL DB System: Installing MySQL Shell and Building a "Poor Man's VPN"

{ Abhilash Kumar Bhattaram : Follow on LinkedIn }

If you've spun up an Oracle Cloud Infrastructure (OCI) Always Free MySQL DB System, you've probably noticed something deliberate about how it's configured: it only exposes a private IP address.

For demostration purposes I have created a OCI MySQL DB System with a public subnet but it exposes only the Private Subnet and this is how it must be designed from cloud a security standpoint .

Private IP Only in Public Subnet

There's no public endpoint to point a client at from your laptop. That's a good security default — but it means you need a way to reach a database that, by design, nothing outside its own network can see.

This post walks through two things:

  1. Installing MySQL Shell on an Oracle Linux compute instance sitting inside the same Virtual Cloud Network (VCN) as the DB System, so you can connect directly from there.
  2. Building an SSH tunnel from your laptop, through that compute instance, into the private DB endpoint — a lightweight substitute for a full VPN client that gets the job done with a single command.

Part 1 — Installing MySQL Shell on Oracle Linux

MySQL Shell isn't part of Oracle Linux's default repositories, so the first step is adding MySQL's own Yum/DNF repository.

Add the MySQL repository

Oracle Linux 10 is supported directly, and MySQL 8.4 LTS is the current default release line (8.0 is now the legacy series):

sudo dnf install -y https://dev.mysql.com/get/mysql84-community-release-el10-1.noarch.rpm
Enter fullscreen mode Exit fullscreen mode

Install MySQL Shell

The tools (including mysql-shell) live in a subrepository that isn't always enabled by default:

sudo dnf config-manager --enable mysql-tools-community
sudo dnf install -y mysql-shell mysql-community-client
Enter fullscreen mode Exit fullscreen mode

A quick note on GPG keys

MySQL's signing key rotates periodically, and if the copy your system has cached has expired, dnf will refuse the install with a NOTTRUSTED error even after you import a fresh key — because rpm itself re-validates against whatever's already sitting in its trust database. If you hit this:

# Find the expired key package
rpm -qa gpg-pubkey*

# Remove it
sudo rpm -e gpg-pubkey-<id>-<hash>

# Retry, skipping the (now moot) signature check
sudo dnf install -y --nogpgcheck mysql-shell
Enter fullscreen mode Exit fullscreen mode

Once that completes, confirm it's working:

mysqlsh --version
Enter fullscreen mode Exit fullscreen mode

Part 2 — Connecting Directly from the Compute Instance

If your compute instance is in the same VCN as the DB System, you can connect right away using the private endpoint shown in the OCI console (DB System → Connections → Primary endpoint):

mysqlsh --uri admin@10.10.3.3:3306
Enter fullscreen mode Exit fullscreen mode

You'll be prompted for the password interactively. A successful connection here confirms two things: your compute instance has network line-of-sight to the DB System, and the security list/NSG rules allow port 3306 between them. That matters, because it's the foundation the next step depends on.

Connect from Compute Instance


Part 3 — The "Poor Man's VPN": SSH Tunneling from Your Laptop

Here's the core problem: MySQL Workbench (or any client) running on your laptop has no route to 10.10.3.3 — that address only means something inside the VCN. Your laptop isn't in the VCN. A full OCI VPN Connect / IPSec setup would solve this properly, but for a single developer needing occasional access, that's a lot of infrastructure for a small problem.

SSH local port forwarding solves it with one command, using a resource you already have: your compute instance, which already has a legitimate route to the database.

The idea in one sentence

Open an SSH connection to the compute instance, and tell SSH to forward a local port on your laptop through that encrypted connection to the DB System's private port on the other side.

The diagram

Your laptop never talks to 10.10.3.3 directly — it can't. It talks to 127.0.0.1:3306 on itself. SSH quietly relays that traffic, encrypted, to the compute instance, which then makes the final unencrypted hop to the database — a hop it's allowed to make because it lives inside the VCN.

On macOS/Linux — a single command

ssh -L 3306:10.10.3.3:3306 opc@<compute-instance-public-ip>
Enter fullscreen mode Exit fullscreen mode

Breaking that down:

Piece Meaning
-L "local forward" — open a port on my machine
3306 the port on your laptop you'll connect to
10.10.3.3:3306 the destination, resolved from the compute instance's perspective
opc@<public-ip> the SSH login to the compute instance itself

Add -N if you don't need an interactive shell alongside the tunnel, and -f to background it:

ssh -f -N -L 3306:10.10.3.3:3306 opc@<compute-instance-public-ip>
Enter fullscreen mode Exit fullscreen mode

Leave that session running — the tunnel only exists while the SSH connection is alive.

On Windows — the same thing, via PuTTY

PuTTY does exactly the same job through its GUI:

  1. Session: enter the compute instance's public IP, port 22.
  2. Connection → SSH → Auth → Credentials: browse to your private key (convert a .pem to .ppk with PuTTYgen first if needed).
  3. Connection → SSH → Tunnels: Source port 3306, Destination 10.10.3.3:3306, leave it on Local, click Add.
  4. Go back to Session, save it under a name, and click Open.

The PuTTY window that opens is your tunnel — as long as it's connected, the forward is live.

Pointing your client at the tunnel

Whether you built the tunnel with ssh -L or PuTTY, MySQL Workbench's connection settings look the same:

  • Connection Method: Standard TCP/IP (not "over SSH" — the tunnel is already handling that separately)
  • Hostname: 127.0.0.1
  • Port: 3306
  • Username/Password: your DB System credentials

From Workbench's point of view, it's just talking to a MySQL server on your own machine. It has no idea the traffic is actually crossing into an OCI VCN on the other side of an SSH session.

Below is my MySQL Workbench conncting through localhost - 127.0.0.1:3306 ( mylaptop's local port 3306 )


Why "Poor Man's VPN"?

A real VPN gives you full network-layer access to everything in the remote network, routed transparently, often for many users at once. An SSH tunnel gives you exactly one thing: a single port, forwarded to a single destination, for as long as your terminal session stays open. It's narrower, but it's also zero-config on the OCI side beyond the SSH access you already have — no VPN gateway, no IPSec setup, no extra always-on infrastructure. For reaching a private database from your own laptop during development, it's usually all you need.

NOTE : OCI includes Bastion Service for this kind of requirement, but it was not allowed as free service ( atleast in my region )


Summary

  • MySQL Shell installs cleanly on Oracle Linux via MySQL's Yum repo, once you handle the GPG key rotation quirk.
  • A compute instance inside the same VCN as your Always Free DB System can connect directly using its private IP.
  • Your laptop can't reach that private IP on its own — but an SSH tunnel through the compute instance closes that gap in one line, giving you full MySQL Workbench access without standing up a real VPN.

But in real life tunnel forwarding database IP's will not be used and once needs to a jump box , this blog should help developers and DBA's get started on learning MySQL.

To know more about OCI Always free resources , check here.

How Nabhaas helps you

If you’ve made it this far, you already sense there’s a better way — in fact, you have a way ahead.

If you’d like Nabhaas to assist in your journey, remember — TAB is just one piece. Our Managed Delivery Service ensures your Oracle operations run smoothly between patch cycles, maintaining predictability and control across your environments.

TAB - Whitepaper ,
download here

Managed Delivery Services - Whitepaper ,
download here

Top comments (0)