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

The goal of this lab is to start using Linux in network environment and learn basic concepts needed for machines shared among multiple users. After the lab, you will be able to log in to a remote Linux machine, use Git over SSH and also have a look of what programs are currently running on a Linux machine.

We provide brief overview of several concepts that we believe you should already be familiar with. Feel free to skim these parts and focus on the new topics only.

This lab also contains a mini homework for two points.

Networking introduction

This text assumes that you have basic knowledge of networking. Terms such as IP address, interface or port shall not be new for you. If you need a refresher, we have set-up a short page with a brief overview of networking.

Preflight checklist

  • You can perform basic Git operations using the command-line client.
  • You know the basic concepts of networking as outlined in our overview.

Asymmetric cryptography

Before diving into details about how to access remote machines (over SSH), we need to make a brief refresh of some cryptography-related topics.

In this lab, we will be talking a lot about asymmetric cryptography. In general, it is a method of encryption/decryption where the user needs a different key for decryption of the message than the one that was used for message encryption.

This is different from symmetric ciphers. For example, the well-known Caesar cipher has a single key (the alphabet shift step) which is used for both encryption and decryption.

Asymmetric cryptography creates usually a pair of keys: a public key, that is usually used for encryption and a private one (for decryption). For example, if you make your encryption key public and decryption key private, everybody can encrypt a message for you, but only you can decrypt it. This is secure if it is impossible (or hard enough) to derive the private key from the public one, which is usually the case.

This has an obvious advantage: you do not need to create a secret symmetric key for every pair of users who would want to communicate. Instead, everybody can just distribute their public key and guard the single private key. (This is not as trivial as it looks: When Alice wants to send an encrypted message to Bob, she has to make sure that the public key does really belong to Bob. Otherwise, you can easily establish a secure connection, but to an attacker.)

Unfortunately, there is no good example of an asymmetric cipher as simple as the Caesar’s cipher. For an example, which is more complex, but still approachable, have a look at RSA.

Please note that selecting a good cipher is only a small step in communicating securely. If you want to learn more, please consult some real textbook on cryptography or attend one of our cryptographic courses. The above serves as a refresher to ensure we are on the same page for the rest of this lab.

Two uses for asymmetric cryptography

Asymmetric cryptography has two main uses. The first one is obvious: if we know the public key of the receiver of the message, we can use it to encrypt the message and send it over unprotected medium (and without fear that anyone else would be able to read it).

But it can be used also in reverse to authenticate the owner of the private key. We will always assume we are able to distribute the public keys safely here.

The mini-protocol is then able to authenticate (i.e., verify) that the other party is who they claim to be by proving the ownership of the private key (i.e., we assume that private keys were not stolen).

The method is very simple – the sender generates a random text and encrypts it with the public key of the receiver (the one we wish to verify). If the receiver is the real owner, they would be able to decrypt the random text and send it back to us. Inability to decrypt the text means that the receiver is not the owner of the private key.

Public & private key authentication

Typically a user authenticates to a service with a login and a password. While this method is quite natural and common for human users, it has several drawbacks.

The most obvious problem is password strength: people rarely have long passwords and not many people use any form of password manager. Using the same password at multiple places also allows administrator (or hacker) of one service to impersonate you in other services.

If you do not use a password manager, consider using one. The general idea is that you remember one (but strong!) password and this password encrypts rest of the passwords.

Therefore, all passwords can be generated to be long enough and unique for each service.

There are plenty of managers available, a simple one is pass that can use Git backend and has plenty of GUI clients available, including ones for Android and iOS.

Back to private/public key authentication. Some services allow the user to authenticate with their public key instead of using username/password.

The user uploads their public key to the server (using login and password for authenticating that operation) and when they want to log in, the server challenges them with a random secret encrypted with their public key. As the sole owner of the private key (and hence the only one able to decrypt), the user can decrypt the secret and confirm their identity. The operation then continues as with any other authenticated user.

There are also other options how to authenticate users, such as using special applications or hardware passkeys. They are out of scope for this course, we will focus solely on public/private key-pairs here.

Useful rules

For the public key authentication to work securely, the following is highly recommended (note that most of these rules apply to any other type of authentication, too).

The private key is like the password – it must not leak. Because the private key is usually a file, you must protect this file. Having an encrypted hard drive is a typical option for portable machines.

It is possible to protect the key itself with a passphrase (basically, another password). Then even a leaked private key file is not an immediate threat of identity theft. Note that there are helpers, such as ssh-agent(1), that can store the passphrase for some time so you do not have to enter it every time you use the key.

If you have multiple computers, it is preferred to use a different public/private key pair on each machine. If one machine is compromised, it it sufficient to remove its public key from all applications, while you can still use the other key pairs.

