I just installed Roon Server on my laptop running Fedora 37 Workstation as a separate
roon user instead of the security insanity of the default Linux which installs and runs as the
root user. I did this before, it went a little smoother this time. Here are my notes, they extend Roon’s own Installing Roon on Linux documentation.
Disclaimer 1! If these commands don’t make sense (“do I enter the ‘%’?” “what is sudo?”), then don’t follow this, and take the risk by running the Easy install.
Disclaimer 2 This is an edited version of what I did omitting all the false starts and failed commands. I didn’t QA these by uninstalling and reverting everything and starting again from scratch following my own instructions.
I had them all installed already, but this should work in Fedora:
% sudo dnf install ffmpeg alsa-lib cifs-utils % dnf --cacheonly --installed info glibc
(the latter reports version the version of glibc installed is at version 2.36, high enough).
Create separate user “roon” who will own the files and run Roon Server (but can’t read or write my files).
% sudo useradd roon
Create a password for this user. (This might not be necessary, I’m inexpert about running commands as another user with
sudo --user=roon do-something.)
% sudo passwd roon (enter a password)
To make it easier to debug and view files, I added myself to the
roon group that
useradd creates along with the user
% sudo usermod -G roon $USER
Get the code
% cd /tmp % wget https://download.roonlabs.net/builds/RoonServer_linuxx64.tar.bz2
Unpack the code (It’s all under a RoonServer/ directory) as user roon
% su -l roon % cd /tmp % tar --bzip2 -xvf RoonServer_linuxx64.tar.bz2 % exit
install page says the Easy Installer installs to /opt/RoonServer, so move the files there. (I already had a
% sudo mv -i /tmp/RoonServer /opt/.
Set up the same /var/roon directory for the database and logs as the Easy Installer uses, make it owned by the
roon user and group
% sudo mkdir /var/roon % sudo chown roon:roon /var/roon
Run the check script (I don’t think you have to run this as the roon user).
% /opt/RoonServer/check.sh reports SUCCESS
At this point I ran the start script just to see if it starts.
% ROON_DATAROOT=/var/roon ./start.sh % less /var/roon/RoonServer/Logs/RoonServer_log.txt (look for errors)
I think I ran
kill PID to stop this temporary Roon Server test.
Setting up the firewalld rules for Roon Server
Fedora Workstation ships with firewalld and iptables. I chose to add a service to firewalld even though its user interface is confusing. I reused my old firewall settings for a Roon Server service from this thread, they’re in this gist . Save that somewhere as roon-server.xml, then tell firewalld about it with
% sudo firewall-cmd --permanent --new-service-from-file=/path/to/roon-server.xml
This copies the service to /etc/firewalld/services/ minus comments. I don’t think it actually enables it, but the GUI firewall configuration tool is hella confusing. I struggled with the firewall rule not working but then I couldn’t re-run because it was already present. So to be safe, try to unload (disable?) it with
% sudo firewall-cmd --remove-service=roon-server
Starting RoonServer as a systemd service
I edited the lines in the easy install’s roonserver-installer-linuxx64.sh script that create “SERVICE_FILE”, to create the following roonserver.service file:
[Unit] Description=RoonServer After=network-online.target [Service] Type=simple # I installed Roon so that it runs with user permissions instead of as root; # this required some SELinux fussing around, # and automounting network media drives probably won't work. User=roon Environment=SYSTEMD_LOG_LEVEL=debug Environment=ROON_DATAROOT=/var/roon Environment=ROON_ID_DIR=/var/roon # Enable/disable roon-server firewall rules before/after ('+' runs the commands as root). ExecStartPre=+/usr/bin/firewall-cmd --add-service=roon-server ExecStart=/opt/RoonServer/start.sh ExecStopPost=+/usr/bin/firewall-cmd --remove-service=roon-server Restart=on-abort [Install] ### Manual start. Or could run upon login as Roon user? ### WantedBy=multi-user.target
The key changes are:
- User=roon instead of root
- before starting Roon Server load the firewalld rules for roon-server (see earlier)
- the starting
+runs the command as root
- the starting
- when Roon Server stops, unload the firewalld rules so Roon Server’s mess of open ports are closed again
- I disable automatic start (“WantedBy”)
Copy this to where systemd can find it
% sudo cp -pi roonserver.service /etc/systemd/system/
Making SELinux happy
The first time I tried to run this systemd service, it failed. I got a warning about avc denial or something, was able to open the “SELinux Alert Browser” GUI tool, which told me about a problem with start.sh trying to run start.sh. Huh? But it also told me what to do to fix it:
% sudo /sbin/restorecon -v /opt/RoonServer/start.sh
restorecon is a SELinux command. Fedora Workstation runs Security Enhanced Linux, which enforces certain limitations on what programs can do. Like suggestions to “just disable the firewall,” any program that suggests disabling SELinux is being lazy.
You can also run
tail -f /var/log/audit/audit.log & to see if SELinux complains, though it’s hard to tell in its output.
Now I can start Roon Server with the usual
% systemctl start roonserver
systemd command. I can also check its status with
systemctl status roonserver, and stop it with
systemctl stop roonserver.
Giving the roon user access to my music
roon, I created a symlink to my music directory in
roon’s home directory:
% su -l roon % ln -s /path/to/my/Music/folder myMusic % ls -R ~/myMusic (should list all your music)
roon can’t see all your music, you need to change permissions or groups so that it can. In my case my music folder is on a Windows NTFS partition, and the listing command failed. I wound up changing my Windows NTFS partition’s mount line in
/etc/fstab so that the drive is mounted with the group ID of the
roon user. That means Roon Server can read but not write to my music folder.
Setting up Roon Server
With the Roon Server systemd service running, Roon Control running on my Android phone could find Roon Server over Wi-fi! (It remembered my old Roon server and prompted me to unauthorize/remove? it, which I did.) I pointed it to /home/roon/myMusic, songs started to appear in the UI, and I could play music to my Roon endpoints!
I have a really simple setup with no plug-ins, API use, subnets, ARC, network attached storage, music on removable flash drives, etc. These could probably require changes to the firewalld rules, and/or writing udev rules and helper scripts, and/or changing permissions so the
roon user can access other drives, and/or maybe further SELinux permissions adjustments.
But it’s working for me, and no matter what bugs and exploits are found in Roon’s code, I’ve limited the damage they can do by running as a separate user instead of as root.
I hope this helps. Sorry it’s so long. I saved it as a gist on GitHub. Corrections and comments welcome.