2 Configuring a VPN by Using WireGuard

WireGuard is a cross-platform technology that enables you to create a VPN setup that's simple, fast, but secure through its implementation of the latest cryptography.

Note:

WireGuard is supported beginning with Unbreakable Enterprise Kernel Release 6 Update 3. Ensure that the system is upgraded to this release or later before proceeding to the steps in this chapter. For more information, see Unbreakable Enterprise Kernel Release 6 Update 3: Release Notes (5.4.17-2136).

Installing WireGuard

To configure a VPN with WireGuard, download the package with the following command:

sudo dnf install -y wireguard-tools

You must install WireGuard on the server and all its clients.

Configuring WireGuard

For simplicity, the following sections describe how to deploy WireGuard by using two hosts as examples. One host functions as the VPN server while the other is a client.

To use WireGuard, you need the following requirements:

  • IP addresses of both hosts. Use the ip addr sh command to obtain this information. For the procedures that follow, the IP address of the server is 10.0.0.1 and the IP address of the client is 10.0.0.2.

  • Private IP addresses to be assigned to the WireGuard interfaces of both hosts. For the procedures that follow, the private IP address of the server is 192.168.2.1 and the private IP address of the client is 192.168.2.2.

  • Name of the WireGuard interface. For the procedures that follow, the Wireguard interface name of both server and client is wg0.

  • Console connections to the client.

    Instructions for setting up console connections is outside the scope of this documentation. To use a VNC server for remote connections, see https://docs.oracle.com/en/learn/install-vnc-oracle-linux/#introduction. If you're using an instance in Oracle Cloud Infrastructure, see https://docs.oracle.com/iaas/Content/Compute/References/serialconsole.htm#Instance_Console_Connections.

On the server

  1. Edit the /etc/sysctl.conf file with the following changes:

    net.ipv4.ip_forward = 1
  2. Run the sysctl command to reread the /etc/sysctl.conf file.

    sudo sysctl -p

    You can disregard the error messages that might appear about the command not being able to perform stat.

  3. Create a directory where you can store the WireGuard key pair, for example:

    mkdir ~/.wireguard
    cd ~/.wireguard
    umask 077
  4. In the directory you created, generate a WireGuard cryptographic key pair.

    You can specify any preferred names for the files to contain the server's private and public keys.

    wg genkey | tee privatekey | wg pubkey > publickey
  5. Obtain the server's private and public keys and store them in a temporary storage.

    cat ~/.wireguard/privatekey
    cat ~/.wireguard/publickey

On the client

  1. Create a directory where you can store the WireGuard key pair, for example:

    mkdir ~/.wireguard
    cd ~/.wireguard
    umask 077
  2. In the directory you created, generate a WireGuard cryptographic key pair.

    You can specify any preferred names for the files to contain the client's private and public keys.

    wg genkey | tee privatekey | wg pubkey > publickey
  3. Obtain the client's private and public keys and store them in a temporary storage.

    cat ~/.wireguard/privatekey
    cat ~/.wireguard/publickey
  4. Edit the /etc/wireguard/wg0.conf file to contain the following:

    [Interface]
    Address = 192.168.2.2/24
    SaveConfig = true
    ListenPort = 60477
    PrivateKey = client's private key
    
    [Peer]
    PublicKey = server's public key
    AllowedIPs = 0.0.0.0/0, ::/0
    Endpoint = 10.0.0.1:51820

On the server

  1. Edit the /etc/wireguard/wg0.conf file to contain the following:

    [Interface]
    Address = 192.168.2.1/24
    SaveConfig = true
    PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE
    PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eno1 -j MASQUERADE
    ListenPort = 51820
    PrivateKey = server's private key
    [Peer]
    PublicKey = client's public key
    AllowedIPs = 192.168.2.2/32
    Endpoint = 10.0.0.2:60477

    Note:

    In the PostUp and PostDown lines of the example, the server's interface name is eno1. Ensure that you specify the correct interface name of your server for those same lines. To display the server's IP interface, run the ip addr sh command.

