Using Wireguard, DigitalOcean and firewalld to give your roaming computer a static IP

"Have fun storming the castle"

While we’re waiting to figure out where in Ireland we’ll be living long-term, we’re currently using mobile broadband. I’d like to be able to ssh into my home network from outside, but when I looked into setting up DDNS, I found that I don’t even have a public IP address. My mobile dongle says that its IP address is in the 10.0.0.0/8 range, so there’s no way to direct traffic to it from the internet.

After my first foray in using wireguard, I figured it should be a good fit to give myself ssh access to the home network. I could have just forwarded a specific port to my home network, but I prefer not to have to deal with non-standard ports. And, as this site is hosted on DigitalOcean, the natural next step was to see if I could pull it off with them.

It took a couple of hours (mainly dealing with firewalld as I’m much more comfortable with iptables), but I got there in the end, and I can now ssh into my home network (using key-based authentication, of course).

This guide will walk you through the process, step by step. It assumes you have a DigitalOcean droplet running, that you’re using Fedora on both the roaming computer and the DigitalOcean droplet, and that you have firewalld on both.

Step 1 - Give your droplet a Floating IP

  1. Log into DigitalOcean
  2. Go to Networking, Floating IPs
  3. Select the droplet you want to use as your gateway and click Assign Floating IP:
  4. Check to see what address you got. This will be your new static IP address

Do note that the floating IP will not appear when you run ip addr in your droplet, but there will be a local IP (most likely in the 10.16.0.0/16 range) that all the floating IP’s traffic will be forwarded to.

Step 2 - Setup wireguard between DigitalOcean and your roaming computer

On both the DigitalOcean droplet and your roaming computer, install wireguard. I want to quickly note that it’s not available from the official Fedora repositories because the kernel module hasn’t been merged into the mainline kernel yet. It has just become available in the RPM Fusion Free testing repositories. This guide assumes you’ve already configured the RPM Fusion Free repository on your system.

$ sudo dnf --enablerepo=rpmfusion-free-updates-testing install wireguard

Now, it’s time to set wireguard up on the DigitalOcean droplet.

  1. We’ll use the wg-quick service to set everything up, so put the following in /etc/wireguard/wgnet0.conf:

     [Interface]
     Address = 192.168.32.1/24
     SaveConfig = true
     ListenPort = 51820
     PrivateKey = 
    
     [Peer]
     PublicKey = 
     PresharedKey = 
     AllowedIPs = 192.168.32.0/24
    
  1. Generate a private key and insert it into the line that says PrivateKey:

     $ wg genkey
    
  1. Generate a pre-shared key (which should protect your VPN from the omnipresent quantum computers that are undoubtedly listening in) and insert it into the line that says PresharedKey:

     $ wg genpsk
    
  1. Figure out the public key from the private key you generated in step 2:

     $ echo {private key} | wg pubkey
    

Now for the roaming computer. Because the roaming computer initiates the connection to the DigitalOcean droplet, we need to setup a keepalive so traffic that starts at the droplet (which is the whole point of this exercise) will get back to the roaming computer in 10 seconds max if the link is completely idle.

  1. Put the following in /etc/wireguard/wgnet0.conf, substituting your droplet’s hostname or public IP (but not the floating IP) for www.example.com:

     [Interface]
     Address = 192.168.32.2/24
     PrivateKey = 
    
     [Peer]
     PublicKey = 
     PresharedKey = 
     AllowedIPs = 192.168.32.0/24
     Endpoint = www.example.com:51820
     PersistentKeepalive = 10
    
  1. Insert the public key we extracted in step 4 of the droplet configuration into the line that says PublicKey

  2. Insert the pre-shared key generated in step 3 of the droplet configuration into the line that says PresharedKey

  3. Generate a private key and insert it into the line that says PrivateKey:

     $ wg genkey
    
  1. Now, extract the public key from the private key you just generated, go back to the droplet and insert it into the line that says PublicKey:

     $ echo {private key} | wg pubkey
    

At this point, you should have two configuration files with everything filled in.

