Ubuntu Tips

Multipass

This is Canonical free software that lets you spin up a cluster of VMs on your laptop: Multipass

By defult, it creates an ubuntu user with root privileges, provided you sudo first.

In Powershell, one does something like this to create a shell to VM ccl-vm-1, which logs you into the VM as user ubuntu:

(base) PS C:\Users\aleja> multipass shell ccl-vm-1
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-99-generic x86_64)

* Documentation:  https://help.ubuntu.com
* Management:     https://landscape.canonical.com
* Support:        https://ubuntu.com/advantage

System information as of Thu May 14 13:46:02 PDT 2020

System load:  0.0               Processes:           91
Usage of /:   24.4% of 4.67GB   Users logged in:     0
Memory usage: 68%               IP address for eth0: 192.168.184.87
Swap usage:   0%

* Ubuntu 20.04 LTS is out, raising the bar on performance, security,
and optimisation for Intel, AMD, Nvidia, ARM64 and Z15 as well as
AWS, Azure and Google Cloud.

    https://ubuntu.com/blog/ubuntu-20-04-lts-arrives


12 packages can be updated.
0 updates are security updates.


Last login: Thu May 14 12:41:09 2020 from 192.168.184.81
ubuntu@ccl-vm-1:~$

Set up an Ubuntu server

This link is informative: Initial Server Setup

Multipass makes some of it unnecessary, but is useful to read it through.

Users and passwords

By default, there is a privileged ubuntu user created when multipass creates a VM.

All users are in the file /etc/passwd. The last property (after the last :) is the shell into which that user logs in, which for most is the /user/sbin/nologin that always refuses a login - that is, these are system users that run some processes created by the system, but which should never be able to login.

The second field (usually an x) denotes whether a password exists for that user - if there is an x, then there is a password.

ubuntu@ccl-vm-1:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
alex:x:1001:1001:Alejandro Hernandez,Bulin,+1 (650) 391 4947,Not disclosed,Refuses to say:/home/alex:/bin/bash
ubuntu@ccl-vm-1:~$

Passwords are in /etc/shadow, that requires privileged access. The second field is encryption values for the password in multiple schemes. The other fields are informative times around password expiration lifecycle:

ubuntu@ccl-vm-1:~$ sudo cat /etc/shadow
root:*:18388:0:99999:7:::
daemon:*:18388:0:99999:7:::
bin:*:18388:0:99999:7:::
sys:*:18388:0:99999:7:::
sync:*:18388:0:99999:7:::
games:*:18388:0:99999:7:::
man:*:18388:0:99999:7:::
lp:*:18388:0:99999:7:::
mail:*:18388:0:99999:7:::
news:*:18388:0:99999:7:::
uucp:*:18388:0:99999:7:::
proxy:*:18388:0:99999:7:::
www-data:*:18388:0:99999:7:::
backup:*:18388:0:99999:7:::
list:*:18388:0:99999:7:::
irc:*:18388:0:99999:7:::
gnats:*:18388:0:99999:7:::
nobody:*:18388:0:99999:7:::
systemd-network:*:18388:0:99999:7:::
systemd-resolve:*:18388:0:99999:7:::
syslog:*:18388:0:99999:7:::
messagebus:*:18388:0:99999:7:::
_apt:*:18388:0:99999:7:::
lxd:*:18388:0:99999:7:::
uuidd:*:18388:0:99999:7:::
dnsmasq:*:18388:0:99999:7:::
landscape:*:18388:0:99999:7:::
sshd:*:18388:0:99999:7:::
pollinate:*:18388:0:99999:7:::
ubuntu:!:18396:0:99999:7:::
alex:$6$OkJPdDCr$oVPLDMWa69IjSRt/lQWKXBZrnu9dSYd5RHQaxgruOnX4R7SmbDgaHh0S3ouENpiJuW26gYCDWCSeptaKQgFY10:18396:0:99999:7:::

To add a user:

ubuntu@ccl-vm-1:~$ sudo adduser alex
Adding user `alex' ...
Adding new group `alex' (1001) ...
Adding new user `alex' (1001) with group `alex' ...
Creating home directory `/home/alex' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for alex
Enter the new value, or press ENTER for the default
        Full Name []: Alejandro Hernandez
        Room Number []: Bulin
        Work Phone []: +1 (650) 391 4947
        Home Phone []: Not disclosed
        Other []: Refuses to say
Is the information correct? [Y/n] Y
ubuntu@ccl-vm-1:~$

If we want new user to have privileges, then do:

ubuntu@ccl-vm-1:~$ sudo adduser alex admin
Adding user `alex' to group `admin' ...
Adding user alex to group admin
Done.
ubuntu@ccl-vm-1:~$ sudo adduser alex sudo
Adding user `alex' to group `sudo' ...
Adding user alex to group sudo
Done.
ubuntu@ccl-vm-1:~$

