Solved MeshCentral RC service script help

I've formulated an rc script for meshcentral, and have a question.

Why would this work
Code:
#!/bin/sh
#
# MeshCentral FreeBSD Service Script
#
#

# PROVIDE: meshcentral
# REQUIRE: NETWORKING
# KEYWORD: shutdown

. /etc/rc.subr

name=meshcentral
desc="MeshCentral Computer Management"
rcvar=meshcentral_enable

load_rc_config $name

: ${meshcentral_enable:="NO"}
: ${meshcentral_args:=""}
: ${meshcentral_chdir:="/usr/local/meshcentral"}
: ${meshcentral_rundir:="/var/run/${name}"}
: ${meshcentral_logdir:="/var/log/${name}"}
: ${meshcentral_pidfile:="${meshcentral_rundir}/${name}.pid"}
: ${meshcentral_logfile:="${meshcentral_logdir}/${name}.log"}

user="meshcentral"
group="meshcentral"
node="/usr/local/bin/node"
command="/usr/sbin/daemon"
command_args="-u ${user} -P ${meshcentral_pidfile} -H -o ${meshcentral_logfile} ${node} node_modules/${name} ${meshcentral_args}"

start_precmd="meshcentral_startprecmd"

meshcentral_startprecmd()
{
    if [ ! -d ${meshcentral_rundir} ]; then
        install -d -o ${user} -g ${group} ${meshcentral_rundir};
    else
        chown -R ${user}:${group} ${meshcentral_rundir};
    fi
    if [ ! -d ${meshcentral_logdir} ]; then
        install -d -o ${user} -g ${group} ${meshcentral_logdir};
    else
        chown -R ${user}:${group} ${meshcentral_logdir};
    fi
}

run_rc_command "$1"

But this wont
Code:
#!/bin/sh
#
# MeshCentral FreeBSD Service Script
#
#

# PROVIDE: meshcentral
# REQUIRE: NETWORKING
# KEYWORD: shutdown

. /etc/rc.subr

name=meshcentral
desc="MeshCentral Computer Management"
rcvar=meshcentral_enable

load_rc_config $name

: ${meshcentral_enable:="NO"}
: ${meshcentral_args:=""}
: ${meshcentral_chdir:="/usr/local/meshcentral"}
: ${meshcentral_rundir:="/var/run/${name}"}
: ${meshcentral_logdir:="/var/log/${name}"}
: ${meshcentral_pidfile:="${meshcentral_rundir}/${name}.pid"}
: ${meshcentral_logfile:="${meshcentral_logdir}/${name}.log"}
: ${meshcentral_group:="meshcentral"}
: ${meshcentral_user:="meshcentral"}

node="/usr/local/bin/node"
command="/usr/sbin/daemon"
command_args="-u ${meshcentral_user} -P ${meshcentral_pidfile} -H -o ${meshcentral_logfile} ${node} node_modules/${name} ${meshcentral_args}"

start_precmd="meshcentral_startprecmd"

meshcentral_startprecmd()
{
    if [ ! -d ${meshcentral_rundir} ]; then
        install -d -o ${meshcentral_user} -g ${meshcentral_group} ${meshcentral_rundir};
    else
        chown -R ${meshcentral_user}:${meshcentral_group} ${meshcentral_rundir};
    fi
    if [ ! -d ${meshcentral_logdir} ]; then
        install -d -o ${meshcentral_user} -g ${meshcentral_group} ${meshcentral_logdir};
    else
        chown -R ${meshcentral_user}:${meshcentral_group} ${meshcentral_logdir};
    fi
}

run_rc_command "$1"

The only thing that changed is the user variable. When I use the first script, things just work.
But when I try to use the second one, daemon start complaining "could not set user environment" or "initgroup meshcentral failed"

The user was created with
pw user add meshcentral -c meshcentral -u 6374 -s /usr/sbin/nologin -d /home/meshcentral -m

Or would it be best not to run it as a daemon, and use “su -m ${meshcentral_user}” instead?
 
And tips for improving it are also welcome...

Also, what is best practice for running services? Custom user? Root? And why?
 
Also, what is best practice for running services?
Depends on the service. Apache for example is started as root but drops privileges on its own. Other services never drop privileges and directly started on some user account. Judging by the -u option of meshcentral it will drop privileges on its own?
 
Seems to have something to do with the name being the same as the service in the default variable config, because it works when simply using “user=“

If there are no objections, I’ll just use the one that I shared in the OP.
 
And further testing shows that just setting the "meshcentral_user" variable results in the same error. Oh well. Putting this to rest as it does work by just using "user" variable.
 
I see what is happening. According to https://man.freebsd.org/cgi/man.cgi?query=rc.subr(8)&sektion=&manpath=freebsd-release-ports if the "meshcentral_name" variable is set, the it will try to execute the "daemon" command as the meshcentral user, instead of having daemon run the command as the meshcentral user. I see now...

Code:
${name}_user
                 User  to  run  command  as,  using     chroot(8)  if
                 ${name}_chroot  is     set,  otherwise  uses    su(1).
                 Only supported after /usr is mounted.
 
More study reveals that there might be an underlying issue with the meshcentral process needing npm rights.

If I run su -m meshcentral then it always fails with an error that it can’t access NPM or doesn’t have the rights to use it.

But when I do daemon -u meshcentral then things just work.

I can still su meshcentral and switch to the meshcentral user itself, then run the commands needed and that works. So I’m not sure what exactly is going on…
 
Back
Top