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

In this lab we will do a quick refresh of the principles of networking and asymmetric cryptography. And then start using SSH: a way to work on a remote Linux machine in the shell. We would also talk a little bit about access rights for Linux machines as they will be important for us when working on a shared machine.

We will also look at basic network utilities that would allow you to read your network configuration and debug connectivity issues.

Do not forget that the Before class reading is mandatory and there is a quiz that you are supposed to complete before coming to the labs.

This reading is before the seventh lab.

Before class reading

The before class reading is divided into four big sections. Networking overview that you can actually skip if you have already taken some networking course and understand what is packet, IP address or TCP port. Unix-style access rights that explain who and when can access files on Linux. Then we continue with a short refresher on asymmetric cryptography that you probably already know, too. Finally, we introduce SSH (secure remote shell).

Networking

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. Feel free to skip or just skim through it for a quick refresh.

Unix-style access rights

So far we have silently ignored the fact that there are different user accounts on any Linux machine. And that users cannot access all files on the machine. In this section we will explain the basics of Unix-style access rights and how to interpret them.

Recall what we said about /etc/passwd – it contains the list of user accounts on that particular machine (technically, it is not the only source of user records, but it is a good enough approximation for now).

Every running application, i.e., a process, is owned by one of the users from /etc/passwd (again, we simplify things a little bit). We also say that the process is running under a specific user.

And every file in the filesystem (including both real files such as ~/.bashrc and virtual ones such as /dev/sda or /proc/uptime) has some owner.

When a process tries to read or modify a file, the operating system decides whether the operation is permitted. This decision is based on the owner of the file, the owner of the process, and permissions defined for the file. If the operation is forbidden, the input/output function in your program raises an exception (e.g., in Python), or returns an error code (in C).

Since a model based solely on owners would be too inflexible, there are also groups of users (defined in /etc/group). Every user is a member of one or more groups, one of them is called the primary group. These are associated with every process of the user. Files have both an owning user and an owning group.

Files are assigned three sets of permissions: one for the owner of the file, one for users in the owning group, and one for all other users. The exact algorithm for deciding which set will be used is this:

  1. If the user running the process is the same as the owner of the file, owner access rights are used (sometimes also referred to as user access rights).
  2. If the user running the process is in a group that was set on the file group access rights are used.
  3. Otherwise, the system checks against other access rights.

Every set of permissions contains three rights: read (r), write (w), execute (x):

  • Read and write operations on a file are obvious.

  • The execute right is checked when the user tries to run the file as a program (recall that without chmod +x, the error message was in the sense of Permission denied: this is the reason).

    • Note that a script which is readable, but not executable, can be still run by launching the appropriate interpreter manually.
    • Note that when a program is run, the new process will inherit the owner and groups of its parent (e.g., of the shell that launched it). Ownership of the executable file itself is not relevant once the program was started. For example, /usr/bin/mc is owned by root, yet it can be launched by any user and the running process is then owned by the user who launched it.

The same permissions also apply to directories. Their meaning is a bit different, though:

  • Read right allows the user to list directory entries (files, symlinks, sub-directories, etc.).
  • Write right allows the user to create, remove, and rename entries inside that directory. Note that removing write permission from a file inside a writable directory is pointless as it does not prevent the user from overwriting the file completely with a new one.
  • Execute right on a directory allows the user to open the entries. (If a directory has x, but not r, you can use the files inside it if you know their names; however, you cannot list them. On the contrary, if a directory has r, but not x, you can only view the entries, but not use them.)

Permissions of a file or directory can be changed only by its owner, regardless of the current permissions. That is, the owner can deny access to himself by removing all access rights, but he can always restore them later.

root account

Apart from accounts for normal users, there is always an account for a so-called superuser – more often called simply just root – that has administrator privileges and is permitted to do anything with any file in the system. The permissions checks described above simply do not apply to root-owned processes.

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

Viewing and changing the permissions

Looking at the shortcuts of rwx for individual permissions, you may found them familiar:

drwxr-xr-x 1 intro intro 48 Feb 23 16:00 02/
drwxr-xr-x 1 intro intro 60 Feb 23 16:00 03/
-rw-r--r-- 1 intro intro 51 Feb 23 16:00 README.md

