Setting up a Wireguard VPN Server to Access Restricted Networks

By Fred Rybin

Introduction

If you are a student in RIT’s Computing Security Program or have taken classes that are a part of RIT’s Networking and Systems Administration Department, there is a good chance that you had to use RIT’s Remote Laboratory Emulation System (RLES) for one of your classes. RLES is a system used by RIT that allows students to conduct virtual machine labs similarly to the local labs on-campus from either inside or outside the RIT lab facility (Border).  This system has been essential for the continuation of classes during the covid pandemic and for students unable to access the labs in-person. And while it is a great system, it is not without its flaws, mainly the networking of the Virtual Machines (VMs) in RLES and the ways you can access these machines.

Issues with RLES

One of the main issues with RLES is that VMs in RLES are usually behind two or more layers of NAT. The problem with this is that while VMs may be able to access the external network, it becomes difficult for clients in the external network to access these VMs via IP Addresses. For students to be able to access these VMs from the external network, the only choice that they have is to use either the Remote Web Console or VMware Remote Console (VMRC) to connect to these VMs, which result in the second issue.

Connecting via the Remote Web Console or VMRC is an issue because you cannot copy and paste from your client machine to the VM host in RLES. This problem can waste time in doing an assignment by having issues when typing in commands or just having the keyboard malfunction and the console types in the same key multiple times in a row resulting in the user messing up the command or password they are typing in. In addition to this, if multiple users are trying to connect to VMs in RLES simultaneously, these consoles tend to slow down or freeze up while in use, affecting the students trying to complete their labs.

To solve these problems, I propose for students to set up their own Wireguard VPN tunnels into the RLES network that hosts their machines.

Why Wireguard?

As said on their website, “WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography and aims to be faster, simpler, leaner, and more useful than IPsec while avoiding the massive headache … WireGuard is designed as a general-purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances.” And like they say, it is simpler to set up than other similar VPN solutions while also being if not as fast but faster than other solutions. In addition, it is cross-platform and even part of the mainstream Linux kernel, making it easy to set up no matter which OS you are running it on, which is why I choose it for this project.

How to set up the Wireguard Server?

Requirements

  • One external machine that can be used as the Wireguard Server
    • In this case, it was a VM in my local network running CentOS 8, but it can be anything, even a VM running in AWS or GCP
  • One Host in RLES that has internet connectivity and is connected to your desired network
    • In this case, it was a Kali 2020 VM connected to the NAT network.
  • One Client to connect to the Wireguard Network that would like to access the NAT network
    • In this case, it was my Laptop running Arch Linux.

Server Setup

  • The first step is to install Wireguard onto the server following the official guide for whatever OS you are using.
    • In my case, I followed the Centos 8 Instructions and used Method 2  to install the packages onto my system.
  • Next, I added net.ipv4.ip_forward = 1 to the kernel parameters of the machine by running the following commands as root:
    • echo net.ipv4.ip_forward = 1′ > /etc/sysctl.d/99-custom.conf
    • sysctl -p /etc/sysctl.d/99-custom.conf
  • After enabling IPV4 Forwarding in the kernel, I then added the firewall rules to allow incoming connection on the UDP port Wireguard will be running on and added rules to the firewall to allow communication between the different zones
    • sudo firewall-cmd –permanent –add-port=31194/UDP –zone=public
      • In this case, UDP port 31194 is what I decided to use as my port for Wireguard.
      • This port needs to be accessible via a public IP Address
    •  sudo firewall-cmd –permanent –zone=public –add-masquerade
    •  sudo firewall-cmd –permanent –zone=internal –add-masquerade
    •  sudo firewall-cmd –permanent –add-interface=wg0 –zone=internal
    •  sudo firewall-cmd –reload
  • Now that IP forwarding and the Firewall rules are set, it is time to create the public and private keys for the Wireguard Server using the following commands:
    • cd /etc/wireguard
    • sudo sh -c ‘umask 077; wg genkey | tee privatekey | wg pubkey > publickey’
  • Now, with the port that Wireguard will be running on decided and it’s keys generated, you will create /etc/wireguard/wg0.conf with the following contents, substituting the variables as needed:
    • WIREGUARD_SUBNET: Can be any subnet as long as it is not used in your local network or the RLES network and needs to be a valid IP in that subnet since that is what the IP of the Wireguard server will be: Example 10.13.38.1/24
    • WIREGUARD_SERVER_PORT: Can be any port you would like to use. Example 31194
    • WIREGUARD_SERVER_PRIVATE_KEY: Was generated in the Previous Command: Can be found by using cat /etc/wireguard/privatekey
  • After creating /etc/wireguard/wg0.conf all you need to do is run sudo systemctl enable –now wg-quick@wg0, which will start the Wireguard server, and make it so that it automatically starts when the system boots up.
    • Running wg show wg0 should you get the following output to know if the server is running:
      • WIREGUARD_PUBLIC_KEY: Can be found by using cat /etc/wireguard/publickey

Now that the server is set up, the next step is to set up the peers