To see a user:

To see the credentials of the new user (second field is the encripted password)

ubuntu@ccl-vm-1:~$ sudo cat /etc/shadow | grep alex
alex:$6$OkJPdDCr$oVPLDMWa69IjSRt/lQWKXBZrnu9dSYd5RHQaxgruOnX4R7SmbDgaHh0S3ouENpiJuW26gYCDWCSeptaKQgFY10:18396:0:99999:7:::
ubuntu@ccl-vm-1:~$

To see what groups it belongs to:

ubuntu@ccl-vm-1:~$ id alex
uid=1001(alex) gid=1001(alex) groups=1001(alex),27(sudo),113(admin)
ubuntu@ccl-vm-1:~$

To see contact information:

ubuntu@ccl-vm-1:~$ finger alex
Login: alex                             Name: Alejandro Hernandez
Directory: /home/alex                   Shell: /bin/bash
Office: Bulin, +1 (650) 391 4947        Home Phone: Not disclosed
Never logged in.
No mail.
No Plan.
ubuntu@ccl-vm-1:~$

Allowing SSH connections

These tips were inspired by SSH setup

Scenario

This example is for the following scenario:

  • We have previously created VM CCL-VM-1 with user alex

  • We want to enable clients to SSH into alex@ccl-vm-1.

  • The server VM was previously created with multipass, so password-based SSH is already disabled.

  • The client will be laptop CC-Labs-2.

  • Keep this in mind in the bash snippets below to know whether its the server (ccl-vm-1) or the client (CC-Labs-2).

We will need the server’s IP address, which is 192.168.184.87:

ubuntu@ccl-vm-1:~$ ifconfig | grep broadcast
        inet 192.168.184.87  netmask 255.255.255.240  broadcast 192.168.184.95
ubuntu@ccl-vm-1:~$

We start by noting that the server will disallow password-based SSH connections because of of the setting PasswordAuthentication no in /etc/ssh/sshd_config (this is system-wide, for all users):

ubuntu@ccl-vm-1:~$ cat /etc/ssh/sshd_config | grep Password
PasswordAuthentication no
#PermitEmptyPasswords no
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication, then enable this but set PasswordAuthentication
ubuntu@ccl-vm-1:~$

For that reason, if a client tries to SSH, it will not be prompted for a password, and if the client’s SSH public key has not been configured in the server, then the server will not recognize the client and refuse the connection:

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ ssh alex@192.168.184.87
alex@192.168.184.87: Permission denied (publickey).
(base)
aleja@CC-Labs-2 MINGW64 ~/Documents/Code

Generate private/public keys

So we need to configure key-based SSH connectivity. That starts with creating a pair of private/public keys on the client (a passphrase is recommended):

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/aleja/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/aleja/.ssh/id_rsa.
Your public key has been saved in /c/Users/aleja/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:m8qi4wVPkHsF8m4a68nhgYa1g7kzt8Rp8eOwL/AxsRc aleja@CC-Labs-2
The key's randomart image is:
+---[RSA 2048]----+
|  . .            |
|   + .           |
|  o . .          |
|  .+E.           |
|  *o=.  S        |
|o*+#.    o       |
|=+&+=   o        |
|+B=X.o .         |
|.=X*o.o          |
+----[SHA256]-----+
(base)
aleja@CC-Labs-2 MINGW64 ~/Documents/Code

This keys are created in the ~/.ssh folder, in files id_rsa (private key) and id_rsa.pub (public key). There might be a pre-existing file known_hosts with other types of keys (keys that tells the client which servers it trusts - usually this is from prior SSH connections to other servers).

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ ls -l ~/.ssh/
total 6
-rw-r--r-- 1 aleja 197609 1876 May 14 15:23 id_rsa
-rw-r--r-- 1 aleja 197609  397 May 14 15:23 id_rsa.pub
-rw-r--r-- 1 aleja 197609  176 May 14 14:28 known_hosts
(base)
aleja@CC-Labs-2 MINGW64 ~/Documents/Code

Configure server with client’s public key

Now the client must provide its public key to the server, so that the server can later establish that SSH connection attempts are indeed coming from this client. This is done for the server user that the client would be connecting into.

