Skip to content

Support us

Authors: fire1ce | Created: 2022-06-25 | Last update: 2022-08-05

Wireguard VPN

WireGuard® is 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. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances. Initially released for the Linux kernel, it is now cross-platform (Windows, macOS, BSD, iOS, Android) and widely deployable. It is currently under heavy development, but already it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry.

Github Repository: wireguard-vyatta-ubnt


A guide on installing and using the WireGuard kernel module and tools on Ubiquiti UnifiOS routers (UDM, UDR, and UXG).

Installation

  1. Download the latest release for UnifiOS. Use the correct link in the command below

    curl -Lfo UnifiOS-wireguard.tar.gz https://github.com/WireGuard/wireguard-vyatta-ubnt/releases/download/${RELEASE}/UnifiOS-${RELEASE}.tar.gz
    
  2. Extract the files to your data directory and run the setup script.

    • For the UDM/P or UXG-Pro, extract the files into /mnt/data/wireguard

      tar -C /mnt/data -xvf UnifiOS-wireguard.tar.gz
      /mnt/data/wireguard/setup_wireguard.sh
      
    • For the UDM-SE or UDR, extract the files into /data/wireguard

      tar -C /data -xvf UnifiOS-wireguard.tar.gz
      /data/wireguard/setup_wireguard.sh
      
  3. The setup script will load the wireguard module, and setup the symbolic links for the wireguard tools (wg-quick and wg). You can run dmesg to verify the kernel module was loaded. You should see something like the following:

    [13540.520120] wireguard: WireGuard 1.0.20210219 loaded. See www.wireguard.com for information.
    [13540.520126] wireguard: Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
    

Now you should be able to create a wireguard interface. Please see usage below.


Compatibility

The wireguard module and tools included in this package have been tested on the following Ubiquiti devices:

  • Unifi Dream Machine (UDM) and UDM-Pro 0.5.x, 1.9.x, 1.10.x, 1.11.x.
  • UDM-SE and Unifi Dream Router (UDR) 2.2.x
  • UniFi Next-Gen Gateway (UXG-Pro) 1.11.x

Note that for the UDM, UDM Pro, and UXG-Pro, Ubiquiti includes the wireguard module in the official kernel since firmware 1.11.0-14, but doesn't include the WireGuard tools. The setup script in this package will try to load the built-in wireguard module if it exists first.


Upgrade

  1. Unload the wireguard module.

    rmmod wireguard
    
  2. Re-install wireguard by following the Installation instructions above to get the latest version.


Uninstallation

  1. Delete the wireguard files from your data directory.

    rm -rf /mnt/data/wireguard
    
  2. Delete the wireguard tools and any boot scripts.

    rm /usr/bin/wg /usr/bin/wg-quick
    

Usage

Read the documentation on WireGuard.com for general WireGuard concepts. Here is a simple example of a wireguard server configuration for UnifiOS.

  1. Create the server and client public/private key pairs by running the following. This will create the files privatekey_server, publickey_server and privatekey_client1, publickey_client1. These contain the public and private keys. Store these files somewhere safe.

    wg genkey | tee privatekey_server | wg pubkey > publickey_server
    wg genkey | tee privatekey_client1 | wg pubkey > publickey_client1
    
  2. On your UDM/UDR, create a wireguard config under /etc/wireguard named wg0.conf. Here is an example server config. Remember to use the correct server private key and the client public key.

    [Interface]
    Address = 10.0.2.1/24
    PrivateKey = <server's privatekey>
    ListenPort = 51820
    
    [Peer]
    PublicKey = <client's publickey>
    AllowedIPs = 10.0.2.2/32
    
  3. For your client, you will need a client config like the following example. Remember to use the correct client private key and the server public key.

[Interface]
Address = 10.0.2.2/32
PrivateKey = <client's privatekey>

[Peer]
PublicKey = <server's publickey>
Endpoint = <server's ip>:51820
AllowedIPs = 10.0.2.0/24
  • Adjust Address to change the IP of the client.
  • Adjust AllowedIPs to set what your client should route through the tunnel. Set to 0.0.0.0/0,::/0 to route all the client's Internet through the tunnel. See the WireGuard documentation for more information.
  • Note each different client requires their own private/public key pair, and the public key must be added to the server's WireGuard config as a separate Peer.
  1. To bring the tunnel up, run wg-quick up <config>. Verify the tunnel received a handshake by running wg.