RLES Host Setup

  • The first step is to install Wireguard onto the host following the official guide for whatever OS you are using
    •  For the Kali VM, all I had to do is run sudo apt update and sudo apt install wireguard resolvconf -y
  • Next, I added net.ipv4.ip_forward = 1 to the kernel parameters of the machine by running the following commands as root to allow IPV4 forwarding:
    •  echo ‘net.ipv4.ip_forward = 1’ > /etc/sysctl.d/99-custom.conf
    •  sysctl -p /etc/sysctl.d/99-custom.conf
  • Now that IP forwarding is enabled and Wireguard is installed it is time to create the public and private keys for the Wireguard Host using the following commands
    •  cd /etc/wireguard
    •  sudo sh -c ‘umask 077; wg genkey | tee privatekey | wg pubkey > publickey’
  • Now with the keys generated, you will create /etc/wireguard/wg0.conf with the following contents, substituting the variables as needed
    •  WIREGUARD_HOST_PRIVATE_KEY: Was generated in the Previous Command: Can be found by using cat /etc/wireguard/privatekey
    •  WIREGUARD_HOST_IP: The IP of this host in the Wireguard Network: Example 10.13.38.2
    •  NETWORK_INTERFACE: The name of the network interface connected to the NAT network: can be found using ip a, Example eth0
    •  WIREGUARD_SERVER_PUBLIC_KEY: The public key of the Wireguard Server: can be found by running cat /etc/wireguard/publickey on the Wireguard Server that was previously setup
    •  WIREGUARD_SERVER_PORT: The port specified in the /etc/wireguard/wg0.conf on the Wireguard Server: Example 31194
    •  WIREGUARD_SERVER_PUBLIC_IP: The public IP in which the Wireguard Server’s port can be accessed on
    •  ALLOWED_IPS: In this case, it just needs to contain the WIREGUARD_SUBNET: Example 10.13.38.0/24
  • In addition to editing /etc/wireguard/wg0.conf on the host, /etc/wireguard/wg0.conf also needs to be modifed on the server:
    •  Run sudo systemctl stop wg-quick@wg0 on the server to temporarily stop the Wireguard server
    •  Modify /etc/wireguard/wg0.conf on the server by appending the following to the config
      • WIREGUARD_HOST_PUBLIC_KEY: The public key of the Wireguard Host: can be found by running cat /etc/wireguard/publickey on the Wireguard Host
      • NAT_SUBNET: The IP Subnet for the network in RLES: Example 192.168.0.0/16
  •  Run sudo systemctl stop wg-quick@wg0 on the server to temporarily start the Wireguard server
  • Finally, run sudo systemctl enable –now wg-quick@wg0 on the host, to bring up the Wireguard Client and try to ping the IP of the Wireguard Server: Example ping 10.13.38.1

Client Setup

Now that the Wireguard Server and RLES Host are set up, it is time to set up the Client that would be used to connect to the RLES Environment Externally

  • The first step is to install Wireguard onto the client following the official guide for whatever OS you are using
    •  For my Arch Client, all I needed to do was run sudo pacman -S wireguard-tools
  • Now that Wireguard is installed it is time to create the public and private keys for the Wireguard Client using the following commands
    •  cd /etc/wireguard
    •  sudo sh -c ‘umask 077; wg genkey | tee privatekey | wg pubkey > publickey’
  • Now with the keys generated, you will create /etc/wireguard/wg0.conf with the following contents, substituting the variables as needed
    •  WIREGUARD_CLIENT_PRIVATE_KEY: Was generated in the Previous Command: Can be found by using cat /etc/wireguard/privatekey
    •  WIREGUARD_CLIENT_IP: The IP of this client in the Wireguard Network: Example 10.13.38.3
  • In addition to editing /etc/wireguard/wg0.conf on the client, /etc/wireguard/wg0.conf also needs to be modifed on the server:
    •  Run sudo systemctl stop wg-quick@wg0 on the server to temporarily stop the Wireguard server
    •  Modify /etc/wireguard/wg0.conf on the server by appending the following to the config
      • WIREGUARD_CLIENT_PUBLIC_KEY: The public key of the Wireguard Client: can be found by running cat /etc/wireguard/publickey on the Wireguard Client
  •  Run sudo systemctl stop wg-quick@wg0 on the server to temporarily start the Wireguard server
  • Finally, run sudo systemctl start wg-quick@wg0 on the host, to bring up the Wireguard Client and try to ping the IP of the Wireguard Host: Example ping 10.13.38.2
    •  Also, try to ping a host in the RLES network: Example ping 192.168.206.49

Conclusion

With this, you now have network access into RLES and can access your boxes remotely via SSH or RDP and don’t have to mess with the Web Client or VMRC.

References

Border, Charles. “The Development and Deployment of a Multi-User, Remote Access Virtualization System for Networking, Security, and System Administration Classes.” Proceedings of the 38th SIGCSE Technical Symposium on Computer Science Education – SIGCSE ’07, Mar. 2007, doi:10.1145/1227310.1227501.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s