Setting up Wireguard on Azure Virtual Machine
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:
- Setup Inbound rule on your virtual machine
- Setup firewall
- Allow IP forwarding
- Install wireguard
- Create wireguard configuration
- Start wireguard
- Test the connection
- Finalize it
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:
- The first one is for your server, while the second one is for your device.
- This config is only for IPv4. assigning an IPv6 can be done on
Addressproperty and additional command onPostUpandPostDownto forward IPv6 packets. - There is no restriction on assign an interface address. you can just use
69.69.0.1/24and wireguard won't bat an eye at all. - If you don't have a public IPv6 address, just remove any
ip6tablespart inPostUpandPostDownand don't assign an IPv6 address on the interface. - You can use any interface name under the config filename. Put it on
/etc/wireguard/<your_interface_name>.conf - Make sure the default network interface your machine used. You can check it from
ip routeand look at the default. Usually, it is defaulted toeth0. Otherwise, wireguard can't forward your packet to the default interface. - This step is the one that took me pain in the ass because most of the problem was caused by incomplete configuration. So be careful!
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>