Cryptography overview: check you understand the basics

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

Using SSH

Enough of theory: let us connect to some remote machine. Let us explore SSH.

What is SSH?

SSH – that stands for Secure Shell – is a protocol for connecting to a different machine and running a shell there.

From a user perspective, after you SSH from a Linux machine into a different Linux machine, the shell may look the same and some commands would behave completely the same. Except they might be running on a different computer.

Note that this is intentional: remote shell is a natural way to control a Linux machine. No need to make it different from controlling it through a local shell.

SSH practically

Using SSH is very simple (unless you make it complex). To SSH to a remote machine, you need to know your credentials (i.e., login name and a password) and, of course, the name of the remote machine.

Then simply execute the following:

ssh YOUR_LOGIN@REMOTE_MACHINE_NAME

Note that the command ssh is often called a SSH client as it connects to the SSH server (similar to curl or wget being web clients connecting to a web server).

Your login will be usually case sensitive. For our (and university) servers it means that your login will be in lower case.

We have set up a remote machine for you on linux.ms.mff.cuni.cz. You will be using your GitLab (SIS/CAS) login and also the same password.

ssh your_gitlab_login@linux.ms.mff.cuni.cz

If your GitLab account was created manually, probably your SIS password will not work on this machine.

Please, contact us via this link and we will create an account for you manually.

The first login to the machine is a bit more complicated. SSH client wants from you a verification that you trust the remote server. It shows you a so-called server fingerprint:

The authenticity of host 'linux.ms.mff.cuni.cz (195.113.20.170)' can't be established.
ECDSA key fingerprint is SHA256:ltoc1TjoYhCZk6b8qSTAL6wFsRv7blw6u3h6NqCcYvI.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Based on your configuration, RSA or ED25519 key may be used instead:

RSA: SHA256:Z11Qbd6nN6mVmCSY57Y6WmxIJzqEFHFm47ZGiH4QQ9Y
ED25519: SHA256:/CVwDW388z6Z5VlhLJT0JX+o1UzakyQ+S01+34BI0BA

You should have received this fingerprint in a secure way before connecting to the server (for example, printed from your employer etc.). In this case, we hope that a potential attacker would not be able to break both into this web server and the SSH server at once. So we use the HTTPS protocol on the web as a secure way of verifying the SSH server.

The program then continues to ask your for a password and also informs you that the fingerprint was stored.

Usually, the password is not visible at all, i.e. nothing is printed (not even stars). That is fine: type your password and confirm with Enter.

On following logins, the SSH client checks that the fingerprint has not changed. A changed fingerprint belonging to the same machine (i.e., with the same DNS name) could indicate a man-in-the-middle attack. Do not connect when the fingerprint has changed. Always contact the administrator (e.g., the teachers in this particular case) and check with them what is happening.

If you were able to log-in, you will see an (almost) empty home directory and otherwise a normal Linux machine, this time without any graphical applications installed.

Try to run lscpu to see what machine you have logged in to.

Note that this machine is shared for all students of this course. Use it to solve graded tasks or to experiment with commands we show in the labs. You will be using it for the rest of the course for several tasks so keep it usable, please.

Do not use it for computationally intensive tasks or other tasks that are not related to this course.

We also strictly prohibit to use it for any kind of remote development with tools such as Visual Studio, IntelliJ IDEA or similar IDEs. These tools install huge blobs of code/data on the remote machine and because they rarely remove old versions, they are very quick in taking all free space available for themselves.

If we encounter any form of abusive use, we will block the offending account.

Whenever you are debugging issues with SSH, run the SSH client (ssh(1)) with the -v option, which turns on verbose logging, followed by the original arguments. It will print which keys were tried, full identification of the remote machine and other useful details.

When creating an issue about non-functional SSH, please, always paste the output of ssh -v ... there. Thank you!

Configuration of $PS1

We have already touched this a little bit in the previous lab as an extra for further reading.

$PS1 specified how your prompt looks like. From now on, you should ensure that your $PS1 shows also the machine name so that you always know where you are (i.e., which machine you are logged into).

Similarly to setting EDITOR in your ~/.bashrc you should ensure to specify the following (at least) if the default does not display the machine name.

PS1='\u@\h \w\$'

This ensures that you can see your username (\u), the hostname (\h) and also the working directory (\w).

Which ~/.bashrc you need to modify? Answer.

Return to previous lab if you want to see more options about setting your prompt.

As a personal tip: use colorful prompt without user/machine on your workstation but keep the non-colored version with \u@\h on all remote machines to keep short prompt on the personal machine but keep visual distinction when working on a remote one.

