Warung.☕

Setting up Wireguard on Azure Virtual Machine

2020/05/29

There's an ARM template someone made that basically deploy an Ubuntu 18.04 VM with Wireguard installed and ready to use. Don't forget to modify AzureWireGuard.sh since the script will automatically generate a dozen of peer configs.

The simplest, important steps you need to do would be something like this:

But you do know that It's never gonna be that simple to do that.

Enjoy the ride.

Inbound rule

Azure has a section for managing Inbound rule under Networking tab. You need to add a rule to allow udp packets to the wireguard port. If there are some inbound rule previously set in your server, don't forget to move them to the internal firewall inside your system, since you are going to create a private network.

Setup firewall

Basically, add a firewall rule to accept UDP packets from wireguard port. Every distro has its own quick firewall config tool. For example, Ubuntu has ufw while Centos has firewall-cmd. Don't forget to allow ssh port too into the firewall.

By default, Ubuntu set it disabled and you can easily configure it like this

$ sudo ufw allow <wireguard_port>/udp
$ sudo ufw allow ssh
$ sudo ufw enable 

You can check it by running sudo ufw status

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
<wireguard_port>/udp       ALLOW       Anywhere
22/tcp                     ALLOW       Anywhere
<wireguard_port>/udp (v6)  ALLOW       Anywhere (v6)
22/tcp (v6)                ALLOW       Anywhere (v6)

If your machine use neither of those, you can manually add the rule to iptables

$ sudo iptables -A INPUT -p udp -m udp --dport <wireguard_port> -j ACCEPT

Make sure the INPUT chain policy is set to ACCEPT by execute sudo iptables -L

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere             udp dpt:<wireguard_port>
...

Consider check the iptables rule if you are unable to make a connection to the server (point-to-point) later on.

Enable IP forwarding

Packet forwarding only happens inside the machine, and not in the network interface Azure made in the different resource. That one is for handling the network between your public IP and your private IP.

Guess how long it took me to realize that.

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo sysctl -p

In some cases, sysctl might not update it when you restart the system. Usually, uncomment net.ipv4.ip_forward=1 on /etc/sysctl.conf solves the problem.

Install wireguard

Obligatory check official instruction to install wireguard

For Ubuntu distro, I'd suggest you to upgrade your distro to 20.04 and above instead, as it's the most minimum version wireguard officially supports and anything bellow that will be a backport package. Consider lots of bugs occured in the future and wait for them to officially release a stable build on lower versions, if you really want to.

Create wireguard configuration

Some keys are required to use Wireguard. To generate it, use wg command:

$ sudo wg genkey > pri
$ sudo wg pubkey < pri > pub
$ sudo wg genpsk > psk

Generating a pre-shared key (PSK) is considered optional and used for additional security features when you want to share a client configuration to other devices.

Take a look at this setup to configure a server and client configuration

// /etc/wireguard/server.conf
[Interface]
PrivateKey = <private_key>
Address = 10.0.0.1/22 // example
ListenPort = <wireguard_port>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;

[Peer]
PublicKey = <peer_public_key>
PreSharedKey = <psk_key>
AllowedIps = 10.0.0.2/32, 10.0.1.0/24 // example
PersistentKeepalive = 25

// /etc/wireguard/peer.conf
[Interface]
PrivateKey = <peer_private_key>
ListenPort = <peer_port>
Address = 10.0.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <server_public_key>
PresharedKey = <psk_key>
AllowedIPs = 0.0.0.0/0
Endpoint = <server_ip>:<wireguard_port>
PersistentKeepalive = 25

Some side notes:

Test the connection

On your server:

$ sudo wg-quick up <your_interface_name>
$ sudo wg show

On your device, just try connect it. Try to ping the server through wireguard tunnel

ping 10.13.13.1

then try ping to the internet

ping 1.1.1.1

if you got a reply on both of them, then congrats! You finally made a private network to the server.

Final setup

$ systemctl enable wg-quick@<your_interface_name>