Em's Site

Access your local network using Wireguard VPN and Algo

Setting up a secure VPN to access a local network using Wireguard and Algo

If you need to access your home network from somewhere other than your home, the traditional way to do that is using a VPN. However, most VPN tutorials send all of your traffic through your home network. I only wanted to reach the devices in my home network, and not send all my traffic through the VPN. So if that's what you're looking for, this is the tutorial for you.

We'll be using algo for this. Algo is a install script that sets up a WireGuard VPN server. WireGuard is a new-ish VPN program that is meant to be easier to use and faster than traditional VPN servers. It also makes it easy to only send certain IP addresses through the VPN instead of all internet traffic.

You'll need these things:

  • A dedicated home internet connection, where you are the only one using your IP address. This is still common, but if your provider uses DS-Lite or CGNAT or some other form of shared IP address, this won't work, you'll need to get a server and use that. I'm not sure of a generic way to find this out, sorry.
  • A computer running an up-to-date version of Ubuntu. At the time of writing, that's 18.04 and 19.10. Check the algo docs if you're reading this far into the future to see supported versions. Note: if you're using a Raspberry Pi or similar ARM computer, you'll need to use Ubuntu 19.10.
  • A way to get a root shell on the aforementioned computer. This can be either via SSH from a different computer or through the terminal on the computer you're using.
  • A list of devices that will be connecting to the VPN from outside your network.
  • A way to forward ports from your router to the computer.
  • A few hours on a cloudy weekend afternoon with good focus music and a cup of tea (other types of beverages are allowed).

Since we're all using a local computer with Ubuntu, we can shorten the algo install docs somewhat.

Get system and Python requirements

  • Get a root shell. sudo su should work if you freshly installed Ubuntu and you're the only user. You might have to enter your password.
  • Make sure your system has some required things installed: apt install git qrencode wget openssh-server python3-virtualenv.
  • Clone the repo and change into the repo directory: git clone https://github.com/trailofbits/algo && cd algo.
  • Install a python virtual environment to isolate the install: python3 -m virtualenv --python="$(command -v python3)" .env && source .env/bin/activate.
  • Install the algo dependencies: python3 -m pip install -U pip virtualenv && python3 -m pip install -r requirements.txt.
  • Open config.cfg in your favorite editor. If you don't have a favorite editor, I suggest nano: nano config.cfg.

Edit algo config

  • Edit the list of users: and add the list of devices you gathered when I told you to above. BE SURE TO KEEP THE INDENTATION THE SAME: 2 spaces, NOT a tab.
  • Change ipsec_enabled to false.
  • Find the BetweenClients_DROP and change false to true.
  • (Optional) Sometimes you'll have a firewall that drops connections after a while. To get around that, find wireguard_PersistentKeepAlive and set it to 25 (Not a magic number, it's actually WireGuard's recommended setting).
  • Save and close the file. If you're using nano, that's Ctrl+X, then Y, then hit Enter. If you're using vim, it's :x.

Install algo

  • Run ./algo. There's several options to choose from, make sure you choose the "Install to existing Ubuntu server" on the "What provider would you like to use?" prompt.
  • We're going to remove the DNS settings for Wireguard later on, so don't bother setting them up here.
  • The IP address options are a little confusing. The first one is the local IP address, you leave that as localhost. For the "Enter the public IP address of your server", you can find your public IP address using wget -qO - https://canihazip.com/s. You can also use a dyndns provider if you want.
  • The rest of the prompts can be left as their default value.
  • The install should complete successfully. If it doesn't, research the error you got and try again until it does.
  • Take a break, you're almost there. Do some pushups, get some water, take a short jog, and then come back.

Set up devices

  • Run exit to drop back into your user shell, then sudo cp -r /root/algo/configs . and sudo chown $(whoami):$(whoami) -R configs. This moves the configs to your home directory and makes them accessible to you without special privileges.
  • cd into the configs directory. You should see your public IP address as a folder (or the dyndns hostname if you went that route). cd into that, and then into the wireguard directory. There will be a .conf and .png file for each user you specified in config.cfg way back in the beginning.
  • Edit each of the conf files. In the [Interface] section, remove the DNS= line if there is one. In the [Peer] section, change AllowedIPs to the IPv4 and IPv6 subnet of the Address of the [Interface] section.
  • If that isn't clear, you're taking the first value in the Address= line (the default is 10.19.49.x/24, where x is unique to each client). Change the x to a 0, and put that in the AllowedIPs= line, erasing whatever value is currently in there. So if you have Address=10.19.49.2/24, you copy 10.19.49.2/24 and replace the values in AllowedIPs with 10.19.49.0/24, so the entire line is AllowedIPs=10.19.49.0/24.
  • Do the same for the IPv6 subnet, replacing the number after the :: with a 0.
  • See pictures below if you're having trouble.

Configure WireGuard for local network

Sorry this section can't be bullet points, the pictures and code get all wonky.

If you want to access computers connected to your local network but not connected to the VPN, find your local subnet. The easiest way is to run ip a. If you're connecting wirelessly, there should be a interfacethat starts with a w and an IP address associated with that. If you're connected via ethernet, it will be the interface beginning with e. Here's mine as an example (it's using a wireless connection): ip address settings

Copy the IP address that's in the place of the one circled (squared?) in that picture, open up a terminal and run python3 and then enter the lines prefixed with >>>, substituting your IP address for my example:

>>> import ipaddress
>>> ipaddress.ip_network("192.168.1.29/24", False)
    IPv4Network('192.168.1.0/24')

The string in the IPv4Network that is returned is the subnet you need to use.

If you like pictures, you started with something similar to this: Initial WireGuard configuration

and you end with something like this: Modified WireGuard configuration

Port forward the WireGuard port

You need to port forward UDP port 51820 to the computer running algo. Unfortunately, there's not a generic way to do this, so you'll need to research how to forward ports on your specific router.

Distribute the configuration files

For desktops and laptops, you can ssh into the computer and copy+paste the configuration. For phones and tablets, the WireGuard app can read a QR code. Algo created one for us, but it isn't valid anymore since we changed the configs. To get the configuration on your phone or tablet, run qrencode -t ansiutf8 -r x.conf, replacing x.conf with the name of the configuration file. The QR code will display in your terminal and you can scan it. If your terminal doesn't support UTF8, run qrencode -t png -r x.conf -o x.png and download x.png to your local computer to display.

IP address conflicts

If you have a common local subnet (192.168.1.0/24 or 192.168.0.0/24 are the most common), it's likely you'll eventually end up on another network that shares the same local subnet, which might prevent you from accessing the local subnet over WireGuard. If you don't need to access any of the local IPs on that network (make sure your DNS isn't using it), there's a few ways to fix it. First, if your ISP and router support IPv6, you can find the IPv6 subnet range just like you found the IPv4 subnet range a few sections up, and add that to your AllowedIPs= line. Then you can connect to your home devices via IPv6. Second, you can connect all the devices to WireGuard so they're all accessible via the WireGuard IP address range. If neither of those are a possibility, the last option is making the IP address rules more specific. I'm not going to show you here, but read up on CIDR ranges (the /24 is the CIDR range I have in my example) and how UNIX/Linux systems route packets, and you may be able to make a more specific route.

Firewall

Algo sets up the iptables firewall to block all ports except the necessary ones for Wireguard. So if you're running some other program that listens on a port, you'll need to go in and add a firewall rule to allow that port.