X

News, tips, partners, and perspectives for the Oracle Linux operating system and upstream Linux kernel work

How to setup WireGuard on Oracle Linux

Guest Author

Oracle Linux engineer William Kucharski provides an introduction to the VPN protocol WireGuard

 

WireGuard has received a lot of attention of late as a new, easier to use VPN mechanism, and it has now been added to Unbreakable Enterprise Kernel 6 Update 1 as a technology preview.

But what is it, and how do I use it?

What is WireGuard?

WireGuard is described by its developers as:

an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache.

(You can read the full statement from the developers here.)

Though IPsec works well and is indeed a standard for secure communication, it can be difficult to configure and use for those not familiar with network administration.

By comparison, WireGuard is reasonably easy to set up, and "aims to be as easy to configure and deploy as SSH."

Linus Torvalds paid it perhaps the ultimate compliment on LKML not too long before the code was merged into the 5.6 kernel:

Can I just once again state my love for it and hope it gets merged soon? Maybe the code isn’t perfect, but I’ve skimmed it, and compared to the horrors that are OpenVPN and IPSec, it’s a work of art.

If you are curious about the inner workings of WireGuard, you can read the protocol in the original technical whitepaper.

If you prefer video, a nice session on WireGuard was given at the 2018 Linux Plumber's Conference in Vancouver, viewable here.

How does it work?

Quoting its authors:

WireGuard associates tunnel IP addresses with public keys and remote endpoints.

When the interface sends a packet to a peer, it does the following:

  1. This packet is meant for 192.168.30.8. Which peer is that? Let me look... Okay, it's for peer ABCDEFGH. (Or if it's not for any configured peer, drop the packet.)
  2. Encrypt entire IP packet using peer ABCDEFGH's public key.
  3. What is the remote endpoint of peer ABCDEFGH? Let me look... Okay, the endpoint is UDP port 53133 on host 216.58.211.110.
  4. Send encrypted bytes from step 2 over the Internet to 216.58.211.110:53133 using UDP.

When the interface receives a packet, this happens:

  1. I just got a packet from UDP port 7361 on host 98.139.183.24. Let's decrypt it!
  2. It decrypted and authenticated properly for peer LMNOPQRS. Okay, let's remember that peer LMNOPQRS's most recent Internet endpoint is 98.139.183.24:7361 using UDP.
  3. Once decrypted, the plain-text packet is from 192.168.43.89. Is peer LMNOPQRS allowed to be sending us packets as 192.168.43.89?
  4. If so, accept the packet on the interface. If not, drop it.

Behind the scenes there is much happening to provide proper privacy, authenticity, and perfect forward secrecy, using state-of-the-art cryptography.

Let's see a sample configuration!

The following assumes you have WireGuard installed on the machines you've decided to use as your client and server, and that the two machines can connect to one another.

You can verify WireGuard is installed by using the following commands:

rpm -qa | grep wireguard
modinfo wireguard

The first should show that the package wireguard-tools is installed and the second should show information on the wireguard kernel module.

For the sake of simplicity, I will demonstrate a configuration using IPv4 addresses, though the parameters in the setup files will support IPv6 addresses.

Assume the current IP addresses for the two systems' eno1 interfaces are:

  • 10.0.0.1 server
  • 10.0.0.2 client

and we want to use WireGuard addresses of:

  • 192.168.2.1 server
  • 192.168.2.2 client

you would follow these steps:

Server Configuration, Part One

Start by generating a crypto key pair: a public key and a private key.

Run the following commands on the machine you've selected as your server as root.

If your system does not allow logins as root, add sudo commands as necessary:

cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey

This will generate the initial private and public crypto keys needed to start the tunnel and store them in the files privatekey and publickey respectively.

Next, edit the file /etc/sysctl.conf and make the following changes (note that depending upon your prior configuration, these values may have already been set elsewhere in the file and you may need to edit those lines appropriately):

net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Then use the sysctl command to make the system reread the /etc/sysctl.conf configuration file:

sysctl -p

(You can safely ignore any errors that are output about files that sysctl cannot stat.)

Client Configuration

As you did for the server, you will need to generate a crypto key pair:

cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Now edit the file /etc/wireguard/wg0.conf to read:

[Interface]
Address = 192.168.2.2/24
SaveConfig = true
ListenPort = 60477
PrivateKey = <contents of /etc/wireguard/privatekey>

[Peer]
PublicKey = <contents of the server's /etc/wireguard/publickey file>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = 10.0.0.1:51820

Server Configuration Part Two and Bringup

Edit the file /etc/wireguard/wg0.conf so that it looks like this:

[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; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -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; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eno1 -j MASQUERADE
ListenPort = 51820
PrivateKey = <contents of /etc/wireguard/privatekey>

[Peer]
PublicKey = <contents of the client's /etc/wireguard/publickey file>
AllowedIPs = 192.168.2.2/32
Endpoint = 10.0.0.2:60477

That's it!

Run the wg-quick command to start the server:

wg-quick up wg0

you will see output something like:

[#] 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

At this point, you can confirm the status of the interface by using the wg command, which will generate output like:

# wg
interface: wg0
   public key: _server public key_
   private key: (hidden)
   listening port: 51820

peer: <client public key>
  endpoint: 10.129.135.30:60477
  allowed ips: 192.168.2.2/32

Client Bringup

The next step is to activate the secure tunnel that will tunnel all of your client's network traffic, encrypted, through the server.

Be sure to be on the console when you perform this operation.

As all network traffic will now be routed through the tunnel, if you run these commands while connected via ssh you will lose your connection and will not be able to reconnect except by logging in on the machine's console.

As on the server, use the wg-quick command:

wg-quick up wg0

you will see output that looks like:

[#] 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

Again, you can check on the status of the client using the wg command, which will generate output similar to:

# wg
interface: wg0
   public key: <client public key>
   private key: (hidden)
   listening port: 60477
   fwmark: 0xca6c

peer: <server public key>
  endpoint: 10.0.0.1:51820
  allowed ips: 0.0.0.0/0, ::/0

  

Use

At this point, the tunnel should be up and functioning, and you should be able to issue network commands from your client machine and have them operate as usual, except traffic will be going through the WireGuard tunnel to the server.

Once you have performed network operations from the client, the wg command will show usage data in addition to the configuration information it showed earlier.

For example, a ping might look like this:

# ping oracle.com
PING oracle.com (137.254.16.101) 56(84) bytes of data.
64 bytes from bigip-ocoma-cms-adc.oracle.com (137.254.16.101): icmp_seq=1 ttl=240 time=41.9 ms
64 bytes from bigip-ocoma-cms-adc.oracle.com (137.254.16.101): icmp_seq=2 ttl=240 time=42.0 ms

--- oracle.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 2002ms
tt min/avg/max/mdev = 32.074/32.085/32.106/0.014 ms

# wg
interface: wg0
  public key: <client public key>
  private key: (hidden)
  listening port: 60477
  fwmark: 0xca6c

peer: <server public key>
  endpoint: 10.0.0.1:51820
  allowed ips: 0.0.0.0/0, ::/0
  latest handshake: 3 seconds ago
  transfer: 1.56 KiB received, 756 B sent
  

You can see that the latest handshake was three seconds ago with 1,560 bytes received from and 756 bytes sent to the tunneled connection.

Client Teardown

To close the tunnel and restore normal network operation, use the wg-quick command:

# wg-quick down wg0
[#] wg showconf wg0
[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip -6 rule delete table 51820
[#] ip -6 rule delete table main suppress_prefixlength 0
[#] ip link delete dev wg0
[#] iptables-restore -n
[#] ip6tables-restore -n

Server Teardown

To shut down the WireGuard server, once again the wg-quick command is used:

# wg-quick down wg0
[#] wg showconf wg0
[#] ip link delete dev wg0
[#] iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eno1 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eno1 -j MASQUERADE

Conclusion

As with any network protocol, connection details are precise, but WireGuard definitely is much easier to configure and use than IPsec. Further, a variety of clients are available for other operating systems as well allowing you to provide secure communications for an entire organization quite easily as compared to other methods.

This factor alone may make WireGuard a de facto standard for VPN creation in the near future.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.