Using SSH to run one command

The command ssh is actually quite powerful and configurable. One important feature is that you can specify a command after the hostname and run this command directly. In this case, SSH never starts an interactive shell on the remote machine, but executes only the given command and returns.

Following commands prints uname -r on the remote machine.

ssh user@hostname uname -r

Investigate how (and why) the following command behaves differently.

The difference is visible only if you are SSHing to a different machine, that is when you execute ssh on your local machine.

ssh user@hostname uname -r >local_file.txt
ssh user@hostname "uname -r >remote_file.txt"

To verify that you are on a different machine, run on both uname -a and hostname -f (it provides the full DNS name of the current machine).

Can you explain the differences? Hint. Answer.

You can also trying checking free -h or uptime.

SSH and passwordless authentication

To enable authentication with public key over SSH, we need to perform two steps. Generate the public-private key pair and copy the public key to the remote machine.

To generate the keys we need to run the following command (the -C is actually a comment, providing e-mail or your login is the usual approach but keeping it empty is possible too).

The -t specifies the type of key we are generating. On most current installations the Ed25519 will be the default anyway so you can omit it completely.

Key generation always happens on the local machine, i.e. the one that we will eventually connect from.

We may want to generate a new key pair on the remote machine too (e.g. on linux.ms.mff.cuni.cz). But then that pair would be used for authentication to another service, such as GitLab (i.e. linux.ms.mff.cuni.cz would be the local one in the communication).

ssh-keygen -t ed25519 -C "your_email@example.com"

The program would ask us where to store the generated private and public key. Keep the defaults. Choose if you want a passphrase or not (it is more secure to have one, but the use is a bit more cumbersome). After ssh-keygen finishes, check that the directory ~/.ssh contains id_ed25519 (the private key) and id_ed25519.pub (the public key).

Do not specify a different location for the keys and a different filename. Otherwise SSH and other program will not be able to find them (with extra configuration from your side)!

When uploading them to your student-LOGIN repository, copy them from .ssh and rename the accordingly in your repo only (see the tasks at the end of the lab).

Feel free to inspect their content, e.g. using cat. Surprised that they are text files?

Once we have the public key ready, we need to upload it to the remote machine. If you have multiple key pairs, read about the -i switch.

ssh-copy-id LOGIN@REMOTE_MACHINE

If you log in to the remote machine again, the SSH client should use the key pair and log you in without asking for a password. If not, run SSH with -vvv to debug the issue.

Note that the public key was stored into ~/.ssh/authorized_keys file on the remote machine. You can copy it there manually but using ssh-copy-id is easier.

If the copying fails with cryptic message about warning: here-document at line 251 delimited by end-of-file (wanted EOF), try upgrading the SSH client first.

If you use the image from us, simple sudo dnf upgrade openssh-clients should work.

Using keys only

Note that some services actually require that you authenticate using a key pair instead of a password as it is considered more secure.

The advantage is that any random attackers could keep guessing your password and still never get access to your machine.

Automated client ban

Typically, SSH server is also configured to ban any client that tries to login without success several times in a row. Our server does that, too.

Copying files

If you have deciphered what the following command does, you should by now have an idea how to copy files to and from a remote machine (we are not saying it would be the most effective way):

ssh user@hostname "uname -r >remote_file.txt"

Wondering how this helps you copy the files? Think about it a bit more before reading on, consider how pipes are used etc.

Have you really thought about it? :-)

To copy the files, we can leverage cat that simply dumps the file as-is to stdout. We will pipe its output to SSH and on the other machine run second cat to store the file.

cat README.md | ssh user@hostname "cat >remote-readme.md"

Now, please, ensure that you can explain what is happening. SSH is able to read stdin (after all, we were typing our commands locally and they appeared in the remote shell on our local screen) and hence we can tunnel the data through it.

Make sure you can explain what is happening in the following cases. Understanding the commands below virtually guarantees you understand how SSH works and what is running where (and where the files will be created).

cat /etc/os-release | ssh login@linux.ms.mff.cuni.cz "cat >client-os.txt"
ssh login@linux.ms.mff.cuni.cz cat /etc/os-release >server-os.txt

There are also scp and rsync that can be used for copying multiple files over SSH easily but we will talk about these in later labs.

File managers

Many file managers allows you to use SSH transparently and copy between machines with the same ease as when working with local files.

For example, in mc, select Shell connection either in left or right panel and specify SSH connection. One of the panels will show the files on the remote machine. Try using F5 to copy files interactively.

Using machines in Rotunda and other labs

Apart from the machine linux.ms.mff.cuni.cz, there are also other machines available.

