Set up Wireguard / Pi-Hole and OpenVPN together
Tags: tutorial, linux, vpn, wireguard
Published: 2020-12-04 10:45:47

Wireguard is fairly new but already ready to replace OpenVPN. It provides a secure connection tunnel from a client to a server using public and private key authentication.

In this tutorial I will assume that you already have some basic knowledge of networking and command line.

###What will we do today? 
The other day I was struggling configuring my Wireguard instance to use Pi-Hole while also using the Cloudflare DNS and my company's DNS over a OpenVPN connection to reach the servers of the company.

As a result I decided to write my guide, based on my experience. The little graph below resume what we'll end up with.

![Graph of the network](https://dev-to-uploads.s3.amazonaws.com/i/bidwwmdjk8mct4jbbs86.png)

###Setting up Pi-Hole
As the name of the project tends to pretend, Pi-Hole is not only reserved for Raspberry Pi. You can run it on a traditional server too and that's what we're going to do.

All you need is running this simple command:
```bash
curl -sSL https://install.pi-hole.net | bash
```
If you need more information for the install, check out [this guide](https://dev.to/thomasbnt/setup-pi-hole-3gkd#install).

Once it's installed, head towards the web admin page of the Pi-Hole and go on the `Settings` page > DNS.

Here you can select which Upstream DNS servers you want to use and setup your own DNS too.
So in my case, my company DNS address is `10.51.1.1`which result in this configuration: 

![Custom Upstream](https://dev-to-uploads.s3.amazonaws.com/i/dgg1lrqrn9xwskjzvs96.png)
![Interfaces](https://dev-to-uploads.s3.amazonaws.com/i/4k947895vvpmrdbrefqu.png)
![Advanced Settings](https://dev-to-uploads.s3.amazonaws.com/i/vvn18v4brtk0u9ltxz39.png)
This config allows me to use `1.1.1.1` for general requests and `10.51.1.1` when it's linked to my company (by the domain name).

You're done with Pi-Hole for the DNS, you might want to play with it a bit to block ads correctly.

###Open-VPN
In our network graph the Open-VPN connection is only used to speak with my company network. It's running Open-VPN due to our router running `pfSense`.

To set it up it's pretty easy, you just have to get your `config.ovpn` file.

Then install `openvpn`:
```bash
apt-get install openvpn
```

Define your credentials:
```bash
echo "username" >> /etc/openvpn/credentials
echo "password" >> /etc/openvpn/credentials
```

And start the tunnel:
```bash
openvpn --config /path/config.ovpn --daemon
```
You should see a new `tun0` interface when you type:
```bash
ip a
```

###Wireguard server
Let's install and configure out Wireguard instance now!

The install process is just 3 commands long:
```bash
apt-get install linux-headers-$(uname --kernel-release)
add-apt-repository ppa:wireguard/wireguard
apt-get update && apt-get install wireguard
```

Now we can configure Wireguard.
Start by creating the needed folder and the private/public keys of the server:
```bash
mkdir -p /etc/wireguard/keys
cd /etc/wireguard/keys
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
```

We'll now create `/etc/wireguard/wg0.conf` which is our Wireguard config:
```bash
vim /etc/wireguard/wg0.conf
```
```
PrivateKey = private_key # from the step above
Address = 172.16.0.0/12,fd5b:5840:9e9f:a477::1/64 # you can change it, but IT STAY PRIVATE IPS
ListenPort = 8999
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens2 -j MASQUERADE; iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o he-ipv6 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens2 -j MASQUERADE; iptables -t nat -D POSTROUTING -o tun0 -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o he-ipv6 -j MASQUERADE

[Peer]
PublicKey = public_key_client_one
AllowedIPs = 172.16.66.2,fd5b:5840:9e9f:a477::ca:571e/128 # update if you changed the Address from above

[Peer]
PublicKey = public_key_client_two
AllowedIPs = 172.16.66.3,fd5b:5840:9e9f:a477::746f:786f/128 # update if you changed the Address from above
```

Once it's configured, make it start and launch at boots:
```bash
 systemctl enable wg-quick@wg0.service
 systemctl start wg-quick@wg0.service
```
###Wireguard client
As it's not the main goal of this tutorial and as it's not very complicated, I'll just give you an example of a client's config.
```
[Interface]
PrivateKey = client_private_key
Address = 172.16.66.3/32,fd5b:5840:9e9f:a477::746f:786f/64
DNS = 10.18.1.57 # IMPORTANT (IP OF THE PI-HOLE)

[Peer]
PublicKey = server_public_key
AllowedIPs = 0.0.0.0/0,::/0 # ROUTE ALL TRAFIC
Endpoint = 123.123.123.123:8999 # IP OF THE SERVER:PORT
PersistentKeepalive = 15
```