How I got Roon working over OpenVPN (hard for me, easy for you)

Since you said you’re using a Raspi4 which is arm64, you’d want the arm64 one I believe. Sorry, I don’t have a RasPi4 to test myself. If that doesn’t work, try the arm32 version.

Honestly, that’s the easy part. The harder part is configuring Wireguard and udp-proxy-2020. This thread will likely help you some, but it’s for Ubiquiti USG and not a RasPi running linux: How to: Roon Mobile over WireGuard on a UniFi USG

Sorry, I don’t have a fancy GUI or super-easy install mode for this… as you can tell, there are at least a dozen different configurations people are using and they’re all different.

That’s how far I had come Aaron. Then I indeed run into the more difficult part: How to configure udp-proxy-2020 on Ubuntu.

If I fail with Ubuntu I will be using dietpi just like Francesco.

Hmmm… i probably could/should create a systemd config file for it. that would help a lot.

Hi Francesco, care to share a bit more about your setup on dietpi?
I’ve Wireguard installed on dietpi, 32 bit version, on pi4. Using dietpi-software, didn’t tailer anything.
And I use this command to start udp-proxy-2020:

./udp-proxy-2020 --port 9003 --interface eth0,wg0 --debug --cachettl 300

And then when starting roon over vpn, I am not able to see any player configurations for the remote device.
However I do see messages being catched and forwarded:

> DEBU[0167]/build/udp-proxy-2020/cmd/listen.go:332 main.(*Listen).learnClientIP() wg0: Learned client IP: 10.6.0.3             
> DEBU[0167]/build/udp-proxy-2020/cmd/listen.go:128 main.(*Listen).handlePackets() wg0: received packet and fowarding onto other interfaces 
> DEBU[0167]/build/udp-proxy-2020/cmd/send.go:32 main.(*SendPktFeed).Send() eth0: sending out because we're not wg0      
> DEBU[0167]/build/udp-proxy-2020/cmd/listen.go:153 main.(*Listen).sendPackets() processing packet from wg0 on eth0           
> DEBU[0167]/build/udp-proxy-2020/cmd/listen.go:290 main.(*Listen).sendPacket() eth0 => 192.168.188.255: packet len: 140: ffffffffffffdca63
> ...
> DEBU[0168]/build/udp-proxy-2020/cmd/listen.go:153 main.(*Listen).sendPackets() processing packet from eth0 on wg0           
> DEBU[0168]/build/udp-proxy-2020/cmd/listen.go:128 main.(*Listen).handlePackets() eth0: received packet and fowarding onto other interfaces 
> DEBU[0168]/build/udp-proxy-2020/cmd/send.go:32 main.(*SendPktFeed).Send() wg0: sending out because we're not eth0      
> DEBU[0168]/build/udp-proxy-2020/cmd/listen.go:290 main.(*Listen).sendPacket() wg0 => 10.6.0.3: packet len: 126: 4500007ec33b40004011f041c0

So somehow, I have the idea udp-proxy-2020 is doing what it should, but I don’t have the ability to play music via Roon on my laptop as vpn client, which I do have at the local wifi.(I can control the Roon endpoints in the house, just not the laptop over vpn.)
So did you tailer the WireGuard setup, or added some more networking routes, or something similar?

Hi,

I am starting udp-proxy-2020 in a very similar way:

udp-proxy-2020 --port 9003 --interface eth0,wg0 --cachettl 500

I am using a systemd script which I am happy to share if it can help, but the final command is this one.

An important thing is that the iPhone must be visible from the Roon core. In my case, the internal network is 192.168.0.x, WireGuard network is 10.6.0.x, the RPi4 is 192.168.0.172.

Hope this helps,
Francesco

From the server (iMac), the phone in the VPN must be reachable.
Try to ping it (i.e. ping 10.6.0.2). If not, add the route table with:

sudo route add -net 10.6.0.0/24 192.168.0.172

