Connect to RDS (PostgreSQL) in a Private Subnet via AWS Client VPN
Source: Dev.to
Introduction
Placing RDS in a private subnet protects it from unauthorized external access — but it also means you can no longer connect directly from your developer machine.
This article walks you through a step‑by‑step guide to securely connect to a private‑subnet RDS (PostgreSQL) instance using AWS Client VPN.
Architecture Overview
Developer PC
│
│ UDP 443 (TLS / Mutual Certificate Authentication)
▼
Client VPN Endpoint (Public Subnet)
│
│ Authorization Rule + Route Table
▼
Private Subnet
│
│ SG: Port 5432 allowed from Client CIDR
▼
Amazon RDS (PostgreSQL)
Prerequisites
| Item | Value |
|---|---|
| VPC CIDR | 10.0.0.0/16 |
| Public Subnet | 10.0.0.0/24 (for VPN association) |
| Private Subnet | 10.0.1.0/24 (for RDS) |
| Client CIDR | 10.100.0.0/22 (IP range for VPN clients) |
| DB Engine | PostgreSQL |
| Port | 5432 |
Step 1 – Create Certificates and Import to ACM
Generate server and client certificates with Easy‑RSA.
git clone https://github.com/OpenVPN/easy-rsa.git
cd easy-rsa/easyrsa3
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa build-server-full server nopass
./easyrsa build-client-full client1 nopass
Import the generated certificates into ACM
# Server certificate
aws acm import-certificate \
--certificate fileb://pki/issued/server.crt \
--private-key fileb://pki/private/server.key \
--certificate-chain fileb://pki/ca.crt \
--region ap-northeast-1
# Client certificate
aws acm import-certificate \
--certificate fileb://pki/issued/client1.crt \
--private-key fileb://pki/private/client1.key \
--certificate-chain fileb://pki/ca.crt \
--region ap-northeast-1
Important: The ACM region must match the region where you create the Client VPN endpoint.
Step 2 – Create the Client VPN Endpoint
Navigate in the console to AWS Management Console → VPC → Client VPN Endpoints → Create and fill in the following values:
| Setting | Value |
|---|---|
| Client IPv4 CIDR | 10.100.0.0/22 |
| Server Certificate ARN | ARN of the server certificate imported to ACM |
| Authentication Type | Mutual Authentication (client certificate) |
| Client Certificate ARN | ARN of the client certificate imported to ACM |
| DNS Server | 10.0.0.2 (VPC DNS) |
| Protocol | UDP |
| Split Tunnel | Enabled |
Why enable Split Tunnel?
Only traffic destined for the VPC is routed through the VPN, leaving regular internet traffic untouched and improving performance.
Step 3 – Associate a Target Network
- Open Client VPN Endpoint → Target Network Associations → Associate.
- Choose Subnet to associate: Public Subnet (10.0.0.0/24).
Step 4 – Add Authorization Rules and Routes
Authorization Rule
| Field | Value |
|---|---|
| Destination CIDR | 10.0.1.0/24 (RDS subnet) |
| Grant access to | All users |
Route
| Field | Value |
|---|---|
| Route Destination | 10.0.1.0/24 |
| Target Subnet | The subnet associated in Step 3 |
Step 5 – Configure Security Groups
Client VPN Endpoint SG
No inbound rules are required because Client VPN is a managed service. Only outbound traffic is needed:
| Direction | Protocol | Port | Target |
|---|---|---|---|
| Outbound | All | All | 0.0.0.0/0 |
RDS Security Group (Critical)
You must allow inbound traffic from the Client CIDR to the RDS SG:
| Direction | Protocol | Port | Source |
|---|---|---|---|
| Inbound | TCP | 5432 | 10.100.0.0/22 (Client CIDR) |
This is the most important step. Without this rule, the VPN connection will never reach the database.
Step 6 – Prepare the Client Configuration File
- Download the
.ovpnfile: Client VPN Endpoint → Download Client Configuration. - Append the client certificate and private key to the end of the file.
# View certificate contents (optional)
cat pki/issued/client1.crt
cat pki/private/client1.key
Add the following blocks to the bottom of the downloaded .ovpn file:
-----BEGIN CERTIFICATE-----
(Paste the contents of client1.crt here)
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
(Paste the contents of client1.key here)
-----END PRIVATE KEY-----
Step 7 – Connect via VPN and Verify RDS Access
Connect to the VPN
# Using the OpenVPN CLI
sudo openvpn --config downloaded-client-config.ovpn
# Or use the AWS VPN Client (GUI)
Verify Connectivity
# Check port reachability
nc -zv mydb.xxxxxx.ap-northeast-1.rds.amazonaws.com 5432
# Expected output:
# Connection to mydb... 5432 port [tcp/postgresql] succeeded!
Connect to PostgreSQL
psql \
-h mydb.xxxxxx.ap-northeast-1.rds.amazonaws.com \
-U postgres \
-d mydb \
-p 5432
If successful, you’ll see:
psql (15.x)
SSL connection (protocol: TLSv1.3, ...)
Type "help" for help.
mydb=#
Verify VPC DNS Settings
(Continue with any additional DNS verification steps you need here.)
DS endpoint hostname resolution requires proper VPC DNS configuration
VPC → Settings
| Setting | Value |
|---|---|
| DNS Resolution | Enabled |
| DNS Hostnames | Enabled |
Set the VPC DNS address (e.g., 10.0.0.2) as the DNS server in the Client VPN endpoint settings so that RDS endpoint names resolve correctly from the client.
Troubleshooting
| Symptom | What to Check |
|---|---|
| Connection times out | Is port 5432 from the Client CIDR allowed in the RDS security‑group inbound rules? |
| DNS resolution fails | Is the VPC DNS (subnet base + 2) set as the DNS server on the VPN endpoint? |
| VPN itself won’t connect | Does the ACM certificate region match the Client VPN endpoint region? |
| VPN connected but can’t reach RDS | With Split Tunnel enabled, is 10.0.1.0/24 added to the route table? |
| Authorization rule error | Is the Client CIDR 10.100.0.0/22 included in routes and authorization rules? |
Summary
| Component | Configuration | Key Point |
|---|---|---|
| Client VPN Endpoint SG | Outbound only | No inbound rules needed |
| RDS SG | Inbound port 5432 | Source = Client CIDR |
| Authorization Rule | Allow private subnet CIDR | — |
| Route Table | Add private subnet CIDR | — |
| Split Tunnel | Enabled | Only VPC traffic goes through VPN |
Common misconception: You need to open inbound UDP 443 on the Client VPN endpoint’s security group. You don’t. What matters is allowing the Client CIDR on the destination resource (RDS) security group.