I ran into some issues when trying to configure an OpenVPN tunnel between my Ubiquiti USG Pro 4 and a Debian VPS. I was very disappointed to discover that the version of OpenVPN on the USG only supports TLS 1.0! My issue was the Debian side rejecting that as insecure.
Thankfully, it was fairly painless to get Wireguard configured on the USG Pro 4. I was hesitant to do so at first because I knew every time my USG was updated I would lose the wireguard pacakge. Fortunately that can be resolved by configuring a post-install script. Thanks to ilar.in and calypte.cc and this github gist for the steps on how to do so.
curl -O https://raw.githubusercontent.com/britannic/install-edgeos-packages/master/install-pkgs
sudo install -o root -g root -m 0755 install-pkgs /config/scripts/post-config.d/install-pkgs
- Add wireguard DEB package to persistent storage that the script will look for:
sudo mkdir -p /config/data/install-packages
cd /config/data/install-packages
curl -fLSs https://github.com/WireGuard/wireguard-vyatta-ubnt/releases/download/1.0.20200729-1/ugw4-v1-v1.0.20200729-v1.0.20200513.deb
- Generate a public/private keypair for USG use
cd /config/auth
umask 077
wg genkey > wg_private.key
wg pubkey < wg_private.key > wg_public.key
- Generate config.gateway.json config to use wireguard
"interfaces": {
...
"wireguard": {
"wg0": {
"address": "<IP_OF_USG_ON_WG_CLIENT_SUBNET>",
"listen-port": "<WG_LISTEN_PORT>",
"peer": {
"<ENDPOINT_CLIENT_PUBLIC_KEY>": {
"allowed-ips": "0.0.0.0/0",
"endpoint": "<ENDPOINT_CLIENT_ADDRESS>:<ENDPOINT_CLIENT_PORT>
"
}
},
"private-key": "/config/auth/priv.key",
"route-allowed-ips": false
},
"wg1": {
"address": "<IP_OF_USG_ON_WG_SERVER_SUBNET",
"firewall": {
"in": {
"name": "LAN_IN"
},
"local": {
"name": "LAN_LOCAL"
},
"out": {
"name": "LAN_OUT"
}
},
"listen-port": "<USG_WG_SERVER_LISTEN_PORT>",
"mtu": "1352",
"peer": {
"<PUBLIC_KEY_OF_WG_CONNECTING_CLIENT": {
"allowed-ips": "<SUBNETS_ON_REMOTE_HOST>"
}
},
"private-key": "/config/auth/wg-server.priv",
"route-allowed-ips": true
}
}
},
I have two different wireguard interfaces configured – wg0 to be a client to another server, and wg1 to be a server accepting other clients (site-to-site VPN.)
If you want to have multiple peers defined on a single wireguard interface, encapsulate the peers with brackets like so:
"peer": [{
"--pubkey--": {
"allowed-ips": [
"172.255.252.2/32"
],
"persistent-keepalive": 60
}
},
{
"--pubkey--": {
"allowed-ips": [
"172.255.252.3/32"
],
"persistent-keepalive": 60
}
}
],
Test configuration first
Before committing your config.gateway.json code, test it line by line by SSHing into the USG-Pro 4 and entering config mode. Then type out your JSON lines one at a time, with each key being a new argument separated by a space. The first section above would look like this:
configure
edit interfaces
set wireguard wg0 address WIREGUARD_ADDRESS
set wireguard wg0 listen-port WG_LISTEN_PORT
set wireguard wg0 peer ENDPOINT_CLIENT_PUBLIC_KEY allowed-ips 0.0.0.0/0
set wireguard wg0 peer ENDPOINT_CLIENT_PUBLIC_KEY endpoint ENDPOINT_ADDRESS:ENDPOINT_PORT
set wireguard wg0 private-key /config/auth/priv.key
set wireguard wg0 route-allowed-ips false
commit
If the commit works without error, you can then drop out of the configure section and look at your wireguard config:
exit
sudo wg show
If all looks well, then copy your config.gateway.json to your controller and trigger a reprovision.
Verify after provisioning:
sudo netstat -npl | grep <WIREGUARD_PORT> | grep udp
Troubleshooting
USG not connecting to changed endpoint address
If you change the address of the wireguard endpoint, USG pro will not connect to that new address. You have to delete and re-create the interface (thanks to https://github.com/Lochnair/vyatta-wireguard/issues/72#issuecomment-423840448 for the information)
Fix this by deleting the wireguard interface
admin@Firewall:~$ configure
[edit]
admin@Firewall# delete interfaces wireguard
[edit]
admin@Firewall# commit
Then reprovision by making a small change, force provision, then change back, and force another provision (annoying) or alternatively reboot firewall.
Wireguard shows established but ping doesn’t work
Example error:
From 10.99.13.1 icmp_seq=5 Destination Host Unreachable
ping: sendmsg: Required key not available
To figure out what’s going on, enable logging to kernel buffer (dmesg) Thanks to procustodibus.com for the info.
echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
With debug on, ping again and check kernel messages (dmesg)
[Tue Dec 21 22:16:12 2021] wireguard: wg0: No peer has allowed IPs matching 10.99.13.2
This showed I didn’t have my access control properly configured. Modify /etc/wireguard/wg0.conf on your client config and make sure your AllowedIPs are properly letting traffic through.
AllowedIPs = 10.99.13.0/24
USG not allowing connections
Clients unable to connect to USG despite having a good config. Double check your firewall rules. I had neglected to create a WAN LOCAL rule allowing UDP packets on my wireguard port. Once that was configured, handshakes completed successfully.
Firewalls can’t ping each other
I had an issue where the firewalls would pass traffic through, but they couldn’t ping each other. The solution was to add the VPN subnet you created to allowed-ips on both sides of the connection.