Because the server does not accept password-based connections (setting PasswordAuthentication no above), we can’t use utilities like ssh-copy-id. So we will have to copy-and-paste the public key from client to server.

Start by displaying the client’s public key, and copying it:

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFZFrXpnh8bvhQAA4D69ie8PJYLadv2E0ZqTNGUXf9RCV5rbbo+gRn5Qbvu3ktVFiimeSNo+HEUqabR/dtRkP7nNaY7hlkrFTPMmVuysDHrNqRsR8zwnTQbd/3otTmBekX5QdSCZx0GjEOl33uQ81XK0Q71xkPCUNxlYMLQYH5xJqUj5qGnWi1Fp33EnkbFzd3O5DRBWe08Ij59OpKKi16SnBF/TRVqtWzh1jGQSl90PwggukGhpBDGWiI/FGmUD0NDZgaRe2A+HUzlGIJMwlL14+QORbkA64s7DvUUubdXcK5lJewJWkZqnmoo+idlr6o+uDNSQWWorpo05taQGQv aleja@CC-Labs-2
(base)
aleja@CC-Labs-2 MINGW64 ~/Documents/Code

Now go to a shell on the server, and switch to the user into whom the SSH connection will come in, since it’s that user’s SSH settings that we will update, and create a .ssh folder in that user’s home directory:

ubuntu@ccl-vm-1:~$ su alex
Password:
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
alex@ccl-vm-1:/home/ubuntu$ cd ~/
alex@ccl-vm-1:~$ mkdir ~/.ssh

Now append the client’s public key to the server’s file of public keys for that server user:

alex@ccl-vm-1:~$ echo <client's public key> >> ~/.ssh/authorized_keys

where <client's public key> is the copied key on the clipboard:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFZFrXpnh8bvhQAA4D69ie8PJYLadv2E0ZqTNGUXf9RCV5rbbo+gRn5Qbvu3ktVFiimeSNo+HEUqabR/dtRkP7nNaY7hlkrFTPMmVuysDHrNqRsR8zwnTQbd/3otTmBekX5QdSCZx0GjEOl33uQ81XK0Q71xkPCUNxlYMLQYH5xJqUj5qGnWi1Fp33EnkbFzd3O5DRBWe08Ij59OpKKi16SnBF/TRVqtWzh1jGQSl90PwggukGhpBDGWiI/FGmUD0NDZgaRe2A+HUzlGIJMwlL14+QORbkA64s7DvUUubdXcK5lJewJWkZqnmoo+idlr6o+uDNSQWWorpo05taQGQv aleja@CC-Labs-2

Then we can see that the key was saved as intended:

alex@ccl-vm-1:~$ cat ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFZFrXpnh8bvhQAA4D69ie8PJYLadv2E0ZqTNGUXf9RCV5rbbo+gRn5Qbvu3ktVFiimeSNo+HEUqabR/dtRkP7nNaY7hlkrFTPMmVuysDHrNqRsR8zwnTQbd/3otTmBekX5QdSCZx0GjEOl33uQ81XK0Q71xkPCUNxlYMLQYH5xJqUj5qGnWi1Fp33EnkbFzd3O5DRBWe08Ij59OpKKi16SnBF/TRVqtWzh1jGQSl90PwggukGhpBDGWiI/FGmUD0NDZgaRe2A+HUzlGIJMwlL14+QORbkA64s7DvUUubdXcK5lJewJWkZqnmoo+idlr6o+uDNSQWWorpo05taQGQv aleja@CC-Labs-2
alex@ccl-vm-1:~$

Establish SSH connection

Now we can go back to the client and attempt again to establish an SSH connection. This time it will work because we have a proper SSH key configuration (notice that the passphrase will be required). But before we do so, observe that server user alex is not connected via SSH (yet):

alex@ccl-vm-1:~$ ps -aux | grep ssh
root       939  0.0  0.6  72300  6192 ?        Ss   07:03   0:00 /usr/sbin/sshd -D
root     14568  0.0  0.7 107984  7184 ?        Ss   13:46   0:00 sshd: ubuntu [priv]
ubuntu   14668  0.0  0.3 107984  3508 ?        S    13:46   0:00 sshd: ubuntu@pts/0
alex     15174  0.0  0.1  14856  1004 pts/0    S+   16:08   0:00 grep --color=auto ssh
alex@ccl-vm-1:~$

The only SSH connections are for the ubuntu user - that’s because this VM is created by multipass and these screenshots are taken with a multipass shell ccl-vm-1 command, which establishes an SSH connection with user ubuntu. But the SSH configuration we are doing in this example, for alex, is not yet manifesting as a connection, as expected - since we didn’t yet connect.