Enabling the WireGuard Tunnel

  1. Start the tunnel on the server.

    wg-quick up wg0
    [#] ip link add wg0 type wireguard
    [#] wg setconf wg0 /dev/fd/63
    [#] ip link set mtu 1420 up dev wg0
    [#] ip -4 route add 192.168.2.2/32 dev wg0
    [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING
     -o eno1 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables 
    -t nat -A POSTROUTING -o eno1 -j MASQUERADE
  2. Check the status of the tunnel in the server.

    sudo wg
    interface: wg0
       public key: server's public key
       private key: (hidden)
       listening port: 51820
    
    peer: client public's key
      endpoint: 10.0.0.2:60477
      allowed ips: 192.168.2.2/32
  3. On a separate terminal window, log in to the client by using a console connection.

    From this point on, all network traffic is routed through the tunnel. If you're logged in to the client through SSH and then issue the command to start the tunnel, that connection becomes lost. You can only reconnect to the client through a console connection.

  4. Start the tunnel on the client.

    wg-quick up wg0
    [#] ip link add wg0 type wireguard
    [#] wg setconf wg0 /dev/fd/63
    [#] ip -4 address add 192.168.2.2/24 dev wg0
    [#] ip link set mtu 1420 up dev wg0
    [#] ip -6 route add ::/0 dev wg0 table 51820
    [#] ip -6 rule add not fwmark 51820 table 51820
    [#] ip -6 rule add table main suppress_prefixlength 0
    [#] ip6tables-restore -n
    [#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
    [#] ip -4 rule add not fwmark 51820 table 51820
    [#] ip -4 rule add table main suppress_prefixlength 0
    [#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
    [#] iptables-restore -n
  5. Check the status of the client.

    sudo wg
    interface: wg0
       public key: client's public key
       private key: (hidden)
       listening port: 60477
       fwmark: 0xca6c
    
    peer: server public's key
      endpoint: 10.0.0.1:51820
      allowed ips: 0.0.0.0/0, ::/0

You can use other commands to check the tunnel information, such as ip addr sh and ip link, for example:

ip addr sh
...
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8920 qdisc noqueue state UNKNOWN group default 
   qlen 1000 link/none 
   inet 192.168.2.1/24 scope global wg0
     valid_lft forever preferred_lft forever
ip link
...
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 8920 qdisc noqueue state UNKNOWN mode DEFAULT group 
   default qlen 1000 link/none

Testing the WireGuard Tunnel

On the client, use the ping command to check communications with the WireGuard server, for example:

ping -c 3 192.168.2.1
ping -c 3 192.168.2.1

PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data.
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=0.640 ms
64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=0.707 ms
64 bytes from 192.168.2.1: icmp_seq=4 ttl=64 time=0.643 ms

--- 192.168.2.1 ping statistics ---
3 packets transmitted, 4 received, 0% packet loss, time 2088ms
rtt min/avg/max/mdev = 0.643/0.690/0.713/0.038 ms

Likewise, the wg command indicates whether a connection to the WireGuard tunnel is established, as shown in the following example:

sudo wg
interface: wg0
  public key: client's public key
  private key: (hidden)
  listening port: 60477
  fwmark: 0xca6c

peer: server's public key
  endpoint: 10.0.0.1:51820
  allowed ips: 0.0.0.0/0, ::/0
  latest handshake: 44 seconds ago
  transfer: 28.22 KiB received, 48.64 KiB sent

The handshake and transfer output show the traffic in the tunneled connection.

If communications between the server and the client can't be established, check if the firewall might be blocking access to the ports that have been set up for WireGuard. You might need to open the ports to link both server and client. For example, you would type the following commands on the server:

sudo firewall-cmd --add-port=51820/udp --permanent
sudo firewall-cmd --reload

Shutting Down the WireGuard Tunnel

To shut down the WireGuard tunnel, type the following command on both server and client.

wg-quick down wireguard-interface

After shutting down, you can optionally check the status of the tunnels by using one of the commands that have been provided elsewhere in this document, such as wg, ip addr, or ip link.