On my last trip out of the country, I discovered one of my banks would not let me access their system if I was outside the UK. I solved this in the short term by doing something insecure using vncserver and a UK-based server.

On my return to the UK, I decided I should setup a VPN on that same server (on the Oracle Cloud, always-free tier), to provide a more secure solution, should I need it again.

So, Wireguard. My travelling laptop runs Windows 10; there’s a Wireguard client for that, so no issue there.

Install and configure the server

To install Wireguard on Oracle Linux 8 use:

sudo dnf install wireguard-tools

There are some guides to configure Wireguard for Oracle Linux. I followed this one.

First, create the keys (as root):

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

Add the following two lines to /etc/sysctl.conf:

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

Then run sysctl -p to apply the changes.

The guide uses iptables to setup forwarding for Wireguard tunnel. I didn’t want to use iptables, as the firewall on the server is firewalld. More about this later. In the first instance, I went with this for the server configuration in /etc/wireguard/wg0.conf:

[Interface]
Address = 192.168.1.1/24
SaveConfig = false
ListenPort = 51820
PrivateKey = (redacted)
[Peer]
PublicKey = (redacted)
AllowedIPs = 192.168.1.2/32

This sets the server IP to 192.168.1.1 and expects the one and only peer (client) to have address 192.168.1.2.

The matching client configuration is (as defined in the Windows Wireguard client):

[Interface]
PrivateKey = (redacted)
Address = 192.168.1.2/32
DNS = 8.8.8.8, 8.8.4.4
[Peer]
PublicKey = (redacted)
AllowedIPs = 0.0.0.0/0, ::/128
Endpoint = server.address.co.uk:51820

The configuration specifies the Google DNS, as at home I use my internal DNS, which would not be accessible once the VPN was up. Wouldn’t be an issue if my laptop was elsewhere, of course.

I read somewhere that I had to add the DNS server addresses, specifed by the client, to the allowedIPs list. Did that, so the wg0.conf line now looked like this:

AllowedIps = 192.168.1.2/32, 8.8.8.8/32, 8.8.4.4/32

Why is it that following random advice from the Internet leads to pain and heartbreak?

Firewalld setup

For the existing firewall setup, I’d used the pre-existing public zone to add open ports. Based on this post I moved them all to the external zone and added the wireguard port and the ethernet port:

firewall-cmd --zone=external --add-port=51820/udp
firewall-cmd --zone=external --add-interface=ens3
firewall-cmd --zone=external --remove-service=ssh

(Oh, and removed the default ssh service; I have that defined in the trusted zone). The external zone has masquarade turned on by default, so that should allow VPN client traffic to get to the internet.

Running the VPN

I started the VPN server with:

wg-quick up wg0

Seemed to start OK.

Then started the Wireguard client. It claimed it was connected, but the log showed no handshakes were received. That’s when I remembered I had not opened the wireguard port (51280/udp) on the Oracle Cloud firewall. Once I’d done that and reactivated the client, the tunnel was up.

I could ping the endpoint, but I could not access any websites from the browser on the laptop. I found I could use curl to access websites by IP adress, but not by name. Hmm, a DNS problem?

I tried various fixes, searched the web, but nothing seemed to fix the issue. Then, by accident, I discovered that I could not use nslookup to access the 8.8.8.8 while the VPN was up. Perhaps putting the DNS addresses in the AllowedIPs was not sensible after all? I removed the DNS addresses from AllowedIPs, restarted the wireguard server and DNS worked.

Firewall changes for Oracle Linux 9

I tried the same Wireguard setup on a new VPS on the Oracle Cloud, running Oracle Linux 9. The tunnel came up and I could ping the server from the client, but no traffic from the client was forwarded to the internet.

After some research, I stumbled on an article about a zone’s default target. It seems that if the ingress and egress zones are both default and the ingress zone doesn’t explicitly allow access, the target becomes DROP.

I therefore added the wireguard interface to the internal zone and enabled the ports that VPN clients would use (e.g. 80, 443 …​). Note, you could also just set a target of ACCEPT to accept all ports from the wireguard port.

firewall-cmd --zone=internal --add-interface=wg0
firewall-cmd --zone=internal --add-port=53/udp
firewall-cmd --zone=internal --add-port=53/tcp
firewall-cmd --zone=internal --add-port=80/tcp
firewall-cmd --zone=internal --add-port=443/tcp

Now clients could access the internet through the Oracle Linux 9 Wireguard VPN.