Please, please FreeBSD gurus, I need your help! šŸ™

Will the gods finally send help? :pray: Trying to figure out custom FreeBSD ā€œrc.d servicesā€ has stumped me.

Hereā€™s the setup:

  • TrueNAS Core 13.3
  • Jail based on FreeBSD 13.3

The application in question, which works 100% if I run it manually:


This works 100% (web UI, connecting to the Soulseek network, searching, downloading, etc):

su soulseek -c "/opt/slskd/slskd --app-dir=/home/soulseek/.local/share/slskd"

As you would expect, it runs the executable /opt/slskd/slskd as the user soulseek, with the flag --app-dir correctly pointing to /home/soulseek/.local/share/slskd. It properly reads my settings from the configuration file slskd.yml.

By all accounts, the software ā€œjust worksā€.

So, like with my other jails, I want to this to automatically start with the jail as a ā€œserviceā€.

I borrowed a similar packageā€™s ā€œrc.dā€ config (amuled), and modified it for slskd. I figured nothing fancy is involved, and so it should work pretty much the same.

/usr/local/etc/rc.d/slskd
#!/bin/sh

# PROVIDE: slskd
# REQUIRE: NETWORKING
# BEFORE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable slskd at startup
# slskd_enable (bool): Set to "NO" by default.
#                Set it to "YES" to enable slskd
# slskd_user (str): Set to user running slskd
#                    (default 'soulseek')

. /etc/rc.subr

name="slskd"
rcvar=slskd_enable

load_rc_config $name

: ${slskd_enable="NO"}
: ${slskd_user:="soulseek"}
: ${slskd_config:="/home/${slskd_user}/.local/share/slskd"}

pidfile="${slskd_config}/slskd.pid"
procname="/opt/slskd/slskd"
required_files="${slskd_config}/slskd.yml"
command="/usr/sbin/daemon"
command_args="-f -p ${pidfile} ${procname} --app-dir=${slskd_config}"

run_rc_command "$1"

Here is my rc.conf file (which is pretty plain):

/etc/rc.conf
cron_flags="$cron_flags -J 15"

# Disable Sendmail by default
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

# Run secure syslog
syslogd_flags="-c -ss"

ifconfig_epair0b="SYNCDHCP"

# Soulseek
slskd_enable="YES"
slskd_user="soulseek"

The result?

:heavy_check_mark: The service starts!

:heavy_check_mark: I am able to login to the web UI on the default port 5030!

:heavy_check_mark: The web UI is fully functional!

:heavy_check_mark: All my settings (slskd.yml) are loaded properly!

:heavy_check_mark: The process is owned by the user soulseek!

So whatā€™s the problem?

:warning: It cannot connect to the outside world. The log reveals this error:
ā€œFailed to resolve address ā€˜vps.slsknet.orgā€™: Name does not resolveā€

Now thatā€™s interesting because:

  • As the user soulseek, I can absolutely ping vps.slsknet.org
  • When I run the application (slskd) manually, it has no issues connecting to the Soulseek network.

For some reason, running it as a service/daemon blocks its access to the outside internet.

Just to reiterate and to repeat this again: Everything works when it starts as a service, except for outside connectivity.

As you can see, Iā€™m stumped. Any and all help would be greatly appreciated. :+1:


  1. slskd is a dotNET application that serves as a web UI frontend for the Soulseek P2P network. It is supported on Linux by its upstream developers, however, FreeBSD ā€œsupportā€ is quite new, and requires building it yourself. (Needless to say, it works 100% if I manually invoke the command slskd) ā†©ļøŽ

Itā€™s not the best way but why not run your command as a cron task with @reboot. You could set your command up as a script and run the script @reboot from cron. I do this in one of my jails and it works fine.

@reboot sh /path/to/script

2 Likes

I had thought about that (or something similar), but I would lose out on the serviceā€™s ā€œstart, stop, restartā€ control while in a running jail. (Not too big of a deal, but itā€™s still something that offers better control, especially when you need to troubleshoot without restarting the jail or finding PIDā€™s to kill.)

Even if I have to resort to that, Iā€™m still very interested why Iā€™m facing this issue as explained in the opening post.

I feel like Iā€™m missing something obvious.

NOTE: Iā€™ve only read the initial post once (but didnā€™t look at any code). When I got to the part about ā€œ.NETā€ I started typing this reply. I will go back and re-read after I ask a dumb question.

A shot in the dark: have you tried allow.mlock=1?

Already enabled. I do it for all jails that will run a dotNET application, including Jellyfin.

If you read the entire original post, youā€™ll see that slskd works 100% (including the web UI, connecting to the Soulseek network, searching, downloading, etc) if I manually invoke the command.

But if I invoke it as a service (whether restarting the jail or using service slskd start), everything worksā€¦ except it has no connectivity to the internet.