Now we connect (notice we are prompted for the passphrase we created earlier):

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ ssh alex@192.168.184.87
Enter passphrase for key '/c/Users/aleja/.ssh/id_rsa':
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-99-generic x86_64)

* Documentation:  https://help.ubuntu.com
* Management:     https://landscape.canonical.com
* Support:        https://ubuntu.com/advantage

System information as of Thu May 14 16:01:54 PDT 2020

System load:  0.0               Processes:           99
Usage of /:   24.5% of 4.67GB   Users logged in:     1
Memory usage: 67%               IP address for eth0: 192.168.184.87
Swap usage:   0%

* Ubuntu 20.04 LTS is out, raising the bar on performance, security,
and optimisation for Intel, AMD, Nvidia, ARM64 and Z15 as well as
AWS, Azure and Google Cloud.

    https://ubuntu.com/blog/ubuntu-20-04-lts-arrives


12 packages can be updated.
0 updates are security updates.



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

alex@ccl-vm-1:~$

As further proof that the CC-Labs-2 client is connected to the ccl-vm-1 server, notice that this time the server will show some SSH processes for user alex (whereas before we didn’t):

alex@ccl-vm-1:~$ ps -aux | grep ssh
root       939  0.0  0.6  72300  6192 ?        Ss   07:03   0:00 /usr/sbin/sshd -D
root     14568  0.0  0.7 107984  7184 ?        Ss   13:46   0:00 sshd: ubuntu [priv]
ubuntu   14668  0.0  0.3 107984  3508 ?        S    13:46   0:00 sshd: ubuntu@pts/0
root     15041  0.0  0.7 107984  7244 ?        Ss   16:01   0:00 sshd: alex [priv]
alex     15145  0.0  0.3 107984  3392 ?        S    16:01   0:00 sshd: alex@pts/1
alex     15169  0.0  0.1  14856  1060 pts/0    S+   16:07   0:00 grep --color=auto ssh

Simple Firewall with ufw

This is inspired by Section 4 of server setup tutorial

I saw that by default ufw is disabled for VMs created with multipass:

alex@ccl-vm-1:~$ sudo ufw status
Status: inactive

We see that ufw knows about OpenSSH as an app that has registered a profile through the ufw firewall:

alex@ccl-vm-1:~$ sudo ufw app list
Available applications:
OpenSSH
alex@ccl-vm-1:~$ sudo ufw app info OpenSSH
Profile: OpenSSH
Title: Secure shell server, an rshd replacement
Description: OpenSSH is a free implementation of the Secure Shell protocol.

Port:
22/tcp

We enable the firewall and look at its status:

alex@ccl-vm-1:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
alex@ccl-vm-1:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    DENY        Anywhere
OpenSSH (v6)               DENY        Anywhere (v6)

Now the server is refusing SSH connections (and presumably, any kind of connection via other apps, since they don’t even have a profile with udf).

So if we tried to SSH, the same connection we tried before will fail (next snippet is from the client, not server:

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ ssh alex@192.168.184.87
ssh: connect to host 192.168.184.87 port 22: Connection timed out

So we need to allow SSH as an application allowed to connect:

alex@ccl-vm-1:~$ sudo ufw allow OpenSSH
Rule updated
Rule updated (v6)
alex@ccl-vm-1:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Now if we go to the client, we will be able to connect:

aleja@CC-Labs-2 MINGW64 ~/Documents/Code
$ ssh alex@192.168.184.87
Enter passphrase for key '/c/Users/aleja/.ssh/id_rsa':
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-99-generic x86_64)

* Documentation:  https://help.ubuntu.com
* Management:     https://landscape.canonical.com
* Support:        https://ubuntu.com/advantage

System information as of Thu May 14 16:47:45 PDT 2020

System load:  0.03              Processes:           98
Usage of /:   24.5% of 4.67GB   Users logged in:     1
Memory usage: 67%               IP address for eth0: 192.168.184.87
Swap usage:   0%

* Ubuntu 20.04 LTS is out, raising the bar on performance, security,
and optimisation for Intel, AMD, Nvidia, ARM64 and Z15 as well as
AWS, Azure and Google Cloud.

    https://ubuntu.com/blog/ubuntu-20-04-lts-arrives


12 packages can be updated.
0 updates are security updates.


Last login: Thu May 14 16:01:55 2020 from 192.168.184.81
alex@ccl-vm-1:~$