1
0
Fork 0
isopod.cool/blog/posts/guide_self_host_safely_with_wireguard/index.html
will 620200137e make it work on phones tm
- Rearranged navigation significantly
  - Navbar is now unlimited width on desktop
  - Navbar is now always on top of the screen, even on the landing page
  - Navbar has been replaced with hamburger menu on mobile
- Significant styling alterations to look good on phones tm
  - Most of the credit goes to a certain meta tag.
  - (Appearance on desktop is mostly unchanged)
  - The background on mobile is now 100% image, but darkened to improve contrast
  - Table pages such as /links/ and /stats/ now rearrange on mobile:

    column a                column a  column b
    column b       vs       column a  column b
    column a                column a  column b
    column b                column a  column b

  - font size on landing page scales with device width on tall displays
  - guestbook posts use CSS grid now
- Working on a @media (prefers-contrast: more) theme as well. Can't figure out how to test it though
- Updated /stats/
  - Added some new stats
  - Updated CD collection size
- Updated /about/uses/
  - I now use Nextcloud News instead of Yarr
  - My phone runs Graphene
  - I use Fennec browser on mobile instead of standard Firefox
  - New background as the old one was horrible for contrast
- Added Waxlimbs - For Science! to /about/music/
- The oldest three articles on /blog/ now show a warning on hover that they're from the legacy v2 site
- Corrected various markup issues with the help of validator.w3.org/nu/
- Added alt text to a ton of images
- todo list is no longer a separate html file. it was fucking with the scaling on mobile and I couldn't be bothered
- /stuff/ remains unchanged. I'll get to it
- Hopefully that's everything lol
2023-02-26 04:22:38 -07:00

