Labs: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.
Please, see latest news in issue #92 (from April 03).
The lab topics include user accounts in Linux, software installation and service execution. The topics are mostly independent and it is possible to read them in virtually any order.
Preflight checklist
- You are ready for the first on-site test :-).
User accounts
We already touched this topic few times: take it also as a refresher for things you already know.
User accounts on Linux are of two basic types. Normal user accounts for end-users, i.e., accounts to which you log via SSH or graphical interface and where you work. There are also system accounts that exist solely for the purpose of being able to run processes under different users for better isolation. One usually do not log in under these accounts at all.
Your accounts on linux.ms.mff.cuni.cz
are of the first type and if you
run ps -ef --forest
you will see what other users are running. The ps
command is used to display running processes, we will return to this topic
in one of the next labs.
System accounts are for example chrony
or nginx
that are used to run
special services of the system.
Each user account has a numerical id (which is how the operating system
identifies the user) and a username that is usually mapped via /etc/passwd
.
/etc/passwd
is a plain text file with colon-delimited fields.
Feel free to inspect its content (cat /etc/passwd
is good enough).
Among user accounts on a Linux system, one user has special privileges.
The user is called root
(or superuser), has numerical id of 0 and has
virtually unlimited power over the running machine.
For example, access rights are actually ignored for root
user
(i.e., a process running under root
can read/write any file).
To switch to the superuser account, you can either use sudo
(see below)
or use su
. Often it is executed like this to ensure you start a login shell
(among other things this also ensures that $HOME
points to /root
and
not to the home directory of the normal user):
su -
Unlike on other systems, Linux is designed in such way that end-user
programs are always executed under normal users and never require root privileges.
As a matter of fact, some programs (historically, this was a very common behaviour
for IRC chat programs) would not even start under root
.
root
is needed for actions that modify the whole system. This includes system
upgrade, formatting of a hard-drive or modification of system-wide configuration files.
The strict separation of normal (work) accounts and a superuser comes from
the fact that Linux was designed as a multi-user system.
The philosophy dates back 50+ years where system was shared by many users and only one
of them – root
– was the administrator of the machine.
Today, when typical notebook installations contain just a single account, the separation
is often more artificial, but it still exists.
The truth is that contemporary users are threatened more by a malicious webpage rather than an unauthorized system software update. Superuser account was designed to prevent the latter rather than the former. However, the idea of separate user accounts is still valid today and a careful user can use different accounts for different activities (e.g., browsing social media vs. working with your bank account).
User account management
We consider this an advanced topic and in this course we will limit ourselves
to pointing you to the documentation of useradd
, userdel
and usermod
commands that create, delete and modify user accounts respectively.
Recall that there is also getent
for retrieving information about
existing accounts. We used it earlier in some of the examples, generally
calling it like getent passwd
will list information about all users,
giving it the username will print details about single user.
Try to run getent passwd YOUR_LOGIN
on our shared machine.
You should be also familiar with passwd
that can be used to change
the user’s password.
sudo
Some programs need privilege escalation, i.e., run with higher privileges and wider permissions than other programs.
Some need this by design and these can use special setting (for now, you can
imagine it as a special variant of chmod +x
).
However, some commands require higher privileges only once in a while,
so running them with the special setting would only broaden the possible
attack vectors unnecessarily.
For these situations, one option is sudo
(homepage).
As the name suggests, it executes (does) one command with superuser privileges.
The advantage of sudo
is that system admin can specify who can run which command
with elevated permissions.
Thus it does not give the allowed user unlimited power over the machine, but only
over a selected subset of commands.
For example, it is possible to give a user option to restart a specific service (e.g., we want to allow a tester to restart a web server) without giving him control over the whole machine.
Note that the granularity of sudo
stops at the level of programs.
It does not restrict what sudo
does inside the program.
For example, it is possible to impose a restriction, that alice
can
execute dangerous_command
only with --safe-option
.
However, if the dangerous_command
reads options also from a ~/.dangerousrc
,
alice
can provide --unsafe-option
there and sudo
cannot
prevent that.
In other words, once the initial check is completed, the program
runs as if it was launched under root
.
This is extremely important for shared machines where the administrator
typically wants to restrict all users as much as possible.
On the other hand, for desktop installations, the typical default is
that the first user created (usually during installation) can sudo
anything.
The reasoning is that it is the only (physical) user, who knows the
root
password anyway.
This is why most tutorials on web usually provide the commands for
system maintenance including the sudo
prefix.
Also note that there are
multiple options for gaining a root shell
(i.e., sudo bash
).
As a safe example what you can try is to execute fdisk -l
to list partitions
on your system. When executed without root privileges, it will probably
fail with several messages about denied access. Running it with sudo
should work.
Note that you enter your password, not the one of superuser (after all,
if it would be superuser password, you will not need sudo
because you would
be able to execute su -
and get the root shell directly).
sudo fdisk -l
Note that sudo
is not the only security mechanism present.
We will not discuss other mechanisms in great detail, but to give you
pointers to documentation: there is also
SELinux
or AppArmor
and a high-level overview on
this Wikipedia page.
User accounts overview: check you understand the basics
Software installation (a.k.a. package management)
Software in Linux is usually installed by means of a package manager. The package manager is a special program that takes care of installation, upgrading, and removing packages. A package can be anything that could be installed; this includes:
- a program (for example, package
ranger
installs the programranger
), - data files or configuration (e.g.,
libreoffice-langpack-cs
for Czech support inside LibreOffice), - a library (e.g.,
gmp
orgmp-devel
providing the GNU arbitrary-precision arithmetics library), - or a meta package (e.g.,
xfce
that coversxfce4-terminal
,xfwm4-themes
etc.).
In this sense, Linux is very similar to what you know from the shopping-center-style management of applications on your smartphones. It is very irregular to install software on Linux using a graphical install wizard.
The advantage of using centralized package management is the ability to upgrade the whole system at once without the need to check updates of individual applications.
Note that it is possible to install software manually too. From the file-system point of view, there is no difference – the package manager also just copies files to the right directories. However, manually installed software has to be upgraded manually too and generally complicates the setup. So avoid it when possible.
A typical package manager works with several software repositories. You can think about it as if your cell-phone has multiple marketplaces where to choose applications from. Typically, you will encounter the following types of repositories. It is up to each user (administrator) to decide which to use.
- Stable and testing, where the latter provides newer versions of software with slight possibility of bugs (usually, there is a third repository, often called unstable, for bleeding-edge software).
- Free and non-free, where the former contains only software without any legal surprises. Non-free software can be encumbered by patent or royalty issues (usually based on US law), or by a license which restricts use or redistribution.
Note that both official and unofficial repositories offer no guarantees in the legal sense. However, using the official repositories of a given distribution is considered safe, the amount of attacks on software repositories is low and – unlike with many commercial organizations – distribution maintainers are very open in informing about security incidents. It is probably much easier to encounter a malicious application in your smartphone marketplace than to encounter it in an official repository of a Linux distribution.
dnf
(a.k.a. package manager in Fedora)
The package manager for Fedora is called DNF.
If you decided to use a different distribution, you will need to edit the commands to match your system. Generally, the operations would be rather similar but we cannot provide a tutorial for every package manager here.
You can use the search
command to get a list of packages which match the
given name.
Note that searching is not a privileged operation, hence it does not require sudo
.
dnf search arduino
dnf search atool
Note that searching for a very generic term can yield hundreds of results.
The output is in the following format:
atool.noarch : A perl script for managing file archives of various types
ratools.x86_64
The .noarch
and .x86_64
strings describe the nature of the package.
noarch
usually refers to a data package or package using interpreted languages,
while .x86_64
denotes a package with binaries for the x86-64 architecture
(e.g., written in C or Rust and then compiled to machine code).
To install a software package, run dnf
with the install
subcommand, giving it the
name of the package to install.
Here, sudo
is needed as we are modifying the system.
sudo dnf install atool
Some applications are not a part of any software repository, but you can still download them in a format understandable by your package manager. That is a better situation than installing the files manually, because your package manager knows about the files (although it cannot upgrade it automatically). One such example is the Zoom client which has to be installed like this:
sudo dnf install "https://zoom.us/client/latest/zoom_x86_64.rpm"
To upgrade the whole system, simply run the following. DNF will ask for confirmation and then upgrade all available packages.
sudo dnf upgrade
Note that unlike on other systems, you can always choose when to upgrade. The system will never reboot the machine for you or display a message about needed restart, unless you explicitly ask for it.
If you want to install a whole group of packages, you can use dnf grouplist
to view their list and sudo dnf install @GROUP_NAME
to install it.
The commands above contain the basics for maintaining your Fedora installation with respect to package management. The following links provide more information. The official Wiki page is a good source of information if you already know the system a bit.
For beginners, this guide about DNF and this tutorial are probably a better starting point.
Package management: check you understand the basics
Services (and daemons too)
In the context of an operating system, the term service usually refers to
any program that is running on the background (typically, no GUI, stdin
from /dev/null
) and provides some kind of service to other programs.
A typical example can be a printing service that takes care of printer discovery and provides end-user applications with list of printers (i.e., the end-user applications do not need to make the discovery themselves). Another example is a web server: it provides files over the HTTP protocol to web browsers.
In the world of Unix systems, such programs are often called daemons
(this probably comes from ancient Greek mythology where daemon is a being working
in the background), traditionally names of such programs end with the letter d
.
For example, the popular Apache web server is actually launched as a program httpd
and the SSH server is running as sshd
.
Daemons operate differently from normal programs.
When started, they read their configuration (typically from a file under /etc/
),
start and listen for requests (imagine a web server listening on port 80).
Changing their behavior is usually done by changing their configuration file and
restarting them.
Because they are started in background, they do not have access to an interactive
stdin and the restart (or shutdown) is performed via signals.
We will talk about signals later: signals are an asynchronous channel
to communicate with running processes (unlike, for example, stdin
where
the program decides when to read while a signal can arrive anytime).
Because the need to restart a running daemon is quite common (and sending signals
is not very elegant), there are special programs for exactly that.
We can call them control scripts and for some services you will find files
serviced
(with the actual daemon code) and servicectl
for controlling it.
Unified daemon control
As the principles stated above are essentially the same for all daemons, there
usually exists a set of scripts unifying this behavior.
So, instead of calling a specific servicectl
, the distribution will typically
offer a special command with which you can control any daemon.
Usually, one will use something along the following lines:
service [start|stop|restart] name-of-daemon
Currently, the most often used program for this task is called systemctl.
About logging
Most services provide so-called logs. There they record every significant action they performed.
For example, a web server typically logs which pages it served together with information about the client.
Usually, for each service you can specify how detailed the logging shall be. Debugging a configuration issue requires a more detailed level, on a production server you usually limit the amount of logged information to minimum for performance reasons.
Systemd
Systemd is one of the most widely used system service management tools in today’s Linux world.
We will not go into detail and just review the two most important
commands: systemctl
and journalctl
.
Notice that systemd
is a daemon, while systemctl
is a command for controlling this daemon.
Starting and stopping a service
Starting a service with systemd is very simple.
The following command starts sshd
, the SSH server:
sudo systemctl start sshd
If the service was already running, nothing happens.
Check that you can now connect to your machine via the following command:
ssh your-login@localhost
To check the state of the service, the status
subcommand is used
(note that status
can be run without sudo
, but may display less information):
sudo systemctl status sshd
● sshd.service - OpenSSH Daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2021-03-01 14:31:40 CET; 2 months 3 days ago
Main PID: 560 (sshd)
Tasks: 1 (limit: 9230)
Memory: 900.0K
CPU: 16ms
CGroup: /system.slice/sshd.service
└─560 sshd: /usr/bin/sshd -D [listener] 0 of 10-100 startups
Warning: journal has been rotated since unit was started, output may be incomplete.
We see that the service is running, most items shall be self explanatory.
The /usr/lib/systemd/system/sshd.service
file contains service configuration
itself (e.g., how to start/stop/restart the service), not the actual configuration of
SSH daemon that is inside /etc/ssh
.
It is safer to stop SSH daemon on your laptop if you are not going to use it:
sudo systemctl stop sshd
Enabling and disabling a service
If you wish to start the service with each boot, you can enable the service:
sudo systemctl enable sshd
Systemd will take care of proper ordering of the individual services (so that SSH server is started only after the network is initialized etc.).
If you no longer wish to have the SSH daemon started by default, call the command with
disable
instead.
Note that both enable
and disable
do not change the current state of
the service: you still need to start
/stop
it if you do not want to wait for reboot.
(For convenience, there is systemctl enable --now sshd
, which also starts the
service.)
Logs
Most system services keep logs of their work. The logs are usually stored under /var/log/
.
Some services produce logs on their own. Such logs are simple textual files, but their
format is specific to the individual services and their configuration.
Many services use a central logging service, which keeps all its logs in a unified format and which can be configured for sorting logs, sending them over the network, removing old records, and so on.
On Fedora, the logging service is called journald
. It keeps the log files in cryptographically
signed binary files, which are not directly readable. But you can read the logs using
the journalctl
command.
For example, the following command shows logs for the SSH daemon:
journalctl -u sshd
More …
If you are interested in this topic, please, consult the relevant manual pages. Take these few paragraphs as a very brief introduction to the topic that allows you basic management of your system.
Printing and scanning in Linux
Below is a quick overview of Linux support for printing and scanning. Today, most devices are connected over network and – at least their basic functions – will work out of the box on Linux.
Extra packages (these you might need to download from the vendor pages) are usually needed only for extra features.
Printing with CUPS
Printing in Linux is handled by the CUPS subsystem that works out-of-the box with virtually every printer supporting IPP (internet printing protocol) and supports also many legacy printers.
Simple sudo dnf install cups
installs the basic subsystem, extra drivers
might be needed for specific models.
OpenPrinting.org contains a searchable
database to determine which (if any) drivers are needed.
For example, for most HP printers, you would need to install the hplip
package.
You typically want CUPS up and running on your system all the time, hence you need to enable it:
sudo systemctl enable --now cups
CUPS has a nice web interface that you can use to configure your printers. For many modern network-connected printers, even that is often unnecessary as they will be auto-discovered correctly.
If you have started CUPS already, try visiting http://localhost:631/. Under the Administration tab, you can add new printers. Selecting the right model helps CUPS decide which options to show in the printing dialog and enables proper functioning of grayscale printing and similar features.
Scanning images and documents with Sane
Scanner support on Linux is handled with SANE (Scanner Access Now Easy). As with printing, most scanners will be autodetected and if you already know GIMP, it has SANE support.
Add it with sudo dnf install xsane-gimp
.
Actual scanning of the image can be done from File -> Create -> XSane dialog where you select your device, scanning properties (e.g., resolution or colors) and then you can start the actual scan.
Periodically running tasks with Cron
There are many tasks in your system that needs to be executed periodically. Many of them are related to system maintenance, such as log rotation (removal of outdated logs), but even normal users may want to perform regular tasks.
A typical example might be backing up your $HOME
or a day-to-day change
of your desktop wallpaper.
From the administrator’s point of view, you need to install the cron
daemon
and start it.
On Fedora, the actual package is called cronie
, but the service is still
named crond
.
System-wide jobs (tasks) are defined /etc/cron.*/
, where you can
directly place your scripts.
For example, to perform a daily backup of your machine, you could place
your backup.sh
script directly into /etc/cron.daily/
Of course, there are specialized backup tools (e.g. duplicity),
but your solution from Lab 07 is a pretty good start for a homebrew approach.
If you want more fine-grained specification than the one offered by the cron.daily
or cron.hourly
directories, you can specify it in a custom file inside
/etc/cron.d/
.
There, each line specifies a single job: a request to run a specified command
at specified time under the specified user (typically root
). The time is given
as a minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week
(0-6, 0 is Sunday). You can use *
for “any” in every field. For more details,
see crontab(5)
.
Therefore, the following will execute /usr/local/bin/backup.sh
every day 85 minutes
after midnight (i.e., at 1:25 am).
The second line will call big-backup.sh
on every Sunday morning.
25 1 * * * root /usr/local/bin/backup.sh
0 8 * * 0 root /usr/local/bin/big-backup.sh
Note that cron.d
will typically contain a special call of the following form
which ensures that the cron.hourly
scripts are executed
(i.e., the cronie
deamon itself looks only inside /etc/cron.d/
, the use of cron.daily
or cron.monthly
is handled by special jobs).
01 * * * * root run-parts /etc/cron.hourly
Running as a normal user
Normal (i.e., non-root) users cannot edit files under /etc/cron.d/
.
Instead, they have a command called crontab
that can be used to edit their personal
cron table (i.e., their list of cron jobs).
Calling crontab -l
will list current content of your cron table.
It will probably print nothing.
To edit the cron table, run crontab -e
.
It will launch your favourite editor where you can add lines in the above-mentioned
format, this time without the user specification.
For example, adding the following entry will change your desktop background every day:
1 1 * * * /home/intro/bin/change_desktop_background.sh
Of course, assuming you have such script in the given location. If you really want to try it, the following script works for Xfce and uses Lorem Picsum.
#!/bin/sh
# Update to your hardware configuration
screen_width=1920
screen_height=1080
wallpaper_path="$HOME/.wallpaper.jpg"
curl -L --silent "https://picsum.photos/$screen_width/$screen_height" >"$wallpaper_path"
# Xfce
# Select the right path from xfconf-query -lvc xfce4-desktop
xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitor0/workspace0/last-image -s "$wallpaper_path"
# LXDE
pcmanfm -w "$wallpaper_path"
# Sway
# For more details see `man 5 sway-output`
# You can also set a different wallpaper for each output (display)
# Run `swaymsg -t get_outputs` for getting specific output name
swaymsg output '*' bg "$wallpaper_path" fill
Learning outcomes and after class checklist
This section offers a condensed view of fundamental concepts and skills that you should be able to explain and/or use after each lesson. They also represent the bare minimum required for understanding subsequent labs (and other courses as well).
Conceptual knowledge
Conceptual knowledge is about understanding the meaning and context of given terms and putting them into context. Therefore, you should be able to …
-
explain how and why is software distributed in the forms of packages
-
explain what account types exist on Linux and how they differ (e.g.
johndoe
,root
andnobody
) -
explain difference between the
root
account and other accounts -
explain why doing non-administrative tasks with
root
account is generally discouraged -
explain in broad terms how
sudo
can be used for system administration -
understand the dangers of using
sudo
-
explain what is a service (daemon)
-
explain life cycle and possible states of a service
-
explain what is a program log and how it can be managed
Practical skills
Practical skills are usually about usage of given programs to solve various tasks. Therefore, you should be able to …
-
use
getent
to retrieve information about user accounts -
use
sudo
to elevate privileges of an executed program -
use a package manager to install or uninstall packages
-
use a package manager to perform a system update
-
use
systemctl
to start and stop services -
use
systemctl
to ensure service is automatically started at machine boot -
use printing and scanning in Linux
-
optional: use
journalctl
to view service logs -
optional: use
useradd
to create a new user account