The very first column actually contains the type of the entry (d for directory, - for a plain file, etc.) and three triplets of permissions. The first triplet refers to owner of the file, the middle one to the group, and last to the rest of the world (other). The third and fourth columns contain owner and group of the file.

Typically, your personal files in $HOME will have you as the owner together with a group with the same name. That is a default configuration that prevents other users seeing your files.

Note that most of the files are actually world-readable (i.e. anyone can read them).

That is actually quite fine because if you check permissions for your $HOME, you will see that it is typically drwx------. Only the owner can modify and cd to it. Since no one can actually change to your directory, no one will be able to read your files (technically, reading a file means traversing the whole directory and checking access rights on the whole path).

To change the permissions, you can use chmod program. It has the general format of

chmod WHO[+=-]PERMISSION file1 file2 ...

WHO can be empty (for all three of user, group and others) or one of u, g or o. And PERMISSION can be one of r, w or x.

Sticky and other bits

If you execute the following command, you will see a bit different output that you would probably expect.

ls -ld /usr/bin/passwd /tmp
drwxrwxrwt 23 root root   640 Mar  3 08:15 /tmp/
-rwsr-xr-x  1 root root 51464 Jan 27 14:47 /usr/bin/passwd*

You should have noticed that /tmp has t in place of an executable bit and passwd has s there.

Those are special variants of the executable bit. The t bit on a directory specifies that user can remove only his own files. The reason is obvious – you shall not be able to remove someone else’s files inside /tmp. Something that is otherwise impossible to specify with traditional (basic) permissions.

The s bit (sticky) is a bit more tricky. It specifies that no matter who runs the shell, passwd will be running under the user owning the file (i.e., root for this file).

While it may look useless, it is a simple way to allow running certain programs with elevated (higher) permissions. passwd is a typical example. It allows the user to change his password. However, this password is stored in a file that is not readable by any user on the system except root (for obvious reason). Giving s bit to the executable means that the process would be running under root and would be able to modify the user database (i.e., /etc/passwd and /etc/shadow that contains the actual passwords).

Since changing the permissions can be done only by the owner of the file, there is no danger that a malicious user would add the s bit to other executables.

There are other nuances regarding Unix permissions and their setting, refer to chmod(1) for details.

Beyond traditional Unix permissions: POSIX ACL

The permission model described above is a rare example of a concept coming from Unix that is considered inflexible for use today. However, it is also considered as a typical example of a simple but well usable security model.

Many programs copied this model and you can encounter it in other places too. It is definitely something worth remembering and understanding.

The inflexibility of the system comes from the fact that allowing a set of users to access a particular file means creating a special group for these users. These groups are defined in /etc/group and require administrator privileges.

With an increasing number of users, the amount of possibly needed groups grows exponentially. On the other hand, for most situations, the basic Unix permissions are sufficient.

To tackle this problem, Linux offers also so-called POSIX access control lists where it is possible to assign an arbitrary list of users to any file to specify the permissions.

We require you to know that getfacl and setfacl are the utilities to control these rights but since these are practically needed rarely, we will leave their knowledge at the level of reading the corresponding manpages.

About asymmetric cryptography

Before diving into details about 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.

Typical use of asymmetric cryptography involves making one of the keys public, while the other one is kept private. 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 just distributes his public key and guards 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 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 he claims 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, he 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 same passwords on multiple places also allows administrator (or hacker) of one service to impersonate you in other services.

Instead, some services allow the user to authenticate with his public key. The user uploads the public key to the server (using login and password for authenticating that operation) and when he wants to log in, the server challenges him with a random secret encrypted with his public key. As he is the sole owner of the private key (and hence the only one able to decrypt), he can decrypt the secret and confirm his identity. The operation then continues as with any other authenticated user.

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.

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 (and secure) shell is a natural way to control a Linux machine. No need to make it different from controlling it through a local shell.

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.

We will do this during the labs. Now only recall the text above to understand the principle why GitLab is able to authenticate you via a public key (i.e., with a public key, you do not specify your username).

Before class quiz

The quiz file is available in the 07 folder of this GitLab project.

Copy the right language mutation into your project as 07/before.md (i.e., you will need to rename the file).