90 lines
9.3 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Guide - Self-Host Safe(r)ly with WireGuard</title>
<link href="../../../style.css" rel="stylesheet" type="text/css" media="all">
<style>
h1 {
background-image: url('wireguard_logo.png');
}
summary > * {
margin-bottom: 0;
display: inline-block;
}
details[open] > summary h6 {
display: none;
}
</style>
</head>
<body>
<h1>guide:</h1>
<h2 id="caption">Self-Host Safe(r)ly with WireGuard</h2>
<nav>
<a href="../../../">home</a>
<a href="../../">blog</a>
</nav>
<details>
<summary><h2>Preamble</h2> <h6>Click to show</h6></summary>
<p>If you're like me, you don't like relying on other people for your online services, either because you don't want to give out your data unnecessarily, or just because you don't want to shell out for subscription services. You might be willing to host such services yourself, and you might even have access to spare hardware to do it on.</p>
<p>One critical issue arises, however: your home network. Maybe you're behind some weird impenetrable NAT setup you don't control, or maybe your IP address is dynamic and changes regularly, or maybe you just don't want to expose your home IP to the world. What then?</p>
<p>Luckily for us, there's a way to circumvent all that nonsense. A custom VPN like the one we'll be setting up today, hosted on an external server like a VPS, can punch through any weird home internet configuration while also swapping out your home IP address for a static one that you can feel safe exposing to the world.</p>
<p>That said, this isn't the be-all end-all for security. I don't claim to know everything about that, and there's probably something you're missing in that regard if you stop here. This is intended as a basic guide for exposing a machine in your home to the internet without messing with your home network or exposing your home IP address.</p>
<p>This guide borrows heavily from the <a href="https://landchad.net/wireguard/">landchad.net</a> WireGuard guide, but while their one is geared toward running a VPN for your personal machine (complete with a tutorial on setting up a WebSocket tunnel), this one will focus specifically on forwarding incoming traffic from one server to another over the internet.</p>
<p>There are some reasons you'd want to do this instead of just hosting everything on the same VPS - in my case, I wanted to host a Minecraft server, and I had a spare computer at home that was better up to the task than anything for rent in my price range. WireGuard can run on pretty much anything; the cheapest tier on Vultr, DigialOcean or Linode will be more than sufficient.</p>
<h2>Now on to the good stuff</h2>
</details>
<p>This guide will take you through the process of setting up a WireGuard VPN connection between two machines running Linux, and configuring it to forward incoming web traffic from one to the other. It assumes you already have two servers set up running Linux (Ubuntu Server in my case, but any distro should suffice) with UFW configured and enabled, and know what ports you'll need.</p>
<p>The machine running your WireGuard server should be an external one exposed to the internet, such as a VPS, for maximum effect. For our purposes, this machine will be the "server", and the one you're forwarding traffic to will be the "client".</p>
<p>We'll be configuring WireGuard with a 172.16.0.1/24 virtual network and forwarding port 25565, the default for Minecraft, but any private IP range and port will do.</p>
<h2>Installation</h2>
<p>First, we'll install WireGuard on both machines:</p>
<code>$ apt install wireguard wireguard-tools</code>
<p>And allow the port it uses in UFW:</p>
<code>$ ufw allow 51820</code>
<h3>On the server</h3>
<p>Uncomment this line in <code>/etc/sysctl.d/99-sysctl.conf</code> to enable IPv4 forwarding:</p>
<code>$ net.ipv4.ip_forward=1</code>
<p>And apply the change with this command:</p>
<code>$ sysctl -w net.ipv4.ip_forward=1</code>
<h3>On the client</h3>
<p>We'll need to generate a public/private key pair for each machine on our VPN network. Do that now for our client like so:</p>
<code>$ sudo bash -c "umask 077 ; wg genkey &gt; /etc/wireguard/client_priv.key"<br>$ sudo bash -c "wg pubkey &lt; /etc/wireguard/client_priv.key &gt; /etc/wireguard/client_pub.key"</code>
<p>This generates a private key for WireGuard and then generates a corresponding public key based on it. Our client's keys can now be found in <code>/etc/wireguard/client_priv.key</code> and <code>/etc/wireguard/client_pub.key</code> for our private and public keys respectively.</p>
<h3>Back to the server</h3>
<p>Now do the same for the server:</p>
<code>$ umask 077 ; wg genkey &gt; /etc/wireguard/server_priv.key<br>$ wg pubkey &lt; /etc/wireguard/server_priv.key &gt; /etc/wireguard/server_pub.key</code>
<p>Our server's keys can now be found in <code>/etc/wireguard/server_priv.key</code> and <code>/etc/wireguard/server_pub.key</code> for our private and public keys respectively.</p>
<p>Now, create a WireGuard configuration file at <code>/etc/wireguard/wg0.conf</code>. <code>wg0</code> will be the name of our network interface, you can name yours something else if you'd like.</p>
<code>[Interface]<br>Address = 172.16.0.1/24<br>ListenPort = 51820<br>PrivateKey = &nbsp;&nbsp;#(server's private key goes here)<br># Firewall rules<br>PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE<br>PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE<br><br>[Peer]<br># Client #1 details<br>PublicKey = &nbsp;&nbsp;#(client's public key goes here)<br># Traffic to route to this client<br>AllowedIPs = 172.16.0.2/32</code>
<p>Paste the server's private key after <code>PrivateKey =</code> in <code>[Interface]</code> and the client's public key after <code>PublicKey =</code> in <code>[Peer]</code>.</p>
<p>With this setup, our server will use the virtual local IP <code>172.16.0.1</code> and our client will use the IP <code>172.16.0.2</code>. You can also add up to 254 more clients by duplicating the <code>[Peer]</code> block and and updating it with the respective public key and a new local IP address.</p>
<p>Now, enable and start the WireGuard service with</p>
<code>$ systemctl enable --now wg-quick@wg0.service</code>
<p><code>wg0</code> being what we called our network interface before.</p>
<h3>Back to the client</h3>
<p>Create a WireGuard configuration file for our client at <code>/etc/wireguard/myvpn.conf</code> (you can replace <code>myvpn</code> with a different name if you so choose):</p>
<code>[Interface]<br>Address = 172.16.0.2/24<br>PrivateKey = &nbsp;&nbsp;#(client's private key goes here)<br># Optionally, set to your desired DNS server<br># DNS = 9.9.9.9<br><br>[Peer]<br>PublicKey = &nbsp;&nbsp;#(server's public key goes here)<br># Endpoint (server) can be a domain name or IP address<br>Endpoint = (server's public IP goes here):51820<br># Traffic to route to server<br>AllowedIPs = 0.0.0.0/0, ::/0<br>PersistentKeepalive = 25</code>
<p>Make sure you use your server's public IP here. The PersistentKeepalive option is there because WireGuard closes the connection by default if no data comes through for a while and will only reopen it for the client, so here we send a KeepAlive packet every 25 seconds to prevent that in order to keep our client accessible from the internet.</p>
<p>Now we start WireGuard:</p>
<code>$ sudo wg-quick up myvpn</code>
<p><code>myvpn</code> being whatever you called your vpn before. Shut WireGuard down by typing <code>down</code> instead of <code>up</code> here. At this point, you should be able to ping the server (<code>172.16.0.1</code>) or any URL from the client and get a response.</p>
<h2>Port Forwarding</h2>
<p>Now we'll configure the firewall and port forwarding. This bit assumes you already have UFW configured and enabled. You can set it up now if necessary.</p>
<h3>On the server</h3>
<p>Allow forwarding for the ports you need:</p>
<code>$ ufw route allow proto tcp to 172.16.0.2 port 25565</code>
<p><code>25565</code> being your relevant port. Repeat this command as necessary.</p>
<p>Now we need to configure iptables. We can do this through UFW by adding the following onto the very end of the file <code>/etc/ufw&#8288;/before.rules</code>:</p>
<code>*nat<br>:PREROUTING ACCEPT [0:0]<br>:POSTROUTING ACCEPT [0:0]<br>-A PREROUTING -i eth0 -p tcp --dport 25565 -j DNAT --to-destination 172.16.0.2<br>-A POSTROUTING -o eth0 -j MASQUERADE<br>COMMIT</code>
<p>Where <code>25565</code> is, again, your relevant port. Copy the <code>-A PREROUTING</code> line for every port you need.</p>
<p>Now restart UFW:</p>
<code>$ ufw reload</code>
<h3>On the client</h3>
<p>Allow the relevant ports and restart UFW:</p>
<code>$ ufw allow 51820<br>$ ufw allow 25565<br>$ ufw reload</code>
<p>And you're done! At this point, your client should be accessible from the IP address of your server on the ports you forwarded.</p>
</body>
</html>