I was a Private Internet Access customer for six years. The price hikes over the years didn't phase me, but what really concerned me was the acquisition by Kape Technologies at the end of 2019. Long story short: the company that acquired PIA has a horrible privacy track record. Can we still trust PIA?
I decided to cancel my subscription and spin up my own VPN. There are some downsides to doing this (for example, your IP won't be shared with others so you'll lose the anonymity aspect), but it works fine for keeping your traffic safe on insecure networks.
If you want to break free from a VPN subscription and roll your own, this post is for you.
the projects we'll be using
What is WireGuard, and what is Pi-hole?
- WireGuard is a simple and fast VPN solution. It's a lot leaner than OpenVPN and is easier to set up. A lot of attention is directed towards WireGuard at the minute, especially because it was recently merged into Linus Torvalds's tree. This means it'll be included in the next release of the Linux kernel.
- Pi-hole is a project which describes itself as a 'black hole for internet advertisements'. It's a DNS server intended to run on a Raspberry Pi on your local network which you then point your router at such that every device in your home resolves DNS through it. Pi-hole blacklists a tonne of shady domains so that when any client on your network requests them, the name just simply doesn't resolve. The upshot? Traffic to dodgy domains is blocked network-wide.
We'll be using WireGuard to set up our actual VPN, and Pi-hole for ad-blocking.
hosting your vpn server
For the purposes of this post I'll assume you're setting up your VPN on a VPS. I use DigitalOcean. You can use whatever. If your main concern is privacy, make sure that you trust the VPS provider!
I'm also going to assume that your server is running some flavor of Ubuntu.
step one: setting up the firewall on your server
We want to enable the firewall, deny traffic by default, and allow all traffic coming from our VPN clients. We're going to use the subnet 192.168.5.0/24 for our VPN. We reserve 192.168.5.0-255 for our VPN.
First, lets add some rules:
# ufw default deny # ufw allow from 192.168.5.0/24
If you're connected via SSH, make sure you add a rule to allow SSH traffic.
# ufw allow 22/tcp
Finally, enable the firewall.
# ufw enable
step two: wireguard server setup
First, install the
wireguard package with:
# add-apt-repository ppa:wireguard/wireguard # apt-get update && apt-get install wireguard
Once that's done, it's time to generate a keypair. WireGuard avoids the code-bloat of key-exchange by delegating the task to the users, a bit like SSH. All peers in your VPN have a public-key and a private-key used for encryption.
We'll generate a keypair for the server in
# mkdir -p /etc/wireguard/keys/server && cd /etc/wireguard/keys/server # wg genkey | tee privatekey | wg pubkey > publickey
wg genkey generates a private key. We write that key to the disk with
tee. We also pass the private key
wg pubkey to generate a public key, which we also write to the disk.
Now we configure WireGuard.
# vim /etc/wireguard/wg0.conf
Since our file is called
wg0.conf, our WireGuard interface will be called
wg0. In this file, we want to write the
[Interface] Address = 192.168.5.1/24 PostUp = sysctl -w net.ipv4.ip_forward=1 PostUp = sysctl -w net.ipv6.conf.all.forwarding=1 PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE ListenPort = 51820 PrivateKey = $private_key_from_earlier
What does this do?
Address = 192.168.5.1/24specifies the subnet for the interface. This just means that the range of IP addresses
192.168.5.255will be used for our VPN.
PostUpspecifies the commands to run when the WireGuard interface is brought up. In this case, when we bring up
wg0, we will enable IPv4 and IPv6 forwarding as well as configure
iptablesto perform NAT for traffic passing through our internet-facing interface.
PostDownspecifies the commands to run when the WireGuard interface is brought down. In this case we just remove the NAT rules we created in
ListenPortdefines the port the VPN will listen on.
PrivateKeyspecifies the VPN server's private key (which we made earlier). This is required to decrypt traffic from our clients.
step three: setting up a client
Next, we want to set up our clients. I'll give you the steps to do this for just one client -- repeat for each client you have.
First of all, make sure you have WireGuard installed on your client. I'll assume you're using macOS, since that's what I used. The steps should be similar for Linux.
$ brew install wireguard
Now generate a public-private keypair for the client. Keep these somewhere safe.
/etc/wireguard/keys would be a good
$ wg genkey | tee privatekey | wg pubkey > publickey
Now, on the server, we must edit
/etc/wireguard/wg0.conf and add ourselves as a peer. Add the following to the
[Peer] # my macbook PublicKey = $client_public_key AllowedIPs = 192.168.5.6/32
What are we doing here?
PublicKeyspecifies the peer's public key, naturally. We need to include this so that the server knows how to encrypt traffic destined for this peer.
AllowedIPsspecifies a range of IP addresses that this client may use within the VPN. It is not a list of IPs that you are allowed to connect from, as the name might suggest. In our case, we're saying 'this client can only use the IP 192.168.5.6 inside our VPN' -- we refuse to route any traffic from this peer that does not use this IP inside the VPN.
Now let's create a config file for the VPN on the client.
[Interface] Address = 192.168.5.6 PrivateKey = $client_private_key DNS = 192.168.5.1 [Peer] PublicKey = $server_public_key Endpoint = $server_public_ip:51820 AllowedIPs = 0.0.0.0/0, ::/0 # Keep the connection alive PersistentKeepalive = 25
That should be the VPN configured. Import the config you created into your WireGuard client and test the connection.
step four: setting up pi-hole to block ads
WIP! Come back soon!