All the Linux machines in the labs (and in Rotunda on Malostranské náměstí) are also reachable via SSH. Again, use your SIS credentials to log in. Note that all machines in Rotunda (but not linux.ms.mff.cuni.cz!) share the same home directory, i.e., it does not matter which one you physically connect to. Your files will be available on all machines.

The same home directory is shared across all lab machines at Malostranské náměstí and in IMPAKT (i.e., SSHing into u-pl1.ms.mff.cuni.cz and creating a file there is the same as if you physically attend lab in N8/N11 and create the lab while logged in to the machine via GUI).

Unfortunately, the used file system and authentication mechanism does not allow to use public key authentication for Rotunda machines. You need to always specify your password. (linux.ms.mff.cuni.cz does not have this limitation and we expect you will use public key authentication there.)

Following machines are available.

  • Lab SU1
    • u1-1.ms.mff.cuni.cz
    • u1-2.ms.mff.cuni.cz
    • u1-14.ms.mff.cuni.cz
  • Lab SU2
    • u2-1.ms.mff.cuni.cz
    • u2-2.ms.mff.cuni.cz
    • u2-25.ms.mff.cuni.cz
  • Rotunda
    • u-pl1.ms.mff.cuni.cz
    • u-pl2.ms.mff.cuni.cz

The computers in Lab SU1 and SU2 can not be connected to via SSH during the day (or more specifically during the scheduled classes). That is to prevent remote users to interfere with classes. Rotunda lab machines are accessible 24/7.

Host keys

Below is a list of our servers and their host keys (they are printed when you connect to them for the first time and SSH warns you on changes).

  • u-pl0.ms.mff.cuni.cz
    • 256 SHA256:a4cEChPmXAbaQiEb4QKmDvddk/pgXqusLRIQLsQTKFM u-pl0.ms.mff.cuni.cz (ED25519)
    • 256 SHA256:U6u6eLekctQDr9uy4CKZJeDFjcCWqCI/v9owL1NODcE u-pl0.ms.mff.cuni.cz (ECDSA)
    • 1024 SHA256:8NUbwUmLxG3NfKSLy0ORuOxjQBTSirnXo1p/WQ0Z6vw u-pl0.ms.mff.cuni.cz (RSA)
  • linux.ms.mff.cuni.cz
    • 256 SHA256:/CVwDW388z6Z5VlhLJT0JX+o1UzakyQ+S01+34BI0BA linux.ms.mff.cuni.cz (ED25519)
    • 256 SHA256:ltoc1TjoYhCZk6b8qSTAL6wFsRv7blw6u3h6NqCcYvI linux.ms.mff.cuni.cz (ECDSA)
    • 3072 SHA256:Z11Qbd6nN6mVmCSY57Y6WmxIJzqEFHFm47ZGiH4QQ9Y linux.ms.mff.cuni.cz (RSA)
  • gitlab.mff.cuni.cz
    • 256 SHA256:jRH0TCd3DTvckbie4NNSAqiUOs/H/J3X44zhLyG2x0E gitlab.mff.cuni.cz (ED25519)
    • 256 SHA256:feqdasElJ4gNZxPFoR6ynKl8ERDPSV/66jWQBUykzuk gitlab.mff.cuni.cz (ECDSA)
    • 2048 SHA256:Irez3gnPeMX5S8dniRsqTZU7hpuoqIXGsHI92IGte7o gitlab.mff.cuni.cz (RSA)

SSH: review your knowledge

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

SSH configuration

The SSH client is configured via the ~/.ssh/config file. Review the syntax of this file via man 5 ssh_config.

The file is divided into sections. Each section is related to one or more remote hosts. The section header is in the format Host pattern, where pattern might use wildcards.

The syntax is mostly self-explanatory, so we will only provide an example.

Host *
    IdentityFile ~/.ssh/id_ed25519

Host intro
    Hostname linux.ms.mff.cuni.cz
    User YOUR_SIS_LOGIN

Host mff0
    Hostname u-pl0.ms.mff.cuni.cz
    User YOUR_SIS_LOGIN

Host mff1
    Hostname u-pl1.ms.mff.cuni.cz
    User YOUR_SIS_LOGIN

With this ~/.ssh/config, we can type ssh intro and the ssh will start connection equivalent to

ssh YOUR_SIS-LOGIN@linux.ms.mff.cuni.cz

Git over SSH

So far, we have used Git over HTTPS. Git can be used over SSH too. Then, the traffic is basically tunneled through an SSH connection and Git relies on the SSH wrapper for security as well as for (partial) authentication.

Virtually all Git servers (GitLab, GitHub, Bitbucket…) will require you to upload your public key if you want to use Git over SSH.

