Provisioning and configuration repository to manage Wireguard AWS VPN Gateway setup.
This repository demonstrates how to setup a VPN gateway for an AWS VPC.
Key features:
- Split tunnel setup: Only Wireguard/VPC traffic is being forwarded to the gateway.
- Custom DNS: Resolve AWS private DNS entries locally. Setup
.private
records for wireguard hosts.
- Ansible 2.x
- Terraform 1.0.x
- Wireguard Tools
- AWS Account
We're setting up a brand new VPC in this repository, if you have an existing one you will need to modify the terraform files accordingly.
You can check if you have all components installed:
ansible-playbook --version
terraform --version
wg --help
On Mac:
brew install ansible
brew install terraform
brew install wireguard-tools
On Ubuntu:
sudo apt update
sudo apt install -y gnupg software-properties-common curl
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt update
sudo apt install -y ansible terraform wireguard resolveconf
This demo repository has a few defaults:
Name | Value | Description |
---|---|---|
Wireguard CIDR | 10.10.0.0/24 |
VPN network range |
AWS Region | us-east-1 |
AWS Region |
AWS CIDR | 10.0.0.0/16 |
AWS VPC network range |
Clone the source repository:
git clone https://github.com/sosedoff/wireguard-aws-gateway
cd wireguard-aws-gateway
Next, run the initialization script:
./scripts/init
Example output:
Generating a new SSH key: ./ansible/keys/ssh
Generating public/private rsa key pair.
Your identification has been saved in ./ansible/keys/ssh.
Your public key has been saved in ./ansible/keys/ssh.pub.
Generating a new Wireguard key: ./ansible/keys/wireguard
Generating a new Wireguard client key: ./ansible/keys/wireguard_client
Creating Terraform variables file: ./terraform/terraform.tfvars
Creating Ansible variables file: ./ansible/vars.yml
The init script will create the following files that you can inspect and modify as needed:
File | Description |
---|---|
./ansible/keys/wireguard |
Server Wireguard private key (+ pubkey) |
./ansible/keys/wireguard_client |
Client Wireguard private key (+ pubkey). |
./ansible/keys/ssh |
Server SSH private key (+ pubkey). |
./terraform/terraform.tfvars |
Terraform variables file. |
./ansible/vars.yml |
Ansible playbook variables. |
You must replace AWS credentials in the terraform.tfvars file before moving onto next step
Terraform will create all required infrastructure components in AWS.
All required configuration has already been created for us by the init script, let's have a quick look:
aws_access_key = "XXX"
aws_secret_key = "XXX"
region = "us-east-1"
vpc_cidr = "10.0.0.0/16"
vpc_public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
gateway_network = "10.10.0.0/24"
gateway_instance_type = "t3.micro"
It's time to provision the infrastructure, run the script:
./scripts/provision
If you have correctly configured Terraform and all variables look good, you'll be prompted to confirm the execution plan. Enter yes
when ready.
Execution takes a minute and successful output might look something like:
Initializing modules...
Initializing the backend...
Initializing provider plugins...
...
Apply complete! Resources: X added, 0 changed, 0 destroyed.
Outputs:
gateway_public_ip = "123.456.789.000"
Great! We have provisioned an EC2 instance, with public (persistent) IP seen above.
Ansible will configure all packages (Wireguard/CoreDNS) on our EC2 instance.
Example configuration has also been created by the init script. Let's have a look:
gateway:
# Server private/public wireguard keys.
private_key: "XXX"
public_key: "XXX"
# Name of the tunnel network interface.
tunnel: "wg0"
# Name of the network interface to forward traffic to.
# Usually it's `eth0` but has a different default on AWS.
interface: "ens5"
# VPN network range. Should not overlap with VPC CIDR!
network: "10.10.0.0/24"
# Wireguard listen address. This is the default.
listen_port: "51820"
# Optional keepalive setting for sensitive clients.
persistent_keepalive: "60"
# List of client peers you would like to connect with.
# These keys should be privded by clients or generated with `wg` toolkit.
peers:
- name: user1
public_key: "XXX"
addr: "10.10.0.1"
coredns:
# Version of the coredns binary
version: "1.8.1"
# AWS provides a resolver on address equals to VPC base range + 2.
# If the VPC CIDR is 10.0.0.0/16 then resolver is available at 10.0.0.2.
forward_to: "10.0.0.2"
# If private zone name is provided all peers from the section above will
# get their own DNS entries, like `user1.private`, etc.
private_zone: "private"
You should be able to continue by running the configuration command:
./scripts/configure
Configuration process might take a minute or two and should look like:
PLAY [all] *****************************************************************************************************************************************************
TASK [setup] ***************************************************************************************************************************************************
ok: [wireguard]
TASK [Update package cache] ************************************************************************************************************************************
changed: [wireguard]
TASK [Install basic packages] **********************************************************************************************************************************
ok: [wireguard]
TASK [Enable IPV4 forwarding] **********************************************************************************************************************************
ok: [wireguard]
TASK [Check if CoreDNS is installed] ***************************************************************************************************************************
ok: [wireguard]
What we have as a result of all previous steps:
- VPN gateway running Wireguard at
123.456.789.000
on port51820
. - VPN network
10.10.0.0/24
- DNS Server running on
10.10.0.0
- Single client configured on
10.10.0.1
- Forwarding traffic to AWS VPC
10.0.0.0/16
To test out our VPN gateway setup you'll need to configure your local Wireguard client.
Get the configuration with:
./scripts/client-config
You can use a Mac or a Linux client to test it out.
Final step in this setup is to make sure our tunnel and configuration works.
Activate your Wireguard VPN connection. Now, let's verify private IP access / DNS resolution really works:
./scripts/verify
All the steps above should be successful and should always return the same ip: 10.0.x.x
. If you happen to have any other resources in your VPC, you can ping them (or resolve their names) similarly.
The script also verified that accessing domain records like user1.private
works. Those will resolve to an address in the VPN range, like 10.10.0.1
.