Securely connecting remote users or services to your private AWS resources is a critical task for any cloud infrastructure. AWS Client VPN offers a managed, scalable solution to bridge this gap, but ensuring that only authorized clients can connect is paramount. This guide will walk you through setting up a robust and secure VPN using one of the strongest authentication methods available: mutual authentication (mTLS).
Unlike simpler authentication schemes, mutual authentication requires both the server (the AWS VPN endpoint) and the client (your remote machine) to cryptographically prove their identities to each other using digital certificates. This creates a zero-trust security posture where trust is never assumed, ensuring that only devices possessing a valid, unrevoked certificate can even initiate a connection. It eliminates the risks of compromised passwords and provides granular, certificate-based control over access.
In this step-by-step guide, we will cover the entire process, from generating your own Certificate Authority (CA) to connecting a Linux client. We will:
By the end, you will have a fully functional and secure VPN, allowing your remote systems to privately access resources within your VPC without exposing them to the public internet. Let’s get started.
Security Notes:
--passin in Easy-RSA).Use Easy-RSA to create a CA, server cert, and client cert. This is done on your admin machine.
git clone https://github.com/OpenVPN/easy-rsa.git
cd easy-rsa/easyrsa3
./easyrsa build-ca):
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa --subject-alt-name=DNS:server build-server-full server nopass
./easyrsa build-client-full vps1 nopass
Output files:
pki/ca.crtpki/issued/server.crt, pki/private/server.keypki/issued/vps1.crt, pki/private/vps1.keySecurely back up the CA key—it’s needed for future certs or revocations.
Import only the server cert and CA chain to ACM in the same region as your Client VPN endpoint. The client cert stays local.
server.crtserver.key (PEM format, unencrypted)ca.crtFrom the directory with the files:
aws acm import-certificate --certificate fileb://server.crt --private-key fileb://server.key --certificate-chain fileb://ca.crt
Copy the returned ARN.
Optional: If using separate CAs or for explicit client auth, import the client cert similarly and note its ARN. For shared CA, reuse the server ARN for client auth.
172.27.0.0/22 (must not overlap VPC CIDR).172.31.0.2 for default VPCs).pending-associate).172.31.0.0/16 targeting associated subnet). For internet access, add 0.0.0.0/0.172.31.0.0/16) or specific subnets/DBs.172.31.0.2/32).State changes to available after first association.
Use OpenVPN on Linux (AWS also provides a native client, but OpenVPN is standard).
sudo apt update && sudo apt install -y openvpn
Download the .ovpn config from AWS Console > Client VPN endpoint > Download client configuration.
/etc/openvpn/client/ca.crt (from pki/ca.crt)/etc/openvpn/client/vps1.crt (from pki/issued/vps1.crt)/etc/openvpn/client/vps1.key (from pki/private/vps1.key)client.ovpn in /etc/openvpn/client/client.ovpn to reference files:
ca /etc/openvpn/client/ca.crt
cert /etc/openvpn/client/vps1.crt
key /etc/openvpn/client/vps1.key
sudo openvpn --config /etc/openvpn/client/client.ovpn --daemon
sudo mv /etc/openvpn/client/client.ovpn /etc/openvpn/client.conf
sudo systemctl enable --now openvpn@client
sudo systemctl status openvpn@client
(Routes to VPC are automatically pushed; Docker containers on the host use host routing.)
For multiple clients, generate unique certs per VPS/user. This setup ensures secure, private access without public endpoints. Test thoroughly before production.