Go back to the DigitalOcean droplet now and get the service running.

  1. First open the service port in the firewall:

     $ sudo firewall-cmd --add-port=51820/udp --permanent
     $ sudo firewall-cmd --reload
    
  1. Enable and start the service

     $ sudo systemctl enable wg-quick@wgnet0.service
     $ sudo systemctl start wg-quick@wgnet0.service
    

Assuming you haven’t hit any errors, you should now have wireguard running on your droplet

On your roaming computer, get the service running.

  1. Enable and start the service

     $ sudo systemctl enable wg-quick@wgnet0.service
     $ sudo systemctl start wg-quick@wgnet0.service
    

Test the service by pinging 192.168.32.1 from your roaming computer and 192.168.32.2 from your DigitalOcean droplet. Assuming both work, congratulations, you’ve now setup a VPN between your two systems!

Step 3 - Forward ports from the roaming IP to your roaming computer

So now you have a floating IP on your DigitalOcean droplet and a VPN between the droplet and your roaming computer, so the final step is to put them together.

This process would be easier if DigitalOcean used different interfaces for the public IP and the floating IP, but they don’t, so we have to use firewalld’s rich rules to make this work.

First, figure out which ports you want to open up. We’ll just open the ssh port in this example.

On the droplet, do the following steps:

  1. Verify that you can ssh into the roaming computer:

     $ ssh user@192.168.32.2
    

    If this step fails, you’ve made a mistake in your ssh configuration, and fixing it is beyond the scope of this guide.

  2. Figure out the private address that traffic to the floating IP is coming to:

     $ ip addr show eth0
    

    Look for the line that begins with inet 10.x.x.x. 10.x.x.x is the IP address you’re looking for. On my system it’s 10.16.0.5, so that’s what I’m going to use for the rest of the example.

  3. Turn on masquerading for any traffic going over the VPN:

     $ sudo firewall-cmd --add-rich-rule "rule family=ipv4 destination address=192.168.32.2/32 masquerade" --permanent
    
  1. Forward the ports from the floating IP to the VPN, making sure to substitute the IP address you found in step 2 for 10.16.0.5:

     $ sudo firewall-cmd --add-rich-rule "rule family=ipv4 destination address=10.16.0.5/32 forward-port port=22 protocol=tcp to-port=22 to-addr=192.168.32.2" --permanent
    
  1. Repeat step four for any other ports you want open.

  2. Reload the firewall rules:

     $ sudo firewall-cmd --reload
    

Voilà! When you ssh into your floating IP, it should be forwarded to your roaming computer, while your droplet is still accessible on its public IP.

Security notice: you do not want to allow root to ssh into your system using a password. That’s just begging for someone to guess the password and get root access on your roaming computer. Setup SSH keys, and, at the minimum, make sure that root can only log in with an SSH key

One of the benefits of wireguard is that the client (in this case, the roaming computer) will automatically reconnect as it moves from network to network, so your roaming computer will automatically be available at the floating IP no matter where it is as long as it’s on the Internet.

Do note that DigitalOcean doesn’t seem to allow you to connect more than one floating IP to a droplet at a time, so you’ll be limited to one forwarded IP per droplet.

Enjoy your new static IP. If you run into any problems, please leave a message in the comments below.

Hacked!

With our school’s graduation ceremony last night, the school year is now officially finished. This year will definitely go down in my memory as the year that the students got the best of me… twice!

IP-gate

To give some background on the first “hack,” our current network uses a flat IP network with IP subnets used for each different set of machines (for organizational purposes). We don’t use IP-based security for obvious reasons, but we do use the subnets for deciding internet speed. IP addresses (fixed except for the guest subnet) are given out using DHCP, and each of the subnets except the guest subnet gets decent speed.

When I set up this system ten years ago, I was well aware of the obvious drawback: any person could set a static IP address on any subnet they chose, and, given our lack of managed switches (at the time we had none, though things are changing), there wasn’t much of anything I could do about it. On the flip side, the worst that could happen is that these users would get faster internet, hardly the end of the world.