To actually use Git over SSH, we first need to tell GitLab about our SSH keys (recall the protocol that is used to authenticate the user).

GitLab and SSH keys

Copy your public key to GitLab. Navigate to right-top menu with your avatar, select Preferences and then SSH keys or visit this link.

Copy your public key there and name it. Typically, the name should mention your username and your machine. Note that GitLab will send you an e-mail informing you about a new key. Why? Hint. Answer.

Go to your project and clone it again. This time, use the Clone with SSH URL.

git clone git@gitlab.mff.cuni.cz:teaching/nswi177/2025/student-LOGIN.git

Have you noticed that this looks like SSH address? It actually is exactly that. The first part identifies the machine and the user (git) and after a colon is a local path.

This way, you can clone a Git directory from any SSH server by specifying its remote path there (here, GitLab does some mangling but the principle holds).

Note that the user we clone with is git – not you. This way, GitLab needs only one physical user account for handling Git requests and distinguishes the users via their public keys. How? Answer.

By the way, what happens if you try to run the following?

ssh git@gitlab.mff.cuni.cz

Note that you should prefer the SSH protocol for working with Git as it is much more comfortable for use.

Git on other platforms also offers generation of an SSH key but often the key is usable only by one application (different applications have incompatible key formats), while on Linux a single key is generally usable for Git, other machines, and other services.

Rest of the work with Git remains the same. git add, git commit, git push etc. will work the same but only the communication with GitLab goes through SSH tunnel. Note that you don’t have to reenter your credentials while doing git push. This is because git remembers how did you git clone the repository and will use the same URL (either HTTPS or SSH) for git push as well (unless you configure it otherwise). And since you used SSH for pulling, it will use SSH for pushing as well, which uses the public/private authentication you already set up.

Basic networking tools

Most of the time, the networking on your machine will just work.

But when there are issues it is good to know which tools are available and how to perform basic network debugging.

Network Manager

There are several ways how to configure networking in Linux. Server admins often prefer to use the bare ip command or they setup networking through systemd-networkd; on desktops most distributions today use the NetworkManager, so we will show it here too. Note that the ArchLinux Wiki page about NetworkManager contains a lot of information, too.

Server network configuration is part of the Linux administration course.

NetworkManager has a GUI (you probably used its applet without knowing about it), a TUI (which can be run with nmtui), and finally a CLI.

We will (for obvious reasons) focus on the command-line interface here. Without parameters, nmcli will display information about current connections:

wlp58s0: connected to TP-Link_1CE4
        "Intel 8265 / 8275"
        wifi (iwlwifi), 44:03:2C:7F:0F:76, hw, mtu 1500
        ip4 default
        inet4 192.168.0.105/24
        route4 0.0.0.0/0
        route4 192.168.0.0/24
        inet6 fe80::9ba5:fc4b:96e1:f281/64
        route6 fe80::/64
        route6 ff00::/8

p2p-dev-wlp58s0: disconnected
        "p2p-dev-wlp58s0"
        wifi-p2p, hw

enp0s31f6: unavailable
        "Intel Ethernet"
        ethernet (e1000e), 54:E1:AD:9F:DB:36, hw, mtu 1500

vboxnet0: unmanaged
        "vboxnet0"
        ethernet (vboxnet), 0A:00:27:00:00:00, hw, mtu 1500

lo: unmanaged
        "lo"
        loopback (unknown), 00:00:00:00:00:00, sw, mtu 65536

DNS configuration:
        servers: 192.168.0.1 8.8.8.8
        interface: wlp58s0

...

Compare the above with the output of ip addr. Notice that NetworkManager explicitly states the routes by default and also informs you that some interfaces are not controlled by it (here, lo or vboxnet0).

Changing IP configuration

While most networks offer DHCP (at least those you will connect to with your workstation), sometimes you need to set up IP addresses manually.

A typical case is when you need to connect two machines temporarily, e.g., to transfer a large file over a wired connection (in our example, it is over the enp0s31f6 interface).

Do not forget that IP address is bound to a network interface (often abbreviated to just if). When configuring IP addresses you need to know both the network (subnet) and the interface.

The only thing you need to decide on is which network you will create. Do not use the same one as your home router uses; our favourite selection is 192.168.177.0/24.

Assuming the name from above, the following command adds a connection named wired-static-temp on enp0s31f6:

sudo nmcli connection add \
    con-name wired-static-temp \
    ifname enp0s31f6 \
    type ethernet \
    ip4 192.168.177.201/24

It is often necessary to bring this connection up with the following command:

sudo nmcli connection up wired-static-temp