To be honest, sometimes I struggle to see the iPhone as output device in vpn. I had this problem while writing this message and I increased the cachettl from 180 to 500, restarted the service and it now works.

Hi, Thanks.

The script would help, would be the next to sort out, so would be nice, but I’m not there yet. First I want to get it to work (manually…)
And it might be that the issue is more related to WireGuard and linux routing and firewalling in general than to dup-proxy-2020.
My network layout is similar to yours:
Internal network is 192.168.188.x, WireGuard network is 10.6.0.x, the RPi4 is 192.168.0.100.
One difference I see is that my Roon core is on Rock, so I’m not able to play around with network settings and routes on that box.

Ping from vpn-client to systems in the internal network works.
Ping from the pi with WireGuard to the vpn client also works.
Ping from any other system on the internal network to the vpn client does not work.
I’ve tried adding a route on the router, pointing the 10.6.0.0 network to the 192.168.188.100, but this didn’t improve the situation.
I’ve also tried some post-up iptables rule from another wireguard guide but that didn’t help either. I’m not really experienced with that part, so that might cost me some more trial and learning. Do have the idea though that it has to be something with accepting packets, like the ping, at eth0 and routing it into the vpn. Looks like sessions initiated from vpn work, but initiated from local lan does not.

Sounds like this would a problem? it’s not on your local network of 192.168.188.x ? Maybe you meant 192.168.188.100 ?

Since you’re using a Rock, everything else sounds about right. Your primary router needs a route to 10.6.0.x to the RasPi so the Rock can talk to 10.6.0.x network.

The other thing that might cause this problem is that your RasPi is doing NAT. That would explain why machines on the VPN can ping the local network, but not the other way around. An easy way of testing for this is run tcpdump -ni eth0 icmp and look at the IP addresses in the icmp-echo messages. One should be the host on the local net, the other should be the 10.6.0.x network. If instead you see the IP address of the RasPi, it’s doing NAT via iptables.

You can also check for any NAT rules by running the iptables -nvL -t nat command

Oops, indeed a mistake, the Pi is on my local network 192.168.188.100.

And the iptables nat output :

DietPi:~# iptables -nvL -t nat
Chain PREROUTING (policy ACCEPT 32303 packets, 3848K bytes)
 pkts bytes target     prot opt in     out     source               destination         