It took ten years, but, finally, someone figured it out. One of our more intelligent students decided that his IP address of 10.10.10.113 didn’t make a whole lot of sense, given that the gateway is 10.10.1.1. He set his IP to 10.10.1.113, and, voilà, his internet speed shot through the roof!

Naturally, he shared his findings with his friends, who managed to keep it under the radar until one of the friends decided to see how well BitTorrent would work with the school internet. What none of these students realized is that the 10.10.1.* subnet was for servers, and, oddly enough, none of our servers uses BitTorrent. The traffic stuck out like a sore thumb, and I finally caught on.

My first step was to blacklist all unrecognized MAC addresses using the server subnet. The next step was more difficult. Now that the cat was out of the bag and everyone knew how to get faster internet, I needed a way to block anybody not using the IP they’d been assigned through our DHCP server. Obviously, there is a correct way of doing this, but that seems to be using 802.1x, and we’re just not there yet. My quick and dirty solution was to copy the dhcp configuration file containing all the host and IP information to our firewall, and then generate a list of iptables rules that only allow traffic through if the IP address matches the expected MAC address.

The problem with this solution is that it doesn’t account for the fact that spoofing MAC addresses is actually relatively simple, so it looks like one of my summer projects is going to be a complete revamp of our network. I’m hoping I can configure our FreeIPA server to also operate as the backend for a RADIUS server so we can implement 802.1x security.

In this case, the consequences of the “hack” for us were pretty insignificant. Students got some extra bandwidth for a while. The students who changed their IP addresses also didn’t suffer any major consequences. Their devices were blacklisted from the internet until they came to speak with me, and then were put on the guest subnet. All of the students were in their final year, so they were only stuck on the guest subnet for the last month or so.

The most obvious lesson I learned from “IP-gate” is that security through obscurity works great…until someone turns on the light. And when that happens, you’d better have a plan.

The Grade-changing Scandal

This was a far messier situation. One of our teachers allowed a student to access their computer to set up a video for class. On the computer, the teacher had saved their login credentials for LESSON, our web-based marking system. While the teacher was distracted, the student used this trick to find the teacher’s password, and then shared the password with different members of the class. Throughout the next few days, the class average for that teacher’s subjects rose at a remarkable rate.

Three days later, one of the students finally told the principal what had happened, and the principal called me. What followed was a day of tying together evidence from multiple sources to work out who changed what and when.

What the students weren’t aware of was that LESSON logs everything at the assignment level, so I could see which IP addresses changed which assignments. If the IP was an internal school address, I could also see which user changed the assignment. One of the students used their laptop (registered on the network, so I knew who it was) to change some marks, then logged in from a lab computer (so once again, I knew who it was), and then finally logged in from home.

The students who logged in from home were harder to track, at least until they did something foolish, like logging in as themselves to verify that the marks had actually changed ten seconds after logging out as the teacher.

We also do daily backups of the LESSON database that we keep for a full year, so it was a piece of cake to restore all of the marks back to their original scores.

Obviously though, this went much further than the IP-spoofing going in in “IP-gate.” This wasn’t just some kids wanting faster internet, this was a case of flagrant academic dishonesty.

In the end, we came up with the following consequences:

  • The students who masterminded the break-in received a zero for the subject for the term
  • The students who we caught changing the marks received zeros for any assignment of theirs that had a changed mark
  • The students we knew that they knew their marks were changed received three Saturday detentions (they have to sit in complete silence for four hours on a Saturday)
  • The students we suspected that they knew their marks were changed received one Saturday detention, though these students were allowed to appeal, and most who did had their Saturday detention reversed

One of the things I’ve learned from this is that there’s never too much audit information. LESSON is going to be changed to record not just who changes each assignment, but who changes each mark, and there will be a history of every changed mark so that teachers can see when marks are changed.

Apart from this, I would be curious as to what others think about the consequences for these two “hacks.” Were we too lenient on the first? Too harsh on the second? What should we have done differently? And what should we do differently going forward?

Laptop computer locked with chain and padlock by Santeri Viinamäki. Used under a CC BY-SA 4.0 license.