Follow the same procedure on the second host, but use a different address (e.g., .202). You should be able to ping the other machine now:

ping 192.168.177.201

To demonstrate how ping behaves when the connection goes down, you can try unplugging the wire, or doing the same in software:

sudo nmcli connection down wired-static-temp

And once you are done you can also remove it completely via nmcli connection delete.

Note that the above command for creating a connection over Ethernet can be modified even for WiFi networks (though there the chances are it will be with DHCP: as a matter of fact, Network Manager can create it for you even with Internet sharing quite easily).

nmcli connection add \
    con-name wifi-static-temp \
    ifname wlp58s0 \
    type wifi \
    ssid "SSID of the Wifi" \
    wifi-sec.key-mgmt "wpa-psk" \
    wifi-sec.psk "WiFi password" \
    ip4 192.168.177.203/24

Other networking utilities

We will not substitute the networking courses here, but we mention some basic commands that could help you debug basic network-related problems.

You already know ping: the basic tool to determine whether a machine with a given IP address is up (and responding to a network traffic).

ping is the basic tool if you suddenly lose a connection to some server. Ping the destination server and also some other well-known server. If the packets are going through, you know that the problem is on a different layer. If only packets to the well-known server gets through, the problem is probably with the server in question. If both fail, your network is probably down.

But there are more advanced tool available too.

traceroute (a.k.a. the path is the goal)

Sometimes, it can be handy to know the precise path, which the packets travel. For this kind of task, we can use traceroute.

Similarly to ping, we need to just specify the destination.

traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
 1  _gateway (10.16.2.1)  2.043 ms  1.975 ms  1.948 ms
 2  10.17.0.1 (10.17.0.1)  1.956 ms  1.971 ms  1.961 ms
 3  gw.sh.cvut.cz (147.32.30.1)  1.947 ms  1.973 ms  1.977 ms
 4  r1sh-sush.net.cvut.cz (147.32.252.238)  2.087 ms  2.262 ms  2.527 ms
 5  r1kn-konv.net.cvut.cz (147.32.252.65)  1.856 ms  1.849 ms  1.847 ms
 6  kn-de.net.cvut.cz (147.32.252.57)  1.840 ms  1.029 ms  0.983 ms
 7  195.113.144.172 (195.113.144.172)  1.894 ms  1.900 ms  1.885 ms
 8  195.113.235.99 (195.113.235.99)  4.793 ms  4.748 ms  4.723 ms
 9  nix4.cloudflare.com (91.210.16.171)  2.264 ms  2.807 ms  2.814 ms
10  one.one.one.one (1.1.1.1)  1.883 ms  1.800 ms  1.834 ms

The first column corresponds to the hop count. The second column represents the address of that hop and after that, you see three space-separated times in milliseconds. traceroute command sends three packets to the hop and each of the time refers to the time taken by the packet to reach the hop. So from the foregoing output we can see that the packages visited 10 hops on its way between the local computer and the destination.

This tool is especial useful, when you have network troubles and you are not sure where the issue is.

traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
 1  10.21.20.2 (10.21.20.2)  0.798 ms  0.588 ms  0.699 ms
 2  10.21.5.1 (10.21.5.1)  0.593 ms  0.506 ms  0.611 ms
 3  192.168.88.1 (192.168.88.1)  0.742 ms  0.637 ms  0.534 ms
 4  10.180.2.113 (10.180.2.113)  1.696 ms  4.106 ms  1.483 ms
 5  46.29.224.17 (46.29.224.17)  14.343 ms  13.749 ms  13.806 ms
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

From this log we can see that the last visited hop was 46.29.224.17, so we can focus our attention to this network element.

nmap (a.k.a. let me scan your network)

nmap is a very powerful tool. Unfortunately, even an innocent – but repeated – usage could be easily misinterpreted as a malicious scan of vulnerabilities that are susceptible to attack. Use this tool with care and experiment in your home network. Reckless scanning of the university network can actually ban your machine from connecting at all for quite some time.

nmap is the basic network scanning tool. If you want to know which network services are running on a machine you can try connecting to all of its ports to check which are opened. Nmap does that and much more.

Try first scanning your loopback device for internal services running on your machine:

nmap localhost

The result could look like this (the machine has a print server and a proxy HTTP server):

Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-04 16:38 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00011s latency).
Other addresses for localhost (not scanned): ::1
rDNS record for 127.0.0.1: localhost.localdomain
Not shown: 998 closed ports
PORT     STATE SERVICE
631/tcp  open  ipp
3128/tcp open  squid-http

Nmap done: 1 IP address (1 host up) scanned in 0.11 seconds

If you want to see more information, you can try adding -A switch.

