Controlling which services to auto-run under systemd

A typical linux computer has installed on it some set of "services." These are programs that can potentially be launched automatically when the machine is turned on, as part of its boot process. It is useful to have a systematic means to control which ones are actually turned on during  boot. Separately it is useful to have a means to turn them on or off at any time on demand, regardless how they were handled back at boot time.

The locations of the actual binaries for the service programs are scattered around different parts of the hierarchical filesystem tree. These programs are independently written. Where they install by default and how they are to be called are determined, in each case, by their authors or perhaps the distribution maintainer. Regardless, there is no uniformity. systemd seeks to regularize this state of affairs, to impose order on chaos. It keeps information about all the services concentrated in one place, namely /lib/systemd/system. Moreover, it keeps it in a uniform format, namely that of a so-called "unit configuration file" for each service. Here is the unit configuration file for the program that performs logging, namely rsyslog:

[Unit]
Description=System Logging Service
;Requires=syslog.socket
Documentation=man:rsyslogd(8)
Documentation=https://www.rsyslog.com/doc/

[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/rsyslog
ExecStart=/usr/sbin/rsyslogd -n $SYSLOGD_OPTIONS
UMask=0066
StandardOutput=null
Restart=on-failure

# Increase the default a bit in order to allow many simultaneous
# files to be monitored, we might need a lot of fds.
LimitNOFILE=16384

[Install]
WantedBy=multi-user.target
;Alias=syslog.service

In particular, note that this file has an "ExecStart=" line that contains specific identification of the binary (executable) file for the program. Indeed, it contains an entire command line by which to launch it, syntax-legal according to rsyslog's rules and design.

Examine the set of unit files:

ls  /lib/systemd/system

each corrsponding to some installed service or other. There are probably hundreds of them.

In general, each unit configuration file contains an ExecStart line that holds the appropriate command for launching the service. Below, extracted from their respective unit files, are the launch commands for the above rsyslog system logger, plus the httpd web server, vsftpd file transfer server, and the sshd secure shell server.:

/usr/sbin/rsyslogd -n $SYSLOGD_OPTIONS

/usr/sbin/httpd $OPTIONS -DFOREGROUND

/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY $PERMITROOTLOGIN

Note the executables are not called with the same arguments. And they needn't even reside in the same directory (though in this case they do). How-to-call-them, however, is all in one place (as above, right here in this directory). So a program that reads these files learns how to launch each service, and could do so. Enter the program systemd. It runs during system boot. It parses this directory's files and executes the programs represented by some of them, and not others. It knows which ones to execute by consulting a directory that holds links (shortcuts) to the ones that should be run. That directory is typically /etc/systemd/system/multi-user.target.wants/ and looks something like this (from a fedora 31 system):

abrtd.service -> /usr/lib/systemd/system/abrtd.service
abrt-journal-core.service -> /usr/lib/systemd/system/abrt-journal-core.service
abrt-oops.service -> /usr/lib/systemd/system/abrt-oops.service
abrt-vmcore.service -> /usr/lib/systemd/system/abrt-vmcore.service
abrt-xorg.service -> /usr/lib/systemd/system/abrt-xorg.service
atd.service -> /usr/lib/systemd/system/atd.service
auditd.service -> /usr/lib/systemd/system/auditd.service
avahi-daemon.service -> /usr/lib/systemd/system/avahi-daemon.service
chronyd.service -> /usr/lib/systemd/system/chronyd.service
crond.service -> /usr/lib/systemd/system/crond.service
cups.path -> /usr/lib/systemd/system/cups.path
cups.service -> /usr/lib/systemd/system/cups.service
dbxtool.service -> /usr/lib/systemd/system/dbxtool.service
dnf-makecache.timer -> /usr/lib/systemd/system/dnf-makecache.timer
flatpak-add-fedora-repos.service -> /usr/lib/systemd/system/flatpak-add-fedora-repos.service
gpm.service -> /usr/lib/systemd/system/gpm.service
irqbalance.service -> /usr/lib/systemd/system/irqbalance.service
lm_sensors.service -> /usr/lib/systemd/system/lm_sensors.service
mcelog.service -> /usr/lib/systemd/system/mcelog.service
mdmonitor.service -> /usr/lib/systemd/system/mdmonitor.service
ModemManager.service -> /usr/lib/systemd/system/ModemManager.service
netcf-transaction.service -> /usr/lib/systemd/system/netcf-transaction.service
nfs-client.target -> /usr/lib/systemd/system/nfs-client.target
remote-fs.target -> /usr/lib/systemd/system/remote-fs.target
rngd.service -> /usr/lib/systemd/system/rngd.service
rsyslog.service -> /usr/lib/systemd/system/rsyslog.service
smartd.service -> /usr/lib/systemd/system/smartd.service
sshd.service -> /usr/lib/systemd/system/sshd.service
sssd.service -> /usr/lib/systemd/system/sssd.service
vboxservice.service -> /usr/lib/systemd/system/vboxservice.service
vmtoolsd.service -> /usr/lib/systemd/system/vmtoolsd.service
xinetd.service -> /usr/lib/systemd/system/xinetd.service

These are all links (shortcuts), pointing to unit configuration files for particular services. By referring to this list systemd knows to read each file, find out how to execute its service, and do so.

The underlying structure and composition of these files support the operation of the main control utility that is part of systemd, namely systemctl. You will exercise it below.


The in-class or homework exercise:

During this exercise construct and fill in a table like this:

currently running? set for launch-on-boot?
rsyslog logging service yes/no? yes/no?
httpd web service yes/no? yes/no?
vsftpd file transfer service yes/no? yes/no?
sshd secure shell service yes/no? yes/no?

based on the activities you perform, below.

Make a clone of the fedora virtual machine (make a VirtualBox "linked" clone, which is not time-consuming, as opposed to makeing a "full" one). Then perform this exercise in the clone. Please operate as user root.

Investigate whether 4 installed services are set for launch-on-boot or not. The services of interest are the logger, the web server,the bluetooth file transfer server, and the secure shell server. Note the presence of the binary executables that launch respective code for these:

ls  -l   /usr/sbin/rsyslogd
ls  -l  /usr/sbin/httpd
ls  -l  /usr/sbin/vsftpd
ls  -l  /usr/sbin/sshd

Verify that these are indeed binary executables:

file  /usr/sbin/rsyslogd
file /usr/sbin/httpd
file /usr/sbin/vsftpd
file /usr/sbin/sshd

The "file" command identifies files by type, through content analysis. It should report these as "ELF...x86..." indicating the "executable and linkable format," meaning they contain runnable machine-code.

Once any of these is launched it will run continuously. Let's identify which ones are set to launch-on-boot. One empirical way is to check whether any of them are currently running. That works because, unless you've manually launched them since boot time (presumably not), if it's running right now it must have launched during boot. So, if it's running now the setting for launch-on-boot must be "on". A process list is a list of everything that's running. Let's try tracking down our 3 services in the process list:

ps  -ef   |  grep [r]syslog
ps  -ef   |  grep [h]ttpd
ps  -ef   |  grep [v]sftpd
ps  -ef   |  grep [s]shd

Another, explicit, method for checking is the systemctl command. It's part of systemd. Try these:

systemctl status rsyslog
systemctl status httpd
systemctl status vsftpd
systemctl status sshd


(exit from any of these by pressing "q"). Output for the one(s) that are running should include something like "Active: active (running)" as opposed to "Active: inactive (dead)". And, should agree with the above ps results. If a service is in the process list, that should be reflected by "...running..." and if it isn't, by "...dead...". Record in your table's "currently running?" column whether each of the 4 services is running or not. Since we equate the two, you can make the same entries in the "set for launch-on-boot?" column.

Another usage of systemctl is to turn services on or off on demand. Choose one service that's running, and one that's not, and use systemctl to reverse that state of affairs. I'll assume rsyslog is running, and httpd is not (I might be wrong, you determined reality above, turn off one that's on and turn on one that's off):

systemctl stop rsyslog
systemctl start httpd

Now check, by both methods you learned, to verify rsyslog isn't running any more but httpd now is:

systemctl status rsyslog
ps  -ef   |  grep [r]syslogd

systemctl status httpd
ps  -ef   |  grep [h]ttpd

A third usage of systemctl is to change the launch-on-boot setting for a service. You already determined what those settings are empirically, above. Now we'll do it explicitly, with systemctl, to double check. Repeat these:

systemctl status rsyslog
systemctl status httpd
systemctl status vsftpd
systemctl status sshd

this time noting either "enabled" or "disabled" appearing near the end of the output's "Loaded: ... " line. This simply reflects the presence or absence of a corresponding file or files in some location(s) under /etc/systemd/system/ (the location depending on the particular service). Look for the presence or absence of a file corresponding to each of our 4 services in:

ls /etc/systemd/system/multi-user.target.wants/

If a given service is enabled a corresponding file for it is in place here, but if disabled there's no such file. systemd traverses the files in this directory at bootup and launches all the represented services. The directory amounts to a list of services to launch during boot.

Let's reverse a couple of these, then reboot and see if the changes took effect. I'll assume rsyslog is "enabled" (i.e., set for launch-on-boot) and httpd is disabled. So please disable rsyslog and enable httpd. (If my assumption is wrong, just reverse the actual setting of two of your services. Is my assumption wrong? "systemd status..." told you, above).

systemctl disable rsyslog
systemctl enable httpd

Record the new settings in your table (change it). Note that the columns don't necessarily always have the same values, if you either start or stop a program on one hand, or enable or disable it on the other. They only have the same values after a fresh boot.

Now reboot. Then check to make sure, according the the changes you just made, that rsyslog is not running, but httpd is:

systemctl status rsyslog
systemctl status httpd


When satisfied, let's set things to the way we want them. For benefit of future reboots:

systemctl enable rsyslog (logging is important, we want it)
systemctl disable httpd

and for our benefit for the rest of this session, let's not leave the logger off:

systemctl start rsyslog

What to turn in:

Please submit a screenshot file. Set the run status of the 4 services to the opposite of how you found them originally. That is, for those that were originally running make sure they are stopped, and for those that were not originally running make sure they are running now. (Don't do anything with enable/disable, only start/stop.) Then make a screenshot that shows the statuses for the 4 services (only the first 3 lines of each status report, to fit on the screen).

systemctl status rsyslog  |  head  -n  3
systemctl status httpd  |  head  -n  3
systemctl status vsftpd  |  head  -n  3
systemctl status sshd  |  head  -n  3

Name the screenshot file "systemd.jpg" (or .png) and submit/upload it to your assignments directory on the remote server.