ā€¦I donā€™t know the 1st thing about FreeBSD but system permissions are not the same as user permissions hence the manual with user permissions has connectivity to all network but system would have to have declared permissions.
But again, I donā€™t know BSD but am sure is something along those lines.

If I set the service to run as root, it behaves the same: everything works, except outside internet connectivity

Doesnā€™t matter if I point it to a fresh config or my existing config.

I can confirm the process is running as the root user, and that the web UI is fully functional.

But sadly, the same thing: ā€œFailed to resolve address ā€˜vps.slsknet.orgā€™: Name does not resolveā€

I recently had an issue with Meshcentral that would prevent ā€œnpmā€ access when the command was run as the ā€œmeshcentralā€ user. I could run it manually just fine as well, but not as the ā€œmeshcentralā€ user. Still unsure why, but try thisā€¦

In the daemon command use ā€œ-u soulseekā€ right after the ā€œ-fā€ switch. That is what fixed my Meshcentral service.

ā€¦that would run it with that userā€™s permissions ( if my guess is right )

It would yes, but the actual daemon command is run by root I believe. I just know that doing it that way works for my specific use case.

In FreeBSD service scripts, when you have ā€œservice_userā€ defined, it will run the command (daemon in most cases) as that user. But it fails to be able to do certain functions in certain cases. Setting the -u option seems to work though for such cases.

2 Likes

This actually did the trick! :confetti_ball:


It ā€œworksā€, but itā€™s kind of a bummer. :confused: Whatā€™s the point of the modularity of ā€œservice_userā€ if some services need to specify the user anyways with the -u flag?

I thought the whole point of the ā€œservice_userā€ variable was essentially to run the daemon under a different user / privilege level. By ā€œhard codingā€ something like -u soulseek, it seems to take away this flexibility.


EDIT: Wait! Instead of -u soulseek I should be able to pass to it -u ${slskd_user} ?

Iā€™ll test that out.

2 Likes

ā€¦I run ( different OS ) a webserver and do so in a limited permissions user. The idea is that if anything goes wrong, and an adversary get to exploit a bug the damage is limited to what that user has access to. Therefore the action of running code ( the program ), from a security point of view, is better with user rights than system ( call it ā€œgod modeā€ )
ā€¦thinking out loud hereā€¦

did -u ${slskd_user} work ?

The problem with having ā€œservice_userā€ defined is that it will try to run the service as that user. Thats just how service scripts work.

So, you will essentially have ā€œsoulseekā€ executing the daemon command and trying to then also run whatever comes after as ā€œsoulseekā€
This will result in ā€œfailed to set user environmentā€

I just add an extra variable called ā€œservice_daemon_userā€ that I then use as a user variable.

You could also just try setting the ā€œservice_userā€ variable, then remove the daemon part of the command and just run the actual command as the actual user. Sort of likeā€¦

#!/bin/sh

# PROVIDE: slskd
# REQUIRE: NETWORKING
# BEFORE: DAEMON
# KEYWORD: shutdown
#
# Add the following lines to /etc/rc.conf to enable slskd at startup
# slskd_enable (bool): Set to "NO" by default.
#                Set it to "YES" to enable slskd
# slskd_user (str): Set to user running slskd
#                    (default 'soulseek')

. /etc/rc.subr

name="slskd"
rcvar=slskd_enable

load_rc_config $name

: ${slskd_enable="NO"}
: ${slskd_user:="soulseek"}
: ${slskd_config:="/home/${slskd_user}/.local/share/slskd"}

required_files="${slskd_config}/slskd.yml"
command="/opt/slskd/slskdā€
command_args="--app-dir=${slskd_config}"

run_rc_command "$1"

This results in the same behavior: everything works except internet access. :confused:

But the other way works? Using the -u?

I have to try again. (It worked when I tried it the first time you shared the idea.) I think Iā€™m hitting a roadblock to configure it how it once worked (using -u).

But I might have to resume tomorrow.

I think it would be wise not to run a P2P application as root (even in a jail.)

It hasnā€™t been a problem with other applications, including Jellyfin, qBittorrent, aMule, and MLdonkey.

Is it possible that something within the application itself is ā€œnon-FreeBSD friendlyā€, and hence exhibiting this behavior? That even though it works when run manually (executing the command), it might have something within that is incompatible (or quirky) if trying to invoke it via ā€œrc.dā€?

1 Like

Not from my experience. Others might chime inā€¦

This works without issue:

soulseek@soulseek:~ $ crontab -l
@reboot /opt/slskd/slskd --app-dir=$HOME/.local/share/slskd

Youā€™ll notice itā€™s the crontab for my user soulseek, and it still works to run on ā€œrebootā€. (Which means ā€œupon jail startā€ in my case.)

Fully functional, and a working internet connectivity. :+1:


But I donā€™t want to ā€œendā€ this thread. I still want to know how to create a custom rc.d script that can be used as service, which also has internet connectivity.

2 Likes

You said here that this works. Can you confirm or deny these allegations?