nmap -A localhost

And if you run it under root (i.e. sudo nmap -A localhost) nmap can try to detect the remote operating system, too.

By default, nmap scans only ports frequently used by network services. You can specify a different range with the -p option:

nmap -p1-65535 localhost

This instructs nmap to scan all TCP ports (-p1-65535) on localhost.

Again: do not scan all TCP ports on machines in the university network!

As an exercise, which web server is used on our GitLab? And which one is on our University website? Solution.

nc (netcat)

Let us examine how to create network connections from the shell. This is essential for debugging of network services, but it is also useful for using the network in scripts.

The Swiss-army knife of network scripting is called netcat or nc.

Unfortunately, there exist multiple implementations of netcat, which differ in options and capabilities. We will show ncat, which is installed by default in Fedora. Your system might have a different one installed.

Trivial things first: if you want to connect to a given TCP port on a remote machine, you can run nc machine port. This establishes the connection and wires the stdin and stdout to this connection. You can therefore interact with the remote server.

Netcat is often connected to other commands using pipes. Let us write a rudimentary HTTP client:

echo -en "GET / HTTP/1.1\r\nHost: www.kernel.org\r\n\r\n" | nc www.kernel.org 80

We are using \r\n, since the HTTP protocol wants lines terminated by CR+LF. The Host: header is mandatory, because HTTP supports multiple web sites running on the same combination of IP address and port.

We see that http://www.kernel.org/ redirects us to https://www.kernel.org/, so we try again using HTTPS. Fortunately, our version of netcat knows how to handle the TLS (transport-layer security) protocol used for encryption:

echo -en "GET / HTTP/1.1\r\nHost: www.kernel.org\r\n\r\n" | nc --ssl www.kernel.org 443

Now, let us build a simple server. It will listen on TCP port 8888 and when somebody connects to it, the server will send contents of a given file to the connection:

nc --listen 8888 <path-to-file

We can open a new shell and try receiving the file:

nc localhost 8888

We receive the file, but netcat does not terminate – it still waits for input from the stdin. Pressing Ctrl-D works, but it is easier to tell netcat to work in one direction only:

nc localhost 8888 --recv-only

OK, this works for transferring a single file over the network. (But please keep in mind that the transfer is not encrypted, so it is not wise to use it over a public network.)

When the file is transferred, the server terminates. What if we want to run a server, which can handle multiple connections? Here, redirection is not enough since we need to read the file multiple times. Instead, we can ask netcat to run a shell command for every connection and wire the connection to its stdin and stdout:

nc --listen 8888 --keep-open --sh-exec 'cat path-to-file'

Of course, this can be used for much more interesting things than sending a file. You can take any program which interacts over stdin and stdout and make it into a network service.

Going further: using tmux for better SSH experience

Few extra bits that will improve your user experience with SSH a lot but can be returned to any time later.

tmux is a terminal multiplexer. That means that inside one terminal it opens several terminals for you that are running in parallel. It also allows you to send the session into background so that it remains there even if you log out or your remote connection is interrupted (this is useful for running long scripts). In other words, tmux gives you tabs (called windows) inside your existing session that can be minimized/iconified (if borrowing terms from GUI would explain the usefulness better).

The simplest way how to start tmux session is simply:

tmux

Alternatively, we can start session with some meaningful name:

tmux new -s <session_name>

To list all sessions run:

tmux ls

To connect/attach to the running session run:

tmux attach -t <session_name>

And finally, in order to kill the session we use:

tmux kill-session -t <session_name>

Inside the session we are able to create multiple windows, split the screen and much more. In order to invoke a tmux command, we need firstly to type tmux prefix. The default key binding is <Ctrl>-b.

In order to detach from session we can simply press (do not forget to type the prefix!):

d  detach from session

Operation with windows:

c  create window
w  list windows
n  next window
p  previous window
f  find window
,  name window
&  kill window

Sometimes it is useful to split the screen into several terminals. These splits are called panes.

Operation with panes (splits):

%  vertical split
"  horizontal split

o  swap panes
q  show pane numbers
x  kill pane
←  switch to left pane
→  switch to right pane
↑  switch to upward pane
↓  switch to downward pane

Other feature is that you can toggle writing simultaneously to all panes. Performing the same operation multiple times may seem not much useful, but you can for example open several different ssh connections in advance and then interactively control all these computers at the same time.

To toggle it, type the prefix and then write :set synchronize-panes. If you want to try this in Rotunda, please do not run computationally intensive tasks…

As usual with Linux tools, you can modify its behavior widely via rc configuration. For instance, in order to navigate among the panes with vim shortcuts, modify your .tmux.conf so it contains

