A set of Ansible playbooks & roles to setup a small VPN with Wireguard and dnsmasq. Totally suited to my personal setup, open sourced for inspiration.
I enjoy the luck of having a public IPv4 address from my ISP. With that I can setup a small personal VPN to interconnect my personal devices while on the road. Something, that public VPNs doesn't give you!
I use small, palm-sized PC as a VPN (and DNS) server. Machine is running Ubuntu server 22.04 installation, using "Manual server installation" method.
In the previous incarnation of the VPN, I set up everything by hand. This time I want the machine to be controlled by Ansible.
Internet
┌─┐
└┼┘
│
│
│ │ │ │ ┌──────────┐
└─┼─┘ │ │ │
│ │ │ ┌───┐ │
WiFi│ WAN│ │LAN│ │ │
│ ┌┼┐ ┌┼┐ ┌┼┐ │ │
│ ┌──┴─┴────┴─┴─┴─┴┐ │ │
└─┤ Router │ │ │
│ │ │ │
└────────────────┘ │ │
│ │
┌────┘ │
192.168.0.9 │ │
┌┼┐ │
┌──────────┴─┴─┐ │
│ VPN server │ │
│ (ecs-liva) │ │
└──────────────┘ │
│
│
____________ ┌┼┐
│ ________ │ ┌────┴─┴──┐
│ │Work │ │ │ ┌─────┐ │
│ │machine │ │ │ │NAS │ │
│ (polaris)│ │ │ (lilith)│
│ │________│ │ │ │ │ │
│____________│ │ ├─────┤ │
/ [][][][][] \ │ ├─────┤ │
/ [][][][][][] \ │ ├─────┤ │
( [][][____][][] ) └─┴─────┴─┘
\______________/
Hostnames in (parentheses)
Router is configured to reserve local LAN address 192.168.0.9
for the VPN server and forward public port 51280
to it. This makes the VPN server accessible from public Internet using my public IP address.
Use-cases like watching movies or accessing files from the NAS, while outside the apartment, are possible.
- Prepare Ubuntu server 22.04 installation on the VPN server machine. You don't need to setup the swap partition or swap file during the installation (we'll do that via Ansible).
- Install
openssh-server
onto VPN server and setup SSH access using SSH key(s) (ssh-copy-id
is your friend).
- Ansible (tested v5.2, v5.3 & v8.4)
- OpenSSL cli, to generate "crypto rands"
- Wireguard cli, to generate VPN client(s) key-pairs
- name of the VPN:
wirevpn
- Subnet
10.2.0.0/24
(configurable) - Static assignment of IP addresses to VPN clients (configured & versioned in this repository)
- VPN server:
10.2.0.1
- NAS:
10.2.0.10
- work machine:
10.2.0.11
- any other device(s) (smartphone, tablet), continuation of this series
- VPN server:
- Important devices (work machine, NAS) accessible via assigned DNS names, no need to remember IP addresses 💡
- VPN server:
ecs-liva.wirevpn
- work machine:
polaris.wirevpn
- NAS:
lilith.wirevpn
- VPN server:
We will store sensitive data (private keys, pre-shared keys) into Ansible vault. That way, these sensitive data can be versioned safely.
-
Generate Ansible vault password file:
openssl rand -base64 32 > vault_pass
-
Generate preshared key file(s) for each VPN client (except VPN server)
openssl rand -base64 32 > .data/polaris.presharedkey
-
Generate wireguard key-pair for each device (except VPN server)
wg genkey | tee .data/polaris.privkey | wg pubkey > .data/polaris.pubkey
-
Create & edit Ansible vault
ansible-vault create group_vars/wireguard_servers/vault.yml
Setup content of the vault by looking on
group_vars/wireguard_servers/vault.yml [example]
. Fill all the needed values for VPN clients from credentials generated above ⬆Don't lose generated
vault_pass
file! You will lose your vault if you losevault_pass
file used for creating it viaansible-vault create
command.
If you ever need to update contents of Ansible vault, use command bellow (original vault_pass
file must be present!):
ansible-vault edit group_vars/wireguard_servers/vault.yml
-
Finish VPN configuration by editing
group_vars/wireguard_servers/vars.yml
-
Create the inventory file by copying
@inventory [example]
into@prod
and editing its contentLearn more about inventories in Ansible documentation.
Playbooks must be executed in this particular order:
-
First we execute
postinstall
playbook. It will perform couple of tasks:- install latest Ubuntu updates
- setup a swapfile
- harden SSH server configuration (disable password authentication)
ansible-playbook playbooks/postinstall.yml -i @prod
You can run system update on VPN server anytime, by limiting executed postinstall tasks via tag
ansible-playbook playbooks/postinstall.yml -i @prod -t upkeep
-
Install and setup Wireguard
ansible-playbook playbooks/wireguard.yml -i @prod
Wireguard is now up & running on VPN server machine, ready to accept client(s) connection.
-
Install and setup dnsmasq
ansible-playbook playbooks/dnsmasq.yml -i @prod
Make sure you configure the main LAN adapter (interface) correctly in
group_vars/dns_servers.yml
! You can list all network interfaces on VPN server by runningip addr
command.
After executing all three playbooks, please restart the VPN server machine.
By executing the playbooks against the inventory file, you setup and configured Wireguard and dnsmasq on VPN server machine. You also need to configure your VPN clients. Part of the configuration is located in group_vars/wireguard_servers/vars.yml
. However you need to create .conf
files, that can be imported into Wireguard GUI clients, that will be connecting to your VPN server.