To create new wiki account, please join us on #znc at Libera.Chat and ask admins to create a wiki account for you. You can say thanks to spambots for this inconvenience.
Running ZNC as a system daemon: Difference between revisions
DarthGandalf (talk | contribs) No edit summary |
m →Windows |
||
(37 intermediate revisions by 12 users not shown) | |||
Line 1: | Line 1: | ||
__TOC__ | |||
<span style="color:red;font-size:15px;font-weight:bold">Note: if you just want to run ZNC automatically, when server is turned on, don't use this page, look <u>[[FAQ#How_can_I_restart_ZNC_automatically_.28in_case_of_a_machine_reboot.2C_crash.2C_etc..29.3F|here]]</u> instead.</span> | |||
==New User== | |||
We first create a new user so that there is a separation of concerns. This separation gives us many security benefits. The new user will have a shell that cannot be logged into so there is no threat of a remote attack or someone sitting at the computer. Also the user will have reduced privileges and therefore can only access files for which it has ownership or is part of the group. We create this new user by issuing the following command (I added a comment field for later system administrators): | |||
* create a | sudo useradd --create-home -d /var/lib/znc --system --shell /sbin/nologin --comment "Account to run ZNC daemon" --user-group znc | ||
* | Though we cannot ourselves login to this user, we can have the system assign the user a process. This also helps identify who is running which processes in the "Task Manager" per se. Creating a new user is not necessary, but as you can see there are many reasons for doing so. | ||
===Making a new home=== | |||
Now that we have a new user, we have to create the data directory that our ZNC server will store its configurations. Since our initialization scripts will be looking for the configuration in <code>/var/lib/znc</code> that's where we have to tell ZNC to make them. | |||
* Make the configuration we will run at startup: | |||
sudo -u znc /usr/bin/znc --datadir=/var/lib/znc --makeconf | |||
* Ensure the config file in <code>/var/lib/znc/config/znc.conf</code> instructs ZNC to create a PID file: | |||
echo "PidFile = /var/run/znc/znc.pid" | sudo su - znc -s /bin/bash -c "tee -a /var/lib/znc/configs/znc.conf" | |||
* You will have to ensure permissions are correct for your system user. | |||
==Create the <code>init.d</code> Scripts== | |||
Once our new user and configuration files have been created, we have to create the initialization script. These scripts might have already been created for you by the package manager. There are two main platforms for Linux, Fedora and Debian. Fedora is like your CentOS and Red Hat distros, while Debian's most notable distro is Ubuntu. There is a difference between the two scripts, so only use the one you need. | |||
===Fedora-based machines=== | |||
'''Fedora has used systemd since Fedora 15 and CentOS since CentOS 7.''' | |||
* Here is the <code>/etc/init.d/znc</code> for Fedora-based machines: | |||
#!/bin/sh | |||
# | |||
# znc - Advanced IRC Bouncer INIT script # | |||
# description: An Advanced IRC bouncer INIT script for | |||
# Source function library. | |||
. /etc/rc.d/init.d/functions | |||
exec=/usr/bin/znc | |||
prog=znc | |||
config=/var/lib/znc | |||
runas=znc | |||
lockfile=/var/lock/subsys/$prog | |||
start() { | |||
[ -x $exec ] || exit 5 | |||
echo -n $"Starting $prog: " | |||
# if not running, start it up here, usually something like "daemon $exec" | |||
daemon --user $runas "$exec -d $config >/dev/null 2>&1" | |||
# If you're reckless with your system, comment the line above and | |||
# uncomment this one below... I just don't get it why | |||
# daemon "$exec -r -d $config >/dev/null 2>&1" | |||
retval=$? | |||
echo | |||
[ $retval -eq 0 ] && touch $lockfile | |||
return $retval | |||
} | |||
stop() { | |||
echo -n $"Stopping $prog: " | |||
# stop it here, often "killproc $prog" | |||
killproc $prog -TERM | |||
retval=$? | |||
echo | |||
[ $retval -eq 0 ] && rm -f $lockfile | |||
return $retval | |||
} | |||
reload() { | |||
echo -n $"Reloading $prog: " | |||
# stop it here, often "killproc $prog" | |||
killproc $prog -HUP | |||
retval=$? | |||
echo | |||
} | |||
restart() { | |||
stop | |||
start | |||
} | |||
rh_status() { | |||
# run checks to determine if the service is running or use generic status | |||
status $prog | |||
} | |||
rh_status_q() { | |||
rh_status >/dev/null 2>&1 | |||
} | |||
case "$1" in | |||
start) | |||
rh_status_q && exit 0 | |||
$1 | |||
;; | |||
stop) | |||
rh_status_q || exit 0 | |||
$1 | |||
;; | |||
restart) | |||
$1 | |||
;; | |||
reload) | |||
rh_status_q || exit 7 | |||
$1 | |||
;; | |||
status) | |||
rh_status | |||
;; | |||
condrestart|try-restart) | |||
rh_status_q || exit 0 | |||
restart | |||
;; | |||
*) | |||
echo $"Usage: $0 {start|stop|status|reload|restart|condrestart|try-restart}" | |||
exit 2 | |||
esac | |||
exit $? | |||
===Debian-based machines=== | |||
'''Debian has used systemd since Debian 7, Ubuntu since 15.04.''' | |||
* Here is the <code>/etc/init.d/znc</code> for Debian-based machines: | |||
#! /bin/sh | #! /bin/sh | ||
### BEGIN INIT INFO | ### BEGIN INIT INFO | ||
Line 147: | Line 262: | ||
esac | esac | ||
After you've created the script, you must give it the proper permissions to run | |||
sudo chmod 755 /etc/init.d/znc | |||
chmod 755 /etc/init.d/znc | |||
==Get the daemon up and running== | |||
update-rc.d znc defaults | |||
* | Everything is now in place! Once we insert the daemon, you can either start the service yourself (as shown below) or restart the computer for the daemon to take its place. | ||
* | * Insert the script into the boot sequence: | ||
sudo update-rc.d znc defaults # For Debian systems | |||
to the | * Start the service: | ||
sudo service znc start | |||
service znc | * Verify that the service is running: | ||
sudo service znc status | |||
== systemd == | |||
=== Create the systemd unit=== | |||
==== System service ==== | |||
* Create the file <code>/etc/systemd/system/znc.service</code> (system service) | |||
<pre> | |||
#----------------------# | |||
# Systemd Unit for ZNC # | |||
#----------------------# | |||
[Unit] | |||
Description=ZNC - Advanced IRC Bouncer | |||
[Service] | |||
# User running the ZNC instance | |||
User=znc | |||
# Add '-f' at the end if you want to launch ZNC on foreground mode | |||
# Example: ExecStart=/usr/bin/znc --datadir=/var/lib/znc -f | |||
ExecStart=/usr/bin/znc --datadir=/var/lib/znc | |||
# Change to 'Type=simple' if you launch ZNC on foreground mode | |||
Type=forking | |||
# Restart policy (this is the advised one) | |||
Restart=on-failure | |||
[Install] | |||
WantedBy=multi-user.target | |||
</pre> | |||
==== User service ==== | |||
* Create the file <code>~/.config/systemd/user/znc.service</code> (user service). | |||
<pre> | |||
#---------------------------# | |||
# Systemd User Unit for ZNC # | |||
#---------------------------# | |||
[Unit] | |||
Description=ZNC - Advanced IRC Bouncer | |||
[Service] | |||
# Add '-f' at the end if you want to launch ZNC on foreground mode | |||
# Example: ExecStart=/home/znc/bouncer/bin/znc -f | |||
ExecStart=/home/znc/bouncer/bin/znc | |||
# Change to 'Type=simple' if you launch ZNC on foreground mode | |||
Type=forking | |||
# Restart policy (this is the advised one) | |||
Restart=on-failure | |||
[Install] | |||
WantedBy=default.target | |||
</pre> | |||
=== Start the systemd unit and enable it for running on boot === | |||
With system service run: | |||
sudo systemctl start znc.service | |||
sudo systemctl enable znc.service | |||
With user service run: | |||
systemctl --user start znc.service | |||
systemctl --user enable znc.service | |||
In case you edit the file, you may need to run <code>systemctl daemon-reload</code> or <code>systemctl --user daemon-reload</code>. <code>start</code> starts the service now and <code>enable</code> starts it on boot. | |||
'''NOTE to user services:''' enabled user services are started when the user logins and killed when the last session of user quits. To start user services on boot and keep them running after the last session is closed you need to enable lingering. You can do that as root with: <code>sudo loginctl enable-linger username</code> or as the user with: <code>loginctl enable-linger</code>. | |||
== Windows == | |||
A user called <code>znc</code> can be created by running netplwiz and clicking add, make sure you create a local user account not a microsoft account. | |||
feel free to specify a password preferably a random one (on windows server and domain joined windows by default this needs to pass the complex password requirement) | |||
we could login to this user but we're not going to | |||
Next do Start -> Windows Administrative Tools -> Local Security Policy -> Local Policies -> User Rights Assessment -> "Log on as a service" -> edit -> add your user | |||
if you can't do this step because local security policy is missing then upgrade your windows edition to pro | |||
with the new user created we need to initialize the znc server data directory | |||
in a command prompt window type | |||
<pre>runas /noprofile /user:znc "C:\cygwin64\bin\mintty.exe -"</pre> | |||
then in the newly opened cygwin terminal run | |||
<pre>znc --makeconf</pre> | |||
and then | |||
<pre>echo "PidFile = /home/znc/.znc/znc.pid" >> /home/znc/.znc/configs/znc.conf</pre> | |||
and exit that terminal once done | |||
make sure the <code>cygrunsrv</code> package is installed in cygwin installer | |||
open cygwin terminal as administrator and run | |||
<pre>cygrunsrv -I znc -p/usr/bin/znc.exe -x/home/znc/.znc/znc.pid -uznc</pre> | |||
you should see a service called znc started in Services mmc snap-in | |||
any issues that may arise with it not starting or crashing on boot can be potentially remediated by setting the service to "Automatic (Delayed Start)" |
Latest revision as of 01:02, 31 October 2024
Note: if you just want to run ZNC automatically, when server is turned on, don't use this page, look here instead.
New User
We first create a new user so that there is a separation of concerns. This separation gives us many security benefits. The new user will have a shell that cannot be logged into so there is no threat of a remote attack or someone sitting at the computer. Also the user will have reduced privileges and therefore can only access files for which it has ownership or is part of the group. We create this new user by issuing the following command (I added a comment field for later system administrators):
sudo useradd --create-home -d /var/lib/znc --system --shell /sbin/nologin --comment "Account to run ZNC daemon" --user-group znc
Though we cannot ourselves login to this user, we can have the system assign the user a process. This also helps identify who is running which processes in the "Task Manager" per se. Creating a new user is not necessary, but as you can see there are many reasons for doing so.
Making a new home
Now that we have a new user, we have to create the data directory that our ZNC server will store its configurations. Since our initialization scripts will be looking for the configuration in /var/lib/znc
that's where we have to tell ZNC to make them.
- Make the configuration we will run at startup:
sudo -u znc /usr/bin/znc --datadir=/var/lib/znc --makeconf
- Ensure the config file in
/var/lib/znc/config/znc.conf
instructs ZNC to create a PID file:
echo "PidFile = /var/run/znc/znc.pid" | sudo su - znc -s /bin/bash -c "tee -a /var/lib/znc/configs/znc.conf"
- You will have to ensure permissions are correct for your system user.
Create the init.d
Scripts
Once our new user and configuration files have been created, we have to create the initialization script. These scripts might have already been created for you by the package manager. There are two main platforms for Linux, Fedora and Debian. Fedora is like your CentOS and Red Hat distros, while Debian's most notable distro is Ubuntu. There is a difference between the two scripts, so only use the one you need.
Fedora-based machines
Fedora has used systemd since Fedora 15 and CentOS since CentOS 7.
- Here is the
/etc/init.d/znc
for Fedora-based machines:
#!/bin/sh # # znc - Advanced IRC Bouncer INIT script # # description: An Advanced IRC bouncer INIT script for # Source function library. . /etc/rc.d/init.d/functions exec=/usr/bin/znc prog=znc config=/var/lib/znc runas=znc lockfile=/var/lock/subsys/$prog start() { [ -x $exec ] || exit 5 echo -n $"Starting $prog: " # if not running, start it up here, usually something like "daemon $exec" daemon --user $runas "$exec -d $config >/dev/null 2>&1" # If you're reckless with your system, comment the line above and # uncomment this one below... I just don't get it why # daemon "$exec -r -d $config >/dev/null 2>&1" retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " # stop it here, often "killproc $prog" killproc $prog -TERM retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } reload() { echo -n $"Reloading $prog: " # stop it here, often "killproc $prog" killproc $prog -HUP retval=$? echo } restart() { stop start } rh_status() { # run checks to determine if the service is running or use generic status status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart) $1 ;; reload) rh_status_q || exit 7 $1 ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 restart ;; *) echo $"Usage: $0 {start|stop|status|reload|restart|condrestart|try-restart}" exit 2 esac exit $?
Debian-based machines
Debian has used systemd since Debian 7, Ubuntu since 15.04.
- Here is the
/etc/init.d/znc
for Debian-based machines:
#! /bin/sh ### BEGIN INIT INFO # Provides: znc # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: ZNC IRC bouncer # Description: ZNC is an IRC bouncer ### END INIT INFO PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="ZNC daemon" NAME=znc DAEMON=/usr/bin/$NAME DATADIR=/var/lib/znc DAEMON_ARGS="--datadir=$DATADIR" PIDDIR=/var/run/znc PIDFILE=$PIDDIR/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME USER=znc GROUP=znc # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started if [ ! -d $PIDDIR ] then mkdir $PIDDIR fi chown $USER:$GROUP $PIDDIR start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test --chuid $USER > /dev/null || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid $USER -- $DAEMON_ARGS > /dev/null || return 2 } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME --chuid $USER RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON --chuid $USER [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME --chuid $USER return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $? ;; reload) log_daemon_msg "Reloading $DESC" "$NAME" do_reload log_end_msg $? ;; restart) log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) echo "Usage: $SCRIPTNAME {status|start|stop|reload|restart}" >&2 exit 3 ;; esac
After you've created the script, you must give it the proper permissions to run
sudo chmod 755 /etc/init.d/znc
Get the daemon up and running
Everything is now in place! Once we insert the daemon, you can either start the service yourself (as shown below) or restart the computer for the daemon to take its place.
- Insert the script into the boot sequence:
sudo update-rc.d znc defaults # For Debian systems
- Start the service:
sudo service znc start
- Verify that the service is running:
sudo service znc status
systemd
Create the systemd unit
System service
- Create the file
/etc/systemd/system/znc.service
(system service)
#----------------------# # Systemd Unit for ZNC # #----------------------# [Unit] Description=ZNC - Advanced IRC Bouncer [Service] # User running the ZNC instance User=znc # Add '-f' at the end if you want to launch ZNC on foreground mode # Example: ExecStart=/usr/bin/znc --datadir=/var/lib/znc -f ExecStart=/usr/bin/znc --datadir=/var/lib/znc # Change to 'Type=simple' if you launch ZNC on foreground mode Type=forking # Restart policy (this is the advised one) Restart=on-failure [Install] WantedBy=multi-user.target
User service
- Create the file
~/.config/systemd/user/znc.service
(user service).
#---------------------------# # Systemd User Unit for ZNC # #---------------------------# [Unit] Description=ZNC - Advanced IRC Bouncer [Service] # Add '-f' at the end if you want to launch ZNC on foreground mode # Example: ExecStart=/home/znc/bouncer/bin/znc -f ExecStart=/home/znc/bouncer/bin/znc # Change to 'Type=simple' if you launch ZNC on foreground mode Type=forking # Restart policy (this is the advised one) Restart=on-failure [Install] WantedBy=default.target
Start the systemd unit and enable it for running on boot
With system service run:
sudo systemctl start znc.service sudo systemctl enable znc.service
With user service run:
systemctl --user start znc.service systemctl --user enable znc.service
In case you edit the file, you may need to run systemctl daemon-reload
or systemctl --user daemon-reload
. start
starts the service now and enable
starts it on boot.
NOTE to user services: enabled user services are started when the user logins and killed when the last session of user quits. To start user services on boot and keep them running after the last session is closed you need to enable lingering. You can do that as root with: sudo loginctl enable-linger username
or as the user with: loginctl enable-linger
.
Windows
A user called znc
can be created by running netplwiz and clicking add, make sure you create a local user account not a microsoft account.
feel free to specify a password preferably a random one (on windows server and domain joined windows by default this needs to pass the complex password requirement)
we could login to this user but we're not going to
Next do Start -> Windows Administrative Tools -> Local Security Policy -> Local Policies -> User Rights Assessment -> "Log on as a service" -> edit -> add your user
if you can't do this step because local security policy is missing then upgrade your windows edition to pro
with the new user created we need to initialize the znc server data directory
in a command prompt window type
runas /noprofile /user:znc "C:\cygwin64\bin\mintty.exe -"
then in the newly opened cygwin terminal run
znc --makeconf
and then
echo "PidFile = /home/znc/.znc/znc.pid" >> /home/znc/.znc/configs/znc.conf
and exit that terminal once done
make sure the cygrunsrv
package is installed in cygwin installer
open cygwin terminal as administrator and run
cygrunsrv -I znc -p/usr/bin/znc.exe -x/home/znc/.znc/znc.pid -uznc
you should see a service called znc started in Services mmc snap-in
any issues that may arise with it not starting or crashing on boot can be potentially remediated by setting the service to "Automatic (Delayed Start)"