Deploys private OpenVPN servers quickly around the world via Amazon AWS EC2.
This project will deploy one (or more)
t3.nano private VPN servers around the world to securely route your desktop,
laptop, router or mobile traffic. The tools in this package will help you configure a private, secure docker container
with an OpenVPN environment that you can easily deploy to any number of Amazon AWS
regions around the world with just a few lines of configuration, at any time. Using
Terraform you can easily setup or destroy your OpenVPN deployments in seconds.
The goal is to create a OpenVPN certificate authority (CA) on your local machine via EasyRSA. This CA will generate a server certificate for use in OpenVPN servers that you can deploy via AWS, and generate client certificates for any machines you want to connect to those OpenVPN servers.
We will then use Terraform to deploy a docker container with the kylemanna/docker-openvpn image to a minimal Amazon AWS EC2 server to one or more AWS regions. Terraform will also update Amazon Route 53 DNS entries pointing to your deployed server(s).
You can then use the
.ovpn profiles generated by the CA on your local machine to connect to your OpenVPN servers
across the globe!
1. Install Docker
First, you will need have Docker installed on your local machine:
2. Local OpenVPN CA Configuration
Next, we'll create a Docker volume on the local machine to host the CA files.
Then, we will use the kylemanna/docker-openvpn docker image to generate a OpenVPN certificate authority (CA) with a CA root key. This CA will be responsible for generating certificates for all of your servers and clients. You won't deploy this container directly to the outside world -- it will be solely responsible for generating server certificates for your OpenVPN servers and client certificates for each of your clients, with the CA root key. These files will live in the Docker volume we created.
This is a modified process of the kylemanna/docker-openvpn Quick Start
guide where we use the local machine to generate the CA root key and
only put the CA certificate
on the deployed OpenVPN servers. The files required for the OpenVPN servers will be generated into
Configure a few environment variables.
vpn.myhost.comwith the Amazon Route 53 DNS entry you want your clients to connect to.
# Set this to the VPN server name OVPN_SERVER="vpn.myhost.com" OVPN_DATA="ovpn-data"
REM Set this to the VPN server name set OVPN_SERVER=vpn.myhost.com set OVPN_DATA=ovpn-data
Create a Docker volume
docker volume create --name $OVPN_DATA
docker volume create --name %OVPN_DATA%
Next, we'll generate the OpenVPN configuration into the
# Generates OpenVPN configs docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://$OVPN_SERVER
REM Generates OpenVPN configs docker run -v %OVPN_DATA%:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://%OVPN_SERVER%
We'll use EasyRSA to build the CA root key, certificate and other files used by the server.
# Initialize the EasyRSA PKI docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
REM Initialize the EasyRSA PKI docker run -v %OVPN_DATA%:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
Finally, we'll call
ovpn_copy_server_fileswhich will copy out the minimal files required for the OpenVPN server into
# Generates the minimal OpenVPN files necessary for clients to connect to into /etc/openvpn/server docker run --net=none --rm -t -i -v $OVPN_DATA:/etc/openvpn kylemanna/openvpn ovpn_copy_server_files # Package the files up into an archive docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn tar -cvz -C /etc/openvpn/server . > files/openvpn-server.tar.gz
REM Generates the minimal OpenVPN files necessary for clients to connect to into /etc/openvpn/server docker run --net=none --rm -t -i -v %OVPN_DATA%:/etc/openvpn kylemanna/openvpn ovpn_copy_server_files REM Package the files up into an archive docker run -v %OVPN_DATA%:/etc/openvpn --rm kylemanna/openvpn tar -cvz -C /etc/openvpn/server . > files/openvpn-server.tar.gz
Now we're all set to generate client certificates and deploy our servers.
3. Client Configuration
For each client you want to allow to connect to your OpenVPN instances, we will use
EasyRSA to generate client certificates and the
.ovpn files that can be used by OpenVPN client software.
The client certificates will end up in
$OVPN_DATA/pki/issued/ and the
.ovpn profiles will be written out to the local
CLIENTNAME=myclient docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full $CLIENTNAME nopass docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient $CLIENTNAME > $CLIENTNAME.ovpn
set CLIENTNAME=myclient docker run -v %OVPN_DATA%:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full %CLIENTNAME% nopass docker run -v %OVPN_DATA%:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient %CLIENTNAME% > %CLIENTNAME%.ovpn
Note if you're going to be deploying multiple VPN instances you'll want to modify the
.ovpn to edit the
Once the server has been configured and you have generated keys for your clients, you are ready to deploy OpenVPN servers to AWS.
We will be using Terraform to easy prepare and deploy OpenVPN servers across the globe.
They will be initialized using the certificates generated via
ovpn_copy_server_files and in the
Terraform uses configuration files to know how to configure each OpenVPN deployment. The base configuration is in
terraform.tfvars, and each deployment has its own
config-[deployment].tfvars file. For example, you could deploy
OpenVPN servers to multiple AWS regions.
First, we'll need to configure Amazon AWS:
Create an IAM user that will be responsible for deploying the EC2 instances and for modifying the Route 53 domain entries.
When you create the IAM user, you will be given a AWS Access Key and a AWS Secret Key that you will use later.
You will need to attach some permissions to this user. You may be able to attach finer-grained policies, but these should be sufficient:
Create (or use an existing) Amazon Route 53 Hosted Zone (root domain) that will host the DNS record you want updated when you deploy a server.
Note the Hosted Zone ID.
Generate (or use an existing) Private Key pair that you will use to connect (via SSH) to EC2 instances.
The easiest way to do this is via the EC2 console. Click on Key Pairs and Create Key Pair. You wil lbe given a
.pemfile with your private keys.
If you already have a Private Key, you will need to make sure it's listed in the EC2 Key Pairs console for every zone that you want to deploy OpenVPN servers to.
If you're deploying to more than one AWS zone, you will use Import Key Pair to import your
.pemto other zones.
Next, we'll need to edit a couple configuration files.
You can use the
terraform.tfvars.samplefile to get you started. Copy it to
aws_access_key = "" aws_secret_key = "" host_route_53_zone_id = "" instance_type = "t3.nano" ssh_key = "mykey.pem" ssh_key_name = "" ssh_user_name = "ec2-user"
aws_access_keyis your AWS Access Key
aws_secret_keyis your AWS Secret Key
host_route_53_zone_idis the Hosted Zone ID you will be updating for
instance_typecan be the AWS EC2 instance type you want to use. At the time of writing,
t3.nanois the cheapest instance type.
ssh_keyis the location of the
.pemfile you created
ssh_key_nameis the name of Key Pair Name in EC2
ssh_user_nameis the user name used to connect to your EC2 instance.
ec2-usershould probably be used.
config-[deployment].tfvarsfor each deployment (e.g. zone) you want to deploy to.
You can use the
config-main.tfvars.samplefile to get you started. For example, copy it to
host_name = "vpn.myhost.com" region = "us-east-2" base_image = "ami-31c7f654"
host_nameis the DNS name of this deployment
regionis the AWS region you want to deploy to
base_imageis your AMI you want to use for that region. This package assumes Amazon Linux 2.
Create Terraform Workspaces for each deployment:
For example, if you want to deploy to
terraform workspace new us-east terraform workspace new us-west terraform workspace new de
Now you're ready to deploy! The Terraform scripts will do the following:
- Configures a VPC, Internet Gateway, Routes and Subnet for this region (required if you're using
- Creates a Security Group (firewall), open to incoming SSH (22) and OpenVPN (1194)
- Launches an EC2 instance
- Once it's ready, it uploads the files in
openvpn-server.tar.gzpackage that has the OpenVPN server certificate
firstname.lastname@example.org ensure the OpenVPN runs after reboots
- Update the packages on the machine
- Install Docker
docker-openvpnas a service
- Create a docker volume for
- Start the
- Once it's ready, it uploads the files in
To deploy to a region, you simply need to switch to that workspace, then run
terraform apply with
-var-file config-[deployment].tfvars set:
terraform workspace select us-east terraform plan -var-file config-us-east.tfvars terraform apply -var-file config-us-east.tfvars terraform workspace select us-west terraform plan -var-file config-us-west.tfvars terraform apply -var-file config-us-west.tfvars terraform workspace select de terraform plan -var-file config-de.tfvars terraform apply -var-file config-de.tfvars
You can destroy (stop) a deployment via:
terraform workspace select us-east terraform destroy -var-file config-us-east.tfvars
- 2018-04-24: Initial version
- 2018-11-08: Changed to
configure_node.shfor latest Amazon Linux 2 AMI