Labs: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11.

There will be an on-site test at the beginning of this lab, the topic is Git CLI (including branching and merging).

The test will be held during the first half of the lab, please, make sure you arrive on time (other details are on this page).

Make sure you can clone from gitolite3@linux.ms.mff.cuni.cz repositories (they are used in Lab 05, for example) from your school machines.

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.

Running passwd modifies the password of the current user. When executed under root, we can specify a username and modify the password for a different user. For a typical installation, that is the way to reset a password easily.

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.

However, you should always understand why you need to run sudo. Never get into the habit if it does not work, let’s try prepending sudo.

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

Select all true statements. You need to have enabled JavaScript for the quiz to work.

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 program ranger),
  • data files or configuration (e.g., libreoffice-langpack-cs for Czech support inside LibreOffice),
  • a library (e.g., gmp or gmp-devel providing the GNU arbitrary-precision arithmetics library),
  • or a meta package (e.g., xfce that covers xfce4-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.

Individual packages often have dependencies – installing one package results in transitive installation of other packages the first one depends on (for example, a web browser will require basic graphical support etc.). It makes the upgrading process a bit more complicated (for the package manager, not for the user, though). But it can save some disk space. And the most important advantage is that different application share the same libraries (on Linux, they have .so extension and are somewhat similar to DLLs on Windows) and it is possible to upgrade a library even for an otherwise abandoned application. That is essential when patching security vulnerabilities.

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.

It is also possible to set up your own repository. This can be useful if you want to distribute your software to multiple machines (and you cannot publish the packages in the normal repositories because it is, for example, proprietary).

Most distributions also offer some kind of user-repository support where virtually anyone can publish their software. For Fedora, this is done via Copr.

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.

Fedora used to have yum as the package manager and it can be found in many tutorials on the Internet (even in quite recent ones). It is considered obsolete and you should better avoid it.

If you are used to yum from older versions of Fedora or from other RPM-based distributions, you will find dnf very similar and in many situations faster than yum.

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.

Alternatives to classic package managers

The existence of various package managers has its disadvantages – when using multiple distributions, the user has to know how to operate different package managers. Furthermore, different distributions need to create different packages (compatible with their package managers), which results in more work.

Therefore, an effort has been made to unite the package managers. Snap was created in order to install packages among distributions uniformly. While for some users it is a way to get the software they want as quickly as possible, for some the proprietary nature of Snap and a need for an account at the package store presents potential dangers and shift in Linux open-source ideology.

To demonstrate a problematic example, let’s attempt to install PyCharm. PyCharm is an IDE for Python, which is (unfortunately) mostly directed at Windows users and also offers a paid professional version. No PyCharm package is offered in Fedora.

This is rather an exception – you won’t encounter problems with most open-source software. Actually, even companies that were traditionally oriented towards different OSes offer DNF-based repositories for their products these days. Note that in this case, providing a full repository is the ideal choice. Users can choose whether to enable this repository or not, distribution maintainers can focus on other tools and the company keeps full control over the release cycle and the distribution process.

There are these two options to install PyCharm:

  1. Use Snap
  2. Use the ad-hoc installation script. It is downloaded with the PyCharm installation.

Note that the second option is usually frowned-at in general. It requires running a shell script that the user downloads which is generally considered dangerous – you should always examine such scripts. (Obviously, using a package manager also involves downloading and running scripts but the attack surface is a bit smaller.)

Another issue is that any application downloaded in this way will not be automatically updated.

Which one to use

Snap is not the only alternative to the classic package managers.

Among others, there is Flatpak or AppImage. They can co-exist and it is up to the user to decide which one to choose.

The decision which one to use is influenced by many factors. Generally, using pre-packaged software distributed with your system (distribution) should be preferred.

As a last note – even if the software you want to install does not provide packages for your distribution, you can always create them yourself. The process is out-of-scope for this course but it is actually not very difficult.

Package management: check you understand the basics

Select all true statements. You need to have enabled JavaScript for the quiz to work.

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 and nobody)

  • 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