2022-01-16 / Bartłomiej Kurek
Server setup: #2 - post-install steps

In this article we're going through the basic post-install steps in Debian 11.

Series link

Secure transport (apt)

apt (the high-level interface for the debian pkg manager dpkg) uses apt-secure to verify package signatures.
By default debian configures package repositores as available over http. However, we may change it to https.

# Use https when downloading packages
sed -i 's/http:/https:/g' /etc/apt/sources.list

Check:

# grep -v '^$' /etc/apt/sources.list | grep -v '^#'
deb https://deb.debian.org/debian/ bullseye main
deb-src https://deb.debian.org/debian/ bullseye main
deb https://security.debian.org/debian-security bullseye-security main
deb-src https://security.debian.org/debian-security bullseye-security main
deb https://deb.debian.org/debian/ bullseye-updates main
deb-src https://deb.debian.org/debian/ bullseye-updates main

For faster downloads you may also use the mirrors close to your location. This can be done using netselect-apt. I'm leaving "debian.org" as package repository source.

This is a good moment to update package lists and upgrade:

# apt update -y
# apt upgrade -y

NTP (time protocol)

If you want to synchronize system time with time servers - install ntp and configure it. This will install ntp and the service:

# apt install ntp

Once installed, you may check the list of ntp servers using ntpq -p:

> ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 0.debian.pool.n .POOL.          16 p    -   64    0    0.000   +0.000   0.000
 1.debian.pool.n .POOL.          16 p    -   64    0    0.000   +0.000   0.000
 2.debian.pool.n .POOL.          16 p    -   64    0    0.000   +0.000   0.000
 3.debian.pool.n .POOL.          16 p    -   64    0    0.000   +0.000   0.000
+xxx.xxx.xx      194.xxx.xxx.xxx  2 u   26   64    3    7.920   +6.913   6.944
-xxxxx.xxx       216.xxx.xxx.xxx  3 u   24   64    3   22.367   +7.163   8.241
[...]

If you want to use a fixed set of ntp servers, adapt /etc/ntp.conf:

# You do need to talk to an NTP server or two (or three).
#server ntp.your-provider.example

Network interfaces

The "modern Linux" uses "predictable interface names". I am unable to predict your interface name. If it's ethernet it's probably named ens3 or enp0s3. I am used to the old-school "eth0", so on my systems I reconfigure GRUB so that the main ethernet interface is always named eth0.

Main interface (eth0)

This requires a small change in /etc/default/grub file, updating /etc/network/interfaces, updating grub and rebooting.
Warning: if you're doing this and you are using DHCP, be sure to write down the mac-address of the current interface (just in case).

In /etc/default/grub add net.ifnames=0. In the default install you may achieve it using sed.

sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="net.ifnames=0"/' /etc/default/grub

/etc/network/interfaces:

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp

If you need to set the mac-address, add: hwaddress xx:xx:xx:xx:xx:xx below the last line.

Nodes' interfaces

At this point we can also configure the interfaces for the nodes. We will need "bridge-utils" for this to work. If you like old-school tools (e.g. ifconfig, route, netstat) - you can install 'net-tools' as well.

# apt install bridge-utils net-tools

/etc/network/interfaces.d/inet-bridge:

allow-hotplug eth0.1
iface eth0.1 inet static
    address 192.168.1.1/24
    gateway 192.168.0.1

allow-hotplug eth0.2
iface eth0.2 inet static
    address 192.168.2.1/24
    gateway 192.168.0.1

allow-hotplug eth0.3
iface eth0.3 inet static
    address 192.168.3.1/24
    gateway 192.168.0.1

auto br0
iface br0 inet static
     address 192.168.0.1/24
     bridge_ports eth0.1 eth0.2 eth0.3

Once the interface configuration is in place, update the grub bootloader and reboot.
Warning: make sure you'll have access to the console in case the network doesn't come up (KVM console/direct access).

# update-grub
# reboot

When the system restarts, the interface list should look similar to this:

root@server:~# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:18:33:0b brd ff:ff:ff:ff:ff:ff
    altname enp0s3
11: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 1e:13:68:e5:3d:1e brd ff:ff:ff:ff:ff:ff
12: eth0.1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:18:33:0b brd ff:ff:ff:ff:ff:ff
13: eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:18:33:0b brd ff:ff:ff:ff:ff:ff
14: eth0.3@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 08:00:27:18:33:0b brd ff:ff:ff:ff:ff:ff

Old-school ifconfig:

root@server:~# ifconfig 
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.1  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::1c13:68ff:fee5:3d1e  prefixlen 64  scopeid 0x20<link>
        ether 1e:13:68:e5:3d:1e  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15  bytes 1226 (1.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.219  netmask 255.255.0.0  broadcast 10.0.255.255
        ether 08:00:27:18:33:0b  txqueuelen 1000  (Ethernet)
        RX packets 99040  bytes 28388359 (27.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 59568  bytes 9001735 (8.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0.1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.1  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 08:00:27:18:33:0b  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15  bytes 1226 (1.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0.2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.1  netmask 255.255.255.0  broadcast 192.168.2.255
        ether 08:00:27:18:33:0b  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15  bytes 1226 (1.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0.3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.3.1  netmask 255.255.255.0  broadcast 192.168.3.255
        ether 08:00:27:18:33:0b  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15  bytes 1226 (1.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 302  bytes 69900 (68.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 302  bytes 69900 (68.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

I'm doing this on a vm which has address 10.0.0.219, as you can see.

SSH access

Install ssh server. I'm going to create a devops user which I will use to log in to the server. This user will be able to sudo su - to root, and afterwards I will continue using root account directly.

Warning: consider the username. The bots are using dictionary attacks, so all the usual names (like: devops, test, admin, jira, docker, deploy, ...) are not the best choices. devops is used here only for demonstration purposes.

Install

# apt install -y openssh-server sudo

This has installed and started the ssh service, but we can do it explicitely, too:

# systemctl enable ssh
# /etc/init.d/ssh restart

Create a regular user

Create a user and set a non trivial password. For SSH we will use key-based authentication exclusively, but nevertheless - use a non-trivial password. (One way to generate it is by using uuidgen command from uuid-runtime package).

# useradd --shell /bin/bash --create-home devops -G sudo
# passwd devops

Configure ssh client on your machine

You'll need to generate a key for ssh.

your-machine$ ssh-keygen -t ed25519

Once done, copy the public key to the server.

your-machine$ ssh-copy-id -i ~/.ssh/id_ed25519 devops@server

If you've named the key differently, you may configure the client with a file (man ssh_config). The configuration looks more-or-less like this:

~/.ssh/config:

Host server
    User devops
    Port 22
    IdentityFile ~/.ssh/devops@server

The config is case-insensitive (but the paths are case-sensitive!).
You should now be able to log into the server. Example (I'm using a key named "devops@server"):

your-machine$ ssh devops@server -i ~/.ssh/devops@server
Linux server 5.10.0-10-amd64 #1 SMP Debian 5.10.84-1 (2021-12-08) x86_64
[...]
devops@server:~$ 
devops@server:~$ sudo su -
[sudo] password for devops: 
root@server:~# 

Secure SSH access

Once you are able to log into the server as a regular user using a key - it's best to adapt the sshd configuration. I usually set:

PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
AllowUsers devops

It's also a good idea to change the default port (if you're not inconvenienced by using a non-default one).

Restart/reload ssh server:

# /etc/init.d/ssh restart

Next: firewall preparation