The questions and answers are part of that file, fill in the answers in between the **[A1]** and **[/A1]** markers.

The before-07 pipeline on GitLab will test that your answers are in the correct format. It does not check for actual correctness (for obvious reasons).

Submit your before-class quiz before start of lab 07.

Using SSH

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

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_SIS_LOGIN@linux.ms.mff.cuni.cz

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.

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 him what is happening.

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

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. Do not use it for computationally intensive tasks or other tasks that are not related to this course. If we encounter any form of abusive use, we will block the offending account.

Using machines in Rotunda

Apart from the machine linux.ms.mff.cuni.cz, there is also a full lab of machines available in the Rotunda computer lab on Malostranské náměstí.

All the Linux machines in the lab 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, i.e., it does not matter which one you physically connect to. Your files will be available on all machines.

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
    • u-pl23.ms.mff.cuni.cz

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.

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 see the differences?

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

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

Feel free to inspect their content. 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.

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

Disabling login/password

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.

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

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 mff1
    Hostname u-pl6.ms.mff.cuni.cz
    User YOUR_SIS_LOGIN

Host mff2
    Hostname u-pl17.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

We recommend to use different u-pl* hostnames in your config to distribute the load across multiple machines. Note that the Rotunda machines may be unevenly loaded, so it is a good idea to bookmark several of them and re-login if the first one is too slow.

Copying files

SCP

In order to copy files between two Linux machines, we can use scp. Internally, it establishes a SSH connection and copies the files over it.

The syntax is very simple and follows the semantics of a plain cp:

scp local_source_file.txt user@remote_machine:remote_destination_file.txt
scp user@remote_machine:remote_source_file.txt local_destination_file.txt

SCP issues

For those who care about security we should note that that the SCP protocol has some security vulnerabilities. These can be used to attack your “local” computer while connecting to a malicious server.

SCP is actually a very old protocol, which is showing its age. Better replacements include SFTP (beware that this is different from FTPS – FTP over SSL/TLS) and Rsync.

More information on this topic can be found on LWN.net.

Rsync

A much more powerful tool for copying of files is rsync. Similarly to scp, it runs over a SSH connection, but it has to be installed at both sides. It can copy whole directory trees, handle symlinks, access rights, and other file attributes. It can also detect that some of the files are already present at the other side (either exactly or approximately) and transfer just the differences.

The syntax of a simple copy follows cp and scp, too:

rsync local_source_file.txt user@remote_machine:remote_destination_file.txt
rsync local_source_file.txt user@remote_machine:remote_destination_directory/

File managers

Many file managers allows you to open a SCP-style connection 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.

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/2022/student-LOGIN.git

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

You can clone this way 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 use the SSH protocol for working with Git as it is much more comfortable for use. Note that 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 a generally usable for Git, other machines, and other services.

More about access rights

Let’s return a little bit to the access rights.

Change permission of some of your scripts to be --x. Try to execute them. What happens? Answer.

Remove writable bit for a file and write to it using stdout redirection. What happens?

Reading network configuration

For the following text we will assume your machine is connected to the Internet (this includes your virtualized installation of Linux).

The basic command for setting and reading network configuration is ip.

Probably the most useful one is ip addr.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 54:e1:ad:9f:db:36 brd ff:ff:ff:ff:ff:ff
3: wlp58s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 44:03:2c:7f:0f:76 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.105/24 brd 192.168.0.255 scope global dynamic noprefixroute wlp58s0
       valid_lft 6209sec preferred_lft 6209sec
    inet6 fe80::9ba5:fc4b:96e1:f281/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
8: vboxnet0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0a:00:27:00:00:00 brd ff:ff:ff:ff:ff:ff

It lists four interfaces (lo, enp0s31f6, wlp58s0 and vboxnet0) that are available on the machine. Your list will differ as well as the naming.

The name signifies interface type.

  • lo is the loopback device that will be always present. With loopback device, you can test network applications even without having a “real” connectivity.
  • enp0s31f6 (often also eth*) is a wired ethernet.
  • wlp58s0 is a wireless adapter.
  • vboxnet0 is a virtual network card used by VirtualBox when you create a virtual subnet for your virtual machines (you will probably not have this one there).

The state of the interface (up and running or not) is at the same line as the adapter name.