bind-key C-h run "tmux select-pane -L"
bind-key C-j run "tmux select-pane -D"
bind-key C-k run "tmux select-pane -U"
bind-key C-l run "tmux select-pane -R"

Personal tip № 0: tmux is an excellent tools for collaboration, as multiple users can attach to the same session.

Personal tip № 1: when you give a lecture, you can attach to the tmux session from two terminals. Later on, you push the first one to the projector, while the second one is on you laptop screen. This eliminates the necessity of mirroring your screen. Together with pdfpc and a tiling window manager we get a Swiss-army knife for presentation.

There is much more to say. For more details see this tmux cheatsheet or manual pages.

Tasks to check your understanding

We expect you will solve the following tasks before attending the labs so that we can discuss your solutions during the lab.

Store your public keys into keys/key.[0-9].pub on GitLab (the wildcard denotes the ability to upload multiple keys if you are using multiple machines – obviously, the actual name of the file will be keys/key.0.pub or keys/key.1.pub).

Do not lose the private part for them — we will use it for some other tasks later on.

This example can be checked via GitLab automated tests. Store your solution as keys/key.[0-9].pub and commit it (push it) to GitLab.

Graded mini-homework

This will work only after you upload your keys to keys/key.[0-9].pub.

Then you should be able to clone the following repository (as usual, LOGIN is your GitLab login in lowercase) over SSH.

gitolite3@linux.ms.mff.cuni.cz:lab05-LOGIN

We are updating the keys daily, report issues only if you cannot access the repository 24 hours after changing your keys/key.[0-9].pub files.

If the git clone command asks for a password, your setup is probably broken. You will be using key-based authentication here and the only password that makes sense in this setup is a passphrase of your (private) key (if you have selected to employ one).

Do not enter you GitLab password there. It will not work.

Usual suspects to check: you are on the machine with the key you have uploaded (check ~/.ssh), wait 24 hours after uploading the key, check that the pipeline keys is in the green.

The repository (after cloning) will be empty (and Git will tell you so). That is fine. The point is to check that you can clone a different repository without having any web UI available.

Create a file uptime.txt with output of uptime and a file uname.txt containing output of uname -a.

Put these files into the root of the repository, commit them and push the commit back to the server.

The deadline for this task is March 23.

Add the following public key to authorized keys on your account at linux.ms.mff.cuni.cz. We will check that you have completed this task by SSHing to linux.ms.mff.cuni.cz with your login and this key.

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPuoJJldIS6zOxunFxIFGk6tQlw0qpYSOxHYs57117o/ teachers-nswi177@d3s.mff.cuni.cz

We will create file FROM_TEACHERS once you have setup our key (again, give us some time to run our scripts).

This is to ensure that you can setup remote login for someone else without breaking anything :-).

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).

After class checklist

The list below captures the most important actions that you should have completed by now. Not having them done will make the next lab impossible to complete or will greatly hinder your progress.

  • I have uploaded by public key to my GitLab project.

  • I have completed the mini-homework.

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 basic principles of network communication (in OS agnostic manner)

  • explain basic principles of asymmetric cryptography

  • explain in detail how asymmetric cryptography (public and private key) can be used to authenticate a user

  • explain what is SSH and what functions it offers

  • explain how differs execution of programs locally vs over SSH remotely

  • explain difference between using Git over HTTPS vs Git over SSH

  • explain why use of nmap is often prohibited/limited by network administrators

Practical skills

Practical skills are usually about usage of given programs to solve various tasks. Therefore, you should be able to …

  • set PS1 variable to distinguish different machines

  • use ssh command to login to a remote machine

  • execute commands on a remote machine using SSH

  • use hostname command

  • transfer files over SSH using cat

  • setup password-less authentication on a remote Linux machine using a private/public key pair

  • setup publickey-based authentication to GitLab

  • use git clone (and pull and push) over SSH

  • optional: configure SSH shortcuts

  • optional: use basic functions of tmux terminal multiplexer

  • use nc for basic operations

  • use nmap for basic network scanning

  • use ip command to query current network configuration

  • use ping and traceroute as basic tools for debugging networking issues

  • optional: use NetworkManager to set up static IP addressing

This page changelog

  • 2025-03-11: Extra hints for the graded mini-homework.

  • 2025-03-12: nmcli example for WiFi network.

  • 2025-03-14: Scripts for checking teachers-nswi177@d3s.mff.cuni.cz key (FROM_TEACHERS) are running twice every day.

  • 2025-03-18: Explicitly mention the need to know which interface IP address is bound to.

  • 2025-03-21: Add host keys of MFF servers.

  • 2025-04-09: Extra warning about naming files with keys.