2023-01-09 21:30:45 +00:00
<! DOCTYPE html >
< html lang = " en " >
< head >
< meta charset = " utf-8 " >
2023-02-24 11:05:27 +00:00
< meta name = " viewport " content = " width=device-width, initial-scale=1 " >
2023-02-26 11:22:38 +00:00
< title > Guide - Self - Host Safe ( r ) ly with WireGuard </ title >
2024-01-04 15:02:57 +00:00
< link href = " /style.css " rel = " stylesheet " type = " text/css " media = " all " >
< link href = " /blog/comment/comments.css " rel = " stylesheet " type = " text/css " media = " all " >
2023-02-26 11:22:38 +00:00
< style >
2023-01-09 21:30:45 +00:00
h1 {
background - image : url ( 'wireguard_logo.png' );
}
</ style >
</ head >
< body >
2024-07-08 09:20:49 +00:00
< ? php include ( $_SERVER [ 'DOCUMENT_ROOT' ] . '/nav.php' ); ?>
2023-01-09 21:30:45 +00:00
< h1 > guide :</ h1 >
2023-02-26 11:22:38 +00:00
< h2 id = " caption " > Self - Host Safe ( r ) ly with WireGuard </ h2 >
2024-03-18 10:21:49 +00:00
< ? php include ( " ../post_dates.php " ); ?>
2024-07-08 09:20:49 +00:00
< p >< strong > Warning : The information in this post is outdated and probably bad . I 'd update it but I don' t remember what I did . I 'm pretty sure I had to circumvent UFW entirely. At any rate, probably don' t do what I say to do here .</ strong ></ p >
< h2 > Preamble </ h2 >
2023-01-09 21:30:45 +00:00
< details >
2024-07-08 09:20:49 +00:00
< summary > Show preamble </ summary >
2023-01-09 21:30:45 +00:00
< 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 >
2023-02-26 11:22:38 +00:00
< code > $ sudo bash - c " umask 077 ; wg genkey > /etc/wireguard/client_priv.key " < br > $ sudo bash - c " wg pubkey < /etc/wireguard/client_priv.key > /etc/wireguard/client_pub.key " </ code >
2023-01-09 21:30:45 +00:00
< 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 >
2023-02-26 11:22:38 +00:00
< h3 > Back to the server </ h3 >
2023-01-09 21:30:45 +00:00
< p > Now do the same for the server :</ p >
2023-02-26 11:22:38 +00:00
< 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 >
2023-01-09 21:30:45 +00:00
< 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 >
2023-02-26 11:22:38 +00:00
< 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 = #(client's public key goes here)<br># Traffic to route to this client<br>AllowedIPs = 172.16.0.2/32</code>
2023-01-09 21:30:45 +00:00
< 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 >
2023-02-26 11:22:38 +00:00
< 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 = #(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>
2023-01-09 21:30:45 +00:00
< 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>
2023-02-26 11:22:38 +00:00
< 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 >
2023-01-09 21:30:45 +00:00
< 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 >
2023-02-26 11:22:38 +00:00
< code > $ ufw allow 51820 < br > $ ufw allow 25565 < br > $ ufw reload </ code >
2023-01-09 21:30:45 +00:00
< 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 >
2024-01-04 15:02:57 +00:00
< ? php include ( " ../../comment/form.php " ); ?>
2023-01-09 21:30:45 +00:00
</ body >
</ html >