The link/ denotes the MAC address of the adapter. Lines with inet specify the IP address assigned to this interface, including the network. In this example, lo has 127.0.0.1/8 (obviously), enp0s31f6 is without an address (state DOWN) and wlp58s0 has address 192.168.0.105/24 (i.e., 192.168.0.105 with netmask 255.255.255.0).

Your addresses will be slightly different, but typically you will see also a private address (behind a NAT), as you are probably connecting through a router to your ISP.

Basic networking utilities

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

ping (a.k.a. are you there?)

The ping command is the basic tool to determine whether a machine with a given IP address is up (and responding to a network traffic).

The usage is extremely simple: you tell it the DNS name (or IP address) of the machine you wish to connect to and it starts sending packets. Typically, the session looks like this:

ping d3s.mff.cuni.cz
PING d3s.mff.cuni.cz (195.113.20.60) 56(84) bytes of data.
64 bytes from d3s.mff.cuni.cz (195.113.20.60): icmp_seq=1 ttl=50 time=16.8 ms
64 bytes from d3s.mff.cuni.cz (195.113.20.60): icmp_seq=2 ttl=50 time=14.9 ms
64 bytes from d3s.mff.cuni.cz (195.113.20.60): icmp_seq=3 ttl=50 time=15.0 ms
64 bytes from d3s.mff.cuni.cz (195.113.20.60): icmp_seq=4 ttl=50 time=36.1 ms
64 bytes from d3s.mff.cuni.cz (195.113.20.60): icmp_seq=5 ttl=50 time=14.3 ms
64 bytes from d3s.mff.cuni.cz (195.113.20.60): icmp_seq=6 ttl=50 time=15.0 ms
^C
--- d3s.mff.cuni.cz ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5271ms
rtt min/avg/max/mdev = 14.328/18.688/36.068/7.809 ms

By default, ping will send the ICMP packet forever, you can terminate it with Ctrl-C.

If the machine is not reachable (that might mean a problem anywhere on the route or on the destination machine itself), you will get behavior like in the following examples.

ping: connect: Network is unreachable
PING 195.113.20.60 (195.113.20.60) 56(84) bytes of data.
From 192.168.88.1 icmp_seq=1 Destination Net Prohibited
From 192.168.88.1 icmp_seq=2 Destination Net Prohibited
From 192.168.88.1 icmp_seq=3 Destination Net Prohibited
From 192.168.88.1 icmp_seq=4 Destination Net Prohibited
^C
--- 195.113.20.60 ping statistics ---
5 packets transmitted, 0 received, +4 errors, 100% packet loss, time 4042ms
pipe 3

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.

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.

Going further: using tmux for better SSH experience

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

Graded tasks (deadline: Apr 10)

Remote file ~/LAB07 (25 points)

Create a normal file LAB07 in your home directory on linux.ms.mff.cuni.cz. Make your UKČO (the number from your ISIC) its only content.

Do not create this file in GitLab, we will check it on the linux.ms.mff.cuni.cz only.

Upload our key (25 points)

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

Do not create this file in GitLab, we will check it on the linux.ms.mff.cuni.cz only.

07/key.pub (25 points)

Store your public key into this file.

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

07/file.txt (25 points)

Run the command nswi177-lab07 on the linux.ms.mff.cuni.cz machine.

Paste its output into this file.

Learning outcomes

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/device agnostic manner)

  • explain principles of asymmetric cryptography

  • explain how asymmetric cryptography can be used to authenticate a user

  • explain benefits of using Git over SSH (instead of HTTPS)

  • explain what are basic access rights in Unix and what rwx mean for plain files and directories

  • explain sticky bit

  • explain difference in ownership of a file (script) and a running program

  • explain as a high-level overview what POSIX ACLs are (optional)

Practical skills

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

  • use SSH to login to a remote machine

  • execute commands on a remote machine

  • use uname and hostname commands

  • configure SSH shortcuts (optional)

  • use SCP to copy files to and from a remote machine

  • setup password-less authentication on a remote Linux machine

  • setup public key authentication in GitLab

  • use Git over SSH

  • view and change unix permissions

  • use ip to query current network configuration (state)

  • use ping and traceroute utilities

  • use tmux (optional)

  • use rsync (optional)