With the help of @Aaron_Turner, I managed to get Roon working over WireGuard VPN. Below you can find the steps I took to get it all to work. For more general background info, check this thread.
Some Assumptions
The software in use:
- wireguard-vyatta-ubnt v1.0.20200908-v1.0.20200827
- udp-proxy-2020 v0.0.5
- UniFi Controller v6.0.27
The networks in use:
- The public WAN ip address of the USG is 12.34.56.78 (eth0)
- The corporate LAN network of the USG is 10.0.0.1/24 (eth1)
- The WireGuard VPN network of the USG is 10.0.1.1/24 (wg0)
Authentication:
- The USG is configured with an SSH key (~/.ssh/id-usg).
Conventions:
- Command line statements are prefixed with a dollar sign ($). Do not copy/paste the dollar sign!
- Insert the actual content of the specified file each time you see "(see ).
Installing WireGuard on USG
Download the package ugw3-v1 to your computer:
$ wget https://github.com/WireGuard/wireguard-vyatta-ubnt/releases/download/1.0.20200908-1/ugw3-v1-v1.0.20200908-v1.0.20200827.deb
Upload the package via SSH to the USG:
$ scp -i ~/.ssh/id-usg ugw3-v1-v1.0.20200908-v1.0.20200827.deb admin@10.0.0.1:
Login to your USG over SSH and install the deb package:
$ ssh -i ~/.ssh/id-usg admin@10.0.0.1
$ sudo dpkg -i ugw3-v1-v1.0.20200908-v1.0.20200827.deb
Configure WireGuard on client
Generate a public/private keypair for the client:
$ wg genkey | tee wg.private | wg pubkey > wg.public
Create a WireGuard config file for the client:
[Interface]
PrivateKey = (see wg.private on client)
Address = 10.0.1.2/32
DNS = 10.0.0.8
[Peer]
PublicKey = (see wg.public on usg)
AllowedIPs = 10.0.0.0/24, 10.0.1.0/24
Endpoint = 12.34.56.78:51820
Configure WireGuard on USG
Generate a public/private keypair for the WireGuard server:
$ wg genkey | tee /config/auth/wg.key | wg pubkey > wg.public
In a first stage, weâll just configure the USG over CLI. These instructions do no survive a USG reboot/reprovision, and are solely to test our configuration. On the USG run:
$ configure
# Set up the wg0 interface.
set interfaces wireguard wg0 address 10.0.1.1/24
set interfaces wireguard wg0 listen-port 51820
set interfaces wireguard wg0 route-allowed-ips true
set interfaces wireguard wg0 private-key /config/auth/wg.key
# Set up the allowed peers (ie. clients).
set interfaces wireguard wg0 peer (see wg.public on usg) allowed-ips 10.0.1.2/32
# Setting up the firewall rules
set firewall name WAN_LOCAL rule 20 action accept
set firewall name WAN_LOCAL rule 20 protocol udp
set firewall name WAN_LOCAL rule 20 description 'WireGuard'
set firewall name WAN_LOCAL rule 20 destination port 51820
commit
save
exit
At this stage, you should have a working WireGuard setup. You can verify that a network interface (wg0) has been created and configured with the following commands:
$ sudo wg show
interface: wg0
public key: (see pg.public on usg)
private key: (see /config/auth/wg.key on usg)
listening port: 51820
peer: (see wg.public on client)
endpoint: (hidden)
allowed ips: 10.0.1.2/32
latest handshake: 1 hour, 31 minutes, 49 seconds ago
transfer: 29.85 MiB received, 381.29 MiB sent
persistent keepalive: every 25 seconds
$ sudo wg showconf wg0
[Interface]
ListenPort = 51820
PrivateKey = (see /config/auth/wg.key on usg)
[Peer]
PublicKey = (see wg.public on client)
AllowedIPs = 10.0.1.2/32
Endpoint = (hidden)
PersistentKeepalive = 25
Go ahead and try to connect fom the client to your network over WireGuard VPN. (Note that Roon still requires some more configuration.)
Once you verified that everything works, itâs time to make the changes persistent (so you wonât loose them when the USG is rebooted/reprovisioned).
Locate the exact location where the UniFi Controller expects a config.gateway.json for your site. See USG Advanced Configuration Using config.gateway.json for more info.
Create/edit the config.gateway.json. Make sure it contains this section:
{
"interfaces": {
"wireguard": {
"wg0": {
"address": [
"10.0.1.1/24" // USG gateway address in wireguard subnet
],
"firewall": {
"in": {
"name": "LAN_IN"
},
"local": {
"name": "LAN_LOCAL"
},
"out": {
"name": "LAN_OUT"
}
},
"listen-port": "51820", //Listen port - can be customised, adjust firewall port accordingly
"mtu": "1500",
"peer": [{
"(see wg.public on usg)": { //Peer 1 Public Key
"allowed-ips": [
"10.0.1.2/32" //Peer IP address
],
"persistent-keepalive": 25
}
}],
"private-key": "/config/auth/wg.key",
"route-allowed-ips": "true"
}
}
}
}
To avoid any issues with your USG, make sure the config.gateway.json is a valid JSON file. You can use an online validator to check (e.g. https://jsonlint.com). Do not skip this step or hell might break loose.
Routing network packages across subnets / interfaces
Download the package udp-proxy-2020 for mips arch to your computer:
wget https://github.com/synfinatic/udp-proxy-2020/releases/download/v0.0.5/udp-proxy-2020-0.0.5-linux-mips64-static
Upload the package via SSH to the USG:
scp -i ~/.ssh/id-usg udp-proxy-2020-0.0.5-linux-mips64-static admin@10.0.0.1:
Login to your USG over SSH and make it executable:
$ ssh -i ~/.ssh/id-usg admin@10.0.0.1
$ mkdir -p ~/bin/
$ mv udp-proxy-2020-0.0.5-linux-mips64-static p ~/bin/udp-proxy-2020
$ chmod +x ~/bin/udp-proxy-2020
Now itâs time to start udp-proxy-2020. We basically want to route packages from 10.0.0.0/24 (eth1) to 10.0.1.0/24 (wg0) and vice versa. Given that Roon broadcasts on port 9003 we can execute:
sudo ./udp-proxy-2020 --port 9003 --interface eth1,wg0
As a last step, we need to make sure that udp-proxy-2020 runs whenever the USG reboots. This can be done by creating a new script at /config/scripts/post-config.d/udp-proxy-2020.sh:
#!/usr/bin/env bash
/home/admin/.bin/udp-proxy-2020 --port 9003 --interface eth1,wg0 &
Now change the owner to root and make it executable:
$ sudo chown root:root /config/scripts/post-config.d/udp-proxy-2020.sh
$ sudo chmod +x /config/scripts/post-config.d/udp-proxy-2020.sh
Thatâs it! Weâre all set! Now for the moment weâve all been waiting for, itâs finally time to see whether Roon works over WireGuard VPN:
- Disconnect the client from the local network (e.g disable wifi on your phone)
- Turn on WireGuard VPN on the client (e.g. flip the VPN switch on your phone)
- Open up Roon Remote and see whether it can find your Core and stream to the client
Pics or it didnât happen:
Changelog
2020/10/17:
- Add instructions on how to start udp-proxy-2020 after each boot of the USG
2020/10/17:
- Initial version