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 assigned to VPN clients) |
| DB Engine | PostgreSQL |
| Port | 5432 |
Step 1: Create Certificates and Import to ACM
Generate server and client certificates using 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
Go to AWS Management Console → VPC → Client VPN Endpoints → Create
| Setting | Value |
|---|---|
| Client IPv4 CIDR | 10.100.0.0/22 |
| Server Certificate ARN | Server certificate imported in ACM |
| Authentication Type | Mutual Authentication (client certificate) |
| Client Certificate ARN | Client certificate imported in 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. This avoids impacting regular internet traffic and improves performance.
Step 3: Associate a Target Network
Client VPN Endpoint → Target Network Associations → Associate
Subnet to associate: Public Subnet (10.0.0.0/24)
Step 4: Add Authorization Rules and Routes
Authorization Rule
Client VPN Endpoint → Authorization Rules → Add Authorization Rule
| Field | Value |
|---|---|
| Destination CIDR |
10.0.1.0/24 (RDS subnet) |
| Grant access to | All users |
Add Route
Client VPN Endpoint → Route Table → Create 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 needed for the Client VPN endpoint SG.
Because Client VPN is a managed AWS service, you do not need to add an inbound rule for UDP 443 to its security group. Only outbound rules are required.
| 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 security group.
| Direction | Protocol | Port | Source |
|---|---|---|---|
| Inbound | TCP | 5432 |
10.100.0.0/22 (Client CIDR) |
This is the most important step. Without allowing port 5432 from the Client CIDR in the RDS security group, the connection will never succeed — no matter how correctly the VPN is configured.
Step 6: Prepare the Client Configuration File
Download the .ovpn File
Client VPN Endpoint → Download Client Configuration
Append Certificate Information
Add the client certificate and private key to the end of the downloaded .ovpn file.
# View certificate contents
cat pki/issued/client1.crt
cat pki/private/client1.key
# Append to the end of the .ovpn file
<cert>
-----BEGIN CERTIFICATE-----
(Paste the contents of client1.crt here)
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
(Paste the contents of client1.key here)
-----END PRIVATE KEY-----
</key>
Step 7: Connect via VPN and Verify RDS Access
Connect to the VPN
# Using 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
# 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 the connection is successful, you'll see:
psql (15.x)
SSL connection (protocol: TLSv1.3, ...)
Type "help" for help.
mydb=#
Verify VPC DNS Settings
RDS 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 SG 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 |
A common misconception is that 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.
Top comments (0)