25378 2286K DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 31582 packets, 3804K bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain POSTROUTING (policy ACCEPT 73214 packets, 6683K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2    80 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
   34  2186 MASQUERADE  all  --  *      eth0    10.6.0.0/24          0.0.0.0/0            /* wireguard-nat-rule */
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:9000

Chain OUTPUT (policy ACCEPT 76989 packets, 7007K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    4   160 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:9002 to:172.17.0.2:9000
DietPi:~# 

So there are some NAT rules, now the question is how that is the problem and how it can be solved? And here isn’t my experience so that would require some investigating.
There are some rules related to Docker. On this Pi also the Roon Extension Manage is installed with some extension in Docker.

Am I correct in thinking this will only work with Wireguard or OpenVPN and not the standard L2TP/IPSEC VPN on the Unifi UDM Pro?

Just want to make sure I’m not barking up the wrong tree!

I looked into that before I went with the Wireguard approach. The vpn tunnel is not exposed as a network interface (which is what udp-proxy-2020 needs).

1 Like

Yes, that was what I figured, but wanted to be sure I wasn’t missing something.

Thanks!

Hi Aaron, have you been able to create something in the meantime?

haven’t gotten to it yet to be honest. mostly just because it’s more work writing the docs so people know how to use it is actually more work than creating the file. I also need to update the scripts for pfSense because the latest release (2.5.0) broke the current scripts.

I understand Aaron, I think it’s great that you make it possible anyway.

Okay, here’s some totally untested systemd startup config. be sure to read the README on how to configure it. udp-proxy-2020/startup-scripts at startup-scripts · synfinatic/udp-proxy-2020 · GitHub

Assuming someone says it works for them, I’ll see about merging it.

Also, the above also includes updated rc.d script for FreeBSD 12.x and pfSense 2.5.0.

@Aaron_Turner, I installed on pfSense v2.5.0 and initially ran into an error. I believe you have a typo in step 1 of the instructions.

Instructions

  1. Edit etc/local/etc/udp-proxy-2020.conf as necessary
  2. Copy files to the directories on your pfSense/BSD box
  3. Edit /etc/rc.conf.local and add the line udp_proxy_2020_enable=YES
  4. Copy udp-proxy-2020 binary to /usr/local/etc/bin/udp-proxy-2020

When I went to run, I got the following error.
.: cannot open /usr/local/etc/udp-proxy-2020.conf: No such file or directory

So I moved udp-proxy-2020.conf to /usr/local/etc/udp-proxy-2020.conf

That worked.

My client is an iPhone 12 mini running the WireGaurd app.

Thanks for your efforts. So far it works great. I’ve been driving around this afternoon. Listening to Roon in my car. This is awesome!

1 Like

Some questions and feedback.

  1. Does udp-proxy-2020 support multiple clients/peers? I can’t get a second iPhone to see Roon. VPN is connected. I can get to ROCK status page via Safari but Roon App says Core is not found. If I disconnect the first VPN client, the second one finds Core but never shows up as an audio zone.

  2. 90% of the time when I get a single VPN client connected, they are still missing from audio zone. Restarting the iPhone fixes this but that is very inconvenient. Since I’m on pfSense is there something I can do (configuration or script) to remedy. It is like UDP packets from Core are being broadcast to the VPN clients but VPN clients are not communicating back and letting Roon Core they are available.

What is the correct way to stop und-proxy-2020? I tried /usr/local/etc/rc.d/udp-proxy-2020 stop but get an error.
Unable to kill udp_proxy_2020. Missing pid file?

How best to verify ump-proxy-2020 is running on the pfSense router? I’ve tried looking at processes us ps and top and don’t see it. The service -e command shows it but I don’t think that let’s me know it is running. Does it?

I’ve added an entry to shellcmd to start ump-proxy-2020 on boot. I also added entries to cron to stop and start the process once a week.

  1. For multiple clients on the same VPN… well you’d have to specify their IP’s on the CLI.
  2. Try restarting the Roon app, not the phone.

the command:
ps auxww | grep udp-proxy-2020

Will show you if the service is running without relying on the script.

as for shell commands/ cron jobs… I don’t do that and it’s stable for me on my pfSense box. You should just need to use /etc/rc.conf.local like I’ve documented. Perhaps your cron job isn’t working correctly and ends up killing udp-proxy-2020? That would explain your error above.

A note for those having issues seeing iPhones as an endpoint when connecting via Wireguard…

I initially tried setting up OpenVPN and Wireguard on my NUC (where my Roon Core also runs - both not in containers). A lot of fiddling around and while I could get things to work sometimes, it was very flakey. Although I could play with my iPhone and Macbook as an endpoint out of the house. Huzzah!

So I tried setting up a dedicated rPi as a wireguard server using this great guide, that uses PiVPN. Setup was ridiculously easy, and everything worked perfectly running the udp-proxy-2020 script. Except…I couldn’t use my iPhone or Macbook as an endpoint. Fiddled with a few things but nothing seemed to help.

So as a last-ditch effort I tried running the PiVPN process on the NUC, wondering if having the VPN and Core on the same machine would help the endpoint issue. PiVPN on the NUC worked perfectly (much easier than any other guide I’ve found), I imported profiles to my Macbook and iPhone, and it works perfectly. I’ve even set it up to only access my local network (and DNS) over wireguard so that my internet traffic isn’t all going through my home network.

It seemed to work perfectly without the udp-proxy-2020 script. But my experience is that eventually the device loses the core and can’t find it again until you’re back in the home network. So I’m running it and all seems to be working fine.