wg-quick up /etc/wireguard/wg0.conf
  1. To bring down the tunnel, run wg-quick down <config>.
wg-quick down /etc/wireguard/wg0.conf
  1. In your UniFi Network settings, add a WAN_LOCAL (or Internet Local) firewall rule to ACCEPT traffic destined to UDP port 51820 (or your ListenPort if different). Opening this port in the firewall is needed so remote clients can access the WireGuard server.

Routing

The AllowedIPs parameter in the wireguard config allows you to specify which destination subnets to route through the tunnel.

If you want to route router-connected clients through the wireguard tunnel based on source subnet or source VLAN, you need to set up policy-based routing. Currently, there is no GUI support for policy-based routing in UnifiOS, but it can be set up in SSH by using ip route to create a custom routing table, and ip rule to select which clients to route through the custom table.

For a script that makes it easy to set-up policy-based routing rules on UnifiOS, see the split-vpn project.


Binaries

Prebuilt binaries are available under releases.

The binaries are statically linked against musl libc to mitigate potential issues with UnifiOS' glibc.


Persistence on Reboot

The setup script must be run every time the system is rebooted to link the wireguard tools and load the module. This can be accomplished with a boot script.

  • For the UDM or UDM Pro, install UDM Utilities on-boot-script by following the instructions here, then create a boot script under /mnt/data/on_boot.d/99-setup-wireguard.sh and fill it with the following contents. Remember to run chmod +x /mnt/data/on_boot.d/99-setup-wireguard.sh afterwards.

    Click here to see the boot script.

    #!/bin/sh
    /mnt/data/wireguard/setup_wireguard.sh
    
  • For the UDM-SE or UDR, create a systemd boot service to run the setup script at boot. Create a service file under /etc/systemd/system/setup-wireguard.service and fill it with the following contents. After creating the service, run systemctl daemon-reload && systemctl enable setup-wireguard to enable the service on boot.

    Click here to see the boot service.

    [Unit]
    Description=Run wireguard setup script
    Wants=network.target
    After=network.target
    
    [Service]
    Type=oneshot
    ExecStart=sh -c 'WGDIR="$(find /mnt/data/wireguard /data/wireguard -maxdepth 1 -type d -name "wireguard" 2>/dev/null | head -n1)"; "$WGDIR/setup_wireguard.sh"'
    
    [Install]
    WantedBy=multi-user.target
    
  • Note this only adds the setup script to start at boot. If you also want to bring your wireguard interface up at boot, you will need to add another boot script with your wg-quick up command.


Troubleshooting

Setup script returns error "Unsupported Kernel version XXX" * The wireguard package does not contain a wireguard module built for your firmware or kernel version, nor is there a built-in module in your kernel. Please open an issue and report your version so we can try to update the module.
wg-quick up returns error "unable to initialize table 'raw'" * Your kernel does not have the iptables raw module. The raw module is only required if you use `0.0.0.0/0` or `::/0` in your wireguard config's AllowedIPs. A workaround is to instead set AllowedIPs to `0.0.0.0/1,128.0.0.0/1` for IPv4 or `::/1,8000::/1` for IPv6. These subnets cover the same range but do not invoke wg-quick's use of the iptables raw module.

Credits

Original work to compile WireGuard on UnifiOS by @tusc (wireguard-kmod).

"WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.


The built-in gateway DNS does not reply to requests from the WireGuard tunnel

  • The built-in dnsmasq on UnifiOS is configured to only listen for requests from specific interfaces. The wireguard interface name (e.g.: wg0) needs to be added to the dnsmasq config so it can respond to requests from the tunnel. You can run the following to add wg0 to the dnsmasq interface list:
echo "interface=wg0" > /run/dnsmasq.conf.d/custom_listen.conf
killall -9 dnsmasq
  • You can also those commands to PostUp in your wireguard config's Interface section to automatically run them when the tunnel comes up, e.g.:
 PostUp = echo "interface=%i" > /run/dnsmasq.conf.d/custom_listen.conf; killall -9 dnsmasq
 PreDown = rm -f /run/dnsmasq.conf.d/custom_listen.conf; killall -9 dnsmasq

Comments