Jekyll2019-04-30T22:50:08+00:00https://drexl.me/feed.xmlDetachment 2702an internet survival guideDrexl SpiveySetting up an ad-blocking VPN with Wireguard and Pihole2019-04-22T00:00:00+00:002019-04-22T00:00:00+00:00https://drexl.me/guides/wireguard-pihole-vpn-setup<p>This guide will walk you through the setup of a remote machine that will act as a personal VPN server at the cost of 3 to 5 USD per month. We will also configure it to act as a DNS resolver that will automatically block spam, tracking, advertising and malware domains on all of your connected devices.</p>
<p>I will be using Ubuntu 18.04 on a $5 <a href="https://m.do.co/c/6a7ba542f98e">DigitalOcean</a> (affiliate) droplet but there are cheaper alternatives out there.</p>
<h2 id="rationale">Rationale</h2>
<p>Your internet traffic is accessible to your internet provider which in many cases might not be as innocent as you would imagine. There are many reports where ISPs are actively <a href="https://www.privateinternetaccess.com/blog/2016/12/comcast-still-uses-mitm-javascript-injection-serve-unwanted-ads-messages/">intercepting network traffic</a> and injecting arbitrary code into the webpage. Thankfully that can be mitigated by always visiting sites through <code class="highlighter-rouge">https</code> but not all sites support TLS.</p>
<p>Even with <code class="highlighter-rouge">https</code>, ISPs are still able to monitor all the websites you visit and even actively block you from visiting them. Depending on your jurisdiction, it might be perfectly legal for them to sell that data to adtech companies. Even when your ISP is benevolent, your government might not be, as evident by the soon to be implemented <a href="https://www.bbc.com/news/newsbeat-43795806">UK Porn Ban</a>.</p>
<h3 id="commercial-vs-self-hosting">Commercial vs self-hosting</h3>
<p>A VPN can solve most of these problems by encrypting and routing your whole internet traffic through a server. Typically those servers are run by companies that provide access to them as a service. However the trust is merely being shifted from your ISP to your VPN provider who is now able to do all the monitoring. That might not seem perfect but it is a pretty big privacy gain since most paid VPN providers focus on privacy as their main selling point. Why bother with self hosting then? Here are some pros and cons.</p>
<h4 id="pros">Pros</h4>
<ul>
<li>You control the hardware. As a result you can set up ad blocking, add as many devices as you like, give access to your friends etc.</li>
<li>Certain services like Netflix/Amazon Prime Video etc. blacklist all commercial VPN providers and it’s trivial to detect that you are using one.</li>
<li>If you are already paying to host something on a VPS it’s essentially free.</li>
</ul>
<h4 id="cons">Cons</h4>
<ul>
<li>Your cloud provider (AWS, DigitalOcean) still knows who you are and can monitor your traffic. You can mitigate that by using a provider that accepts anonymous cryptocurrency payments.</li>
<li>Since you are the only one using it, websites can use your IP as an identifier.</li>
</ul>
<p>Another approach that combines the best of both worlds is to have your server do the DNS resolution and then route the traffic through a commercial VPN. That requires a more complex setup and it will not be covered here.</p>
<h2 id="wireguard">Wireguard</h2>
<p><a href="https://www.wireguard.com/">Wireguard</a> is a new generation VPN protocol. It’s main selling point is that it is built on modern but tested cryptography, the implementation is very short and it’s fast. And I mean crazy fast, I’ve been using it on all my devices for a few months now and it is very impressing. Have you ever used a VPN on your phone? With OpenVPN it takes 5-10 seconds to connect when your phone wakes up and it drains battery like crazy. Wireguard is based on UDP so there is no connection to be made, it just sprays encrypted packets. There is no key exchange (it happens out of band) and as a result it’s always ready to go with no delay and it feels like it doesn’t drain any battery at all.</p>
<p>Wireguard is an open source project developed mainly by <a href="https://www.zx2c4.com/">Jason A. Donefeld</a>. It is expected to be merged into the Linux kernel soon and even Linus <a href="https://lists.openwall.net/netdev/2018/08/02/124">praised it</a> and that means something. There are currently implementations for <a href="https://www.wireguard.com/install/">Linux</a> (as a kernel module), <a href="https://play.google.com/store/apps/details?id=com.wireguard.android">Android</a>, <a href="https://itunes.apple.com/us/app/wireguard/id1451685025?ls=1&mt=12">MacOS</a>, <a href="https://itunes.apple.com/us/app/wireguard/id1441195209">iOS</a> and a Windows version is expected to be released soon.</p>
<h2 id="pihole">Pihole</h2>
<p><a href="https://pi-hole.net/">Pihole</a> is a lightweight DNS server typically meant to run on a raspberry pi and acts as a network wide ad blocker for all your devices. It comes with sensible default lists that block around 100.000 malware, advertising and tracking domains but it is highly configurable and you can add as many of the available block lists circulating on the internet as you like. I have added a bunch of lists that block Microsoft telemetry and obnoxious “news” sites but every couple of weeks I find myself having to whitelist a legit blocked domain which is not a big deal because Pihole comes with a slick built-in web interface for this type of tasks.</p>
<h2 id="setup">Setup</h2>
<p>Log in to your droplet and update the installed packages.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get update
<span class="nb">sudo </span>apt-get upgrade
</code></pre></div></div>
<h3 id="pihole-1">Pihole</h3>
<p>The quickest method to install Pihole is to curl into bash the install script (yes, yes I know)</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-sSL</span> https://install.pi-hole.net | bash
</code></pre></div></div>
<p>Alternatively you can clone the repo or download and inspect the script first. More info <a href="https://github.com/pi-hole/pi-hole/#alternative-install-methods">here</a></p>
<p>Running through the installer is pretty straight forward and you can’t go wrong with the defaults. One change I like to make is pick Cloudflare’s <code class="highlighter-rouge">1.1.1.1</code> instead of Google’s <code class="highlighter-rouge">8.8.8.8</code> for the upstream DNS resolver. Cloudflare <a href="https://blog.cloudflare.com/announcing-1111/">launched it’s DNS</a> last year and it is supposed to be more privacy focused. I certainly trust them more than Google with my queries.</p>
<p><img src="..\assets\img\pi2.png" alt="" /></p>
<p>Make sure to enable the admin dashboard and write down your password.</p>
<p>This should get you up and running. You can check that pihole is running with</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pihole status
</code></pre></div></div>
<p>and that the web interface is running with</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-I</span> localhost
</code></pre></div></div>
<p>If you want to blacklist more domains you can do so manually through the web interface or you can find plenty of <a href="https://v.firebog.net/hosts/">curated lists</a> online. To add an online list you have to edit <code class="highlighter-rouge">/etc/pihole/adlists.list</code>, add the url in a new line and then type</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pihole <span class="nt">-g</span>
</code></pre></div></div>
<p>to update.</p>
<h3 id="wireguard-1">Wireguard</h3>
<p>Add the wireguard repository ppa.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>add-apt-repository ppa:wireguard/wireguard
</code></pre></div></div>
<p>Install Wireguard and it’s dependencies.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt install wireguard
</code></pre></div></div>
<p>If you are actually using a raspberry pi, this won’t work, but you can find installation instructions <a href="https://github.com/adrianmihalko/raspberrypiwireguard">here</a></p>
<p>In Wireguard peers are identified by their public keys which are used to encrypt the data. There is no key exchange in the protocol, keys have to be distributed off-channel like in SSH. First we need to generate a private/public key pair for our server.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir /tmp/keys
<span class="nb">cd</span> /tmp/keys
wg genkey | tee privatekey | wg pubkey <span class="o">></span> publickey
</code></pre></div></div>
<p>You should now have two base64 keys</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ubuntu@digitalocean:/tmp/keys<span class="nv">$ </span><span class="nb">cat </span>privatekey
<span class="nv">eNgugEfWgEh0Py3qOvqi41BmTPwzi5RQOzF2A4LvjnY</span><span class="o">=</span>
ubuntu@digitalocean:/tmp/keys<span class="nv">$ </span><span class="nb">cat </span>publickey
zaAf9ktzmeapk/jAAxZX42elhQZWn8DibDoeW98pTz8<span class="o">=</span>
</code></pre></div></div>
<p>We will name our new network interface <code class="highlighter-rouge">wg0</code>. Create a configuration file for your server in <code class="highlighter-rouge">/etc/wireguard/wg0.conf</code></p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Interface]
Address = 192.168.5.1/24
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = eNgugEfWgEh0Py3qOvqi41BmTPwzi5RQOzF2A4LvjnY=
</code></pre></div></div>
<p>So, what’s going on here? Let’s see what each line does.</p>
<p><code class="highlighter-rouge">Address</code>: This address will be assigned to the server in the newly created VPN. You should pick a subnet that is used in neither the server nor the client, I picked <code class="highlighter-rouge">192.168.5.xx</code> denoted by the <code class="highlighter-rouge">/24</code> netmask.</p>
<p><code class="highlighter-rouge">PostUp</code> and <code class="highlighter-rouge">PostDown</code>: These are commands that will be run when you bring the new <code class="highlighter-rouge">wg0</code> interface up/down. This specific command sets iptables rules to forward all client internet traffic through the internet facing interface <code class="highlighter-rouge">eth0</code> (change that if yours is different). If you only want to create a tunnel but not forward all your traffic through the server you can skip those.</p>
<p><code class="highlighter-rouge">ListenPort</code>: The UDP port that the server will be listening on.</p>
<p><code class="highlighter-rouge">PrivateKey</code>: The server’s private key that we created a moment ago.</p>
<p>Make sure that no one can read the file since it contains a private key (or Wireguard will complain)</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>chmod 600 /etc/wireguard/wg0.conf
</code></pre></div></div>
<p>Now generate a pair of keys for the client (your home computer)</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ubuntu@digitalocean:/tmp/keys<span class="nv">$ </span>wg genkey | tee clientprv | wg pubkey <span class="o">></span> clientpub
ubuntu@digitalocean:/tmp/keys<span class="nv">$ </span><span class="nb">cat </span>clientprv
cJ20xmVjK+9GWk9u3XIRXabfBzJqnVUmdx6H/Qgg12M<span class="o">=</span>
ubuntu@digitalocean:/tmp/keys<span class="nv">$ </span><span class="nb">cat </span>clientpub
C7OkTUE5jPaGa6OPYVKr2UgOZ4zNzmswCX2TgU+Irlg<span class="o">=</span>
</code></pre></div></div>
<p>Let’s create a configuration file for the client.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Interface]
Address = 192.168.5.2/32
PrivateKey = cJ20xmVjK+9GWk9u3XIRXabfBzJqnVUmdx6H/Qgg12M=
ListenPort = 51820
DNS = <server ip>
[Peer]
PublicKey = zaAf9ktzmeapk/jAAxZX42elhQZWn8DibDoeW98pTz8=
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = <server ip>:51820
</code></pre></div></div>
<p><code class="highlighter-rouge">Address</code>: This is the client’s address in the network. I assigned <code class="highlighter-rouge">192.168.5.1</code> to the server and I am using <code class="highlighter-rouge">192.168.5.2</code> for the client.</p>
<p><code class="highlighter-rouge">PrivateKey</code>: Since this is the configuration file that we will use on the client, this is the <strong>client’s</strong> private key.</p>
<p><code class="highlighter-rouge">DNS</code>: We want to use our droplet for DNS so here goes the server’s public IP (the one you SSH into)</p>
<p>In the <code class="highlighter-rouge">Peer</code> section we add the server’s details</p>
<p><code class="highlighter-rouge">PublicKey</code>: The <strong>server’s</strong> public key</p>
<p><code class="highlighter-rouge">AllowedIPs</code>: This entry acts in two ways. It will accept packets through the tunnel if they have this <em>source</em> IP. It will also send packets through the tunnel if they have this <em>destination</em> IP. Since we use the wildcard IPv4 and IPv6 addresses <strong>all</strong> traffic will go through the tunnel and <strong>all</strong> traffic will be accepted.</p>
<p><code class="highlighter-rouge">Endpoint</code>: This is the external IP address where the server is reachable (the one you SSH into)</p>
<p>Now that we told the client how to communicate with the server let’s go back to the server’s config in <code class="highlighter-rouge">/etc/wireguard/wg0.conf</code> and add a <code class="highlighter-rouge">Peer</code> section to authorize the client.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Peer]
PublicKey = C7OkTUE5jPaGa6OPYVKr2UgOZ4zNzmswCX2TgU+Irlg=
AllowedIPs = 192.168.5.2/32
</code></pre></div></div>
<p><code class="highlighter-rouge">PublicKey</code>: The <strong>client’s</strong> public key</p>
<p><code class="highlighter-rouge">AllowedIPs</code>: Same as before, the server will only accept packets with this <em>source</em> IP from this peer and will encrypt and send packets with this <em>destination</em> IP to this peer.</p>
<p>You can repeat this process to create as many configuration files for your devices/friends as you like. For each one of them you need a new <code class="highlighter-rouge">Peer</code> section in your server’s config.</p>
<p>Make sure that IP forwarding is enabled.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>sysctl net.ipv4.ip_forward<span class="o">=</span>1
</code></pre></div></div>
<p>Now to bring <code class="highlighter-rouge">wg0</code> up simply type</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wg-quick up wg0
</code></pre></div></div>
<p>Copy the client’s configuration file to your home computer, import it to your Wireguard app and click connect. If you are on Linux the process is identical with the server, just put the file in <code class="highlighter-rouge">/etc/wireguard/wg0.conf</code> and <code class="highlighter-rouge">wg-quick up wg0</code></p>
<p>To check the status type</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>wg show
</code></pre></div></div>
<p>and make sure you are receiving packets.</p>
<p>If you want to automatically start Wireguard on startup type</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>systemctl <span class="nb">enable </span>wg-quick@wg0.service
</code></pre></div></div>
<p>Finally let’s make sure that your server is actually being used for DNS resolution.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pihole tail
</code></pre></div></div>
<p>will show you the DNS queries as they come. With that running, open up a browser window on your home computer and try to visit a website. The website’s name should pop up in the output of <code class="highlighter-rouge">tail</code>.</p>
<p>Remember the dashboard password we wrote down in the begining? With the Wireguard connection running, visiting <a href="http://192.168.5.1/admin/">http://192.168.5.1/admin/</a> (or whatever IP you used) will bring up the pihole dashboard where you can login as admin with that password.</p>
<p>This was a pretty basic networking setup but you can do much more complex ones for your use case. If you want to follow updates on wireguard’s development you can subsribe to the <a href="https://lists.zx2c4.com/mailman/listinfo/wireguard">mailing list</a></p>Drexl SpiveyThis guide will walk you through the setup of a remote machine that will act as a personal VPN server at the cost of 3 to 5 USD per month. We will also configure it to act as a DNS resolver that will automatically block spam, tracking, advertising and malware domains on all of your connected devices.