Skip to Content

Minimal Debian

Posted on

Debian Dog In Harmony

Debian 10 aka “Buster” is the latest stable release of the popular Linux operating system. I use Debian’s network installer image to create a console-only base configuration that can be customized for various tasks and alternate desktops.

Let’s go!

Debian GNU/Linux is an operating system created by volunteers of one of the largest and longest-running free software projects in the world. There are 3 release branches: stable (code-named “buster”), testing (bullseye), and unstable (sid).

Below is a visual walk-through of a sample workstation setup that makes use of the entire disk divided into two partitions: a small boot partition, and the remaining storage is dedicated to an encrypted partition used by the Logical Volume Manager (LVM) to create virtual partitions (Logical Volumes) for separate root and home. 1

Installing LVM on top of the encrypted partition allows:

  • creation of multiple LVs protected by a single passphrase entered at boot time
  • dynamic resizing of filesystems
  • snapshots of filesystems that can be used as backups or to restore a previous state

0. Prepare install media

Download and verify the (unofficial with non-free firmware included) 64-bit (or 32-bit for machines 10+ years old) firmware-10.0.0-amd64-netinst.iso

$ wget -c https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/current/amd64/iso-cd/firmware-10.0.0-amd64-netinst.iso
$ wget https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/current/amd64/iso-cd/SHA256SUMS
$ sha256sum -c SHA256SUMS
firmware-10.0.0-amd64-netinst.iso: OK
[...]

Write the installer to an unmounted USB storage device using dd as root. BE VERY CAREFUL TO NOTE THE PROPER DEVICE. ALL DATA ON THE DEVICE WILL BE OVERWRITTEN.

Example: On a Linux system, if a USB stick appears as sde1, then write the installer to sde (no partition number) using …

$ sudo dd bs=4M if=path/to/firmware-10.0.0-amd64-netinst.iso of=/dev/sde status=progress oflag=sync

1. Launch

Install

Select language

Select location

Configure keyboard

Detecting link

DHCP

Hostname

Domain

Root password

Verify password

Full name

Username

User password

Verify password

Select time zone

2. Partitions

Sample layout:

  • sda1 is a 512MB boot partition
  • sda2 uses remaining storage as a LUKS encrypted partition
  • LVM installed on encrypted partition

Partitioning method

Partition disks

Partition table

Free space

New partition

Partition size

Primary partition

Beginning

Modify the default mount options …

Mount point: /boot
Bootable flag: on

Mount point

Boot

Bootable flag

Done

Assign the remaining storage to the encrypted partition …

Free space

New partition

Partition size

Primary partition

Modify default mount options …

Use as: physical volume for encryption
Erase data: no

If the hard disk has not been securely wiped prior to installing Debian you may want to configure Erase data: yes. Note, however, depending on the size of the disk this operation can last several hours.

Use as

Physical volume for encryption

Erase data

Done

Configure encrypted volumes

Write changes

Create encrypted

Devices to encrypt

Finish

Passphrase

Verify passphrase

Select encrypted volume and modify default mount options …

Use as: physical volume for LVM

Select

Use as

Physical volume for LVM

Done

Create a LVM volume group (vg) with two logical volumes:

  • an LV labelled root (24G)
  • an LV labelled home (remaining space)

Configure LVM

Write changes

Create volume group

Vg name

Device for vg

Create lv

Vg

Lv root

Lv root size

Create lv

Vg

Lv home

Lv home size

Finish lvm

Select LV root and modify default mount options …

Use as: Ext4
Mount point: /

Select lv root

Use as

Ext4

Mount point

Root

Done

Select LV home and modify default mount options … 2

Use as: Ext4
Mount point: /home
Reserved blocks: 1%

Select lv home

Use as

Ext4

Mount point

Home

Reserved blocks

Percent

Done

Write changes to disk …

Finish partitioning

Partition tool warns that no swap partition has been created. Choose No to returning to the partition menu (a later step will create a swapfile) …

No swap alert

Write changes

Installing

3. Install packages and finish up

Scan - alpha5

Archive mirror

Use the Debian global mirrors service deb.debian.org

Mirror hostname

Proxy

Retrieving files

Restart services

Package survey

Select only [*] standard system utilities and leave the remaining tasks 3 unmarked …

Software selection

Packages are downloaded and the installer makes its finishing touches …

Install GRUB to MBR

GRUB device

Finish

4. First boot

GRUB menu

User is prompted for the passphrase to unlock the encrypted partition …

Unlock passphrase

Login

Login and welcome to Buster! 🐧

Run timedatectl to confirm system date+time is properly configured …

$ timedatectl

5. Network

Check which network interfaces are detected and settings …

$ ip link

Wired interfaces are usually auto-configured by default and assigned an IP address courtesy of DHCP.

To assign a static address, deactivate the wired interface and create a new entry in /etc/network/interfaces. 4 Sample entry for enp3s0

# The primary network interface
auto enp3s0
iface enp3s0 inet static
address 192.168.1.88
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 8.8.8.8 8.8.4.4

Bring up|down interface with if{up,down} enp3s0.

Create a temporary wireless interface connection to WPA2 encrypted access points manually using wpa_supplicant + wpa_passphrase + dhclinet. Sample setup of wlp1s0 (as root) …

# ip link set wlp1s0 up             ## bring up interface
# iw dev wlp1s0 link                ## get link status
# iw dev wlp1s0 scan | grep SSID    ## scan for access points
# wpa_supplicant -i wlp1s0 -c<(wpa_passphrase "MY_SSID" "MY_PASSPHRASE")   ## connect to WPA/WPA2 ... add '-B' to background process
# dhclient wlp1s0                   ## obtain IP address

More permanent configurations may be set in interfaces. Sample setup 5 with a static IP address …

iface wlp1s0 inet static
address 192.168.1.77
netmask 255.255.255.0
gateway 192.168.1.1                                                              
wpa-ssid MY_SSID
wpa-psk MY_PASSPHRASE
dns-nameservers 8.8.8.8 8.8.4.4                                                  

Alternative setup using DHCP …

iface wlp1s0 inet dhcp
wpa-ssid MY_SSID
wpa-psk MY_PASSPHRASE                                       
dns-nameservers 8.8.8.8 8.8.4.4

Once a link is established install an (optional) network manager utility. Packages network-manager and network-manager-gnome provide the console nmcli and graphical nm-applet clients respectively . Comment out (deactivate) any entries in interfaces that will be managed by network-manager.

6. Upgrade

Install any upgrades …

# apt update && apt full-upgrade

7. Keyboard

If you desire a different default language/keymap, either manually edit /etc/default/keyboard or run …

# dpkg-reconfigure keyboard-configuration

See also: I use the colemak keyboard layout.

8. Console fonts

Find available fonts in /usr/share/consolefonts. Set and display a font (example: Lat15-Terminus20x10) for the current session …

# setfont Lat15-Terminus20x10
# showconsolefont

Make the selection persistent by manually editing /etc/default/console-setup or run …

# dpkg-reconfigure console-setup

9. Sudo

Install sudo to temporarily provide your non-root user (example: foo) account with root privileges …

# apt install sudo && adduser foo sudo

To allow foo to suspend, shutdown or reboot the system without being prompted for a password, first create the file /etc/sudoers.d/00-alias containing …

User_Alias ADMIN = foo
Cmnd_Alias SYS_CMDS = /usr/bin/systemctl poweroff, /usr/bin/systemctl reboot, /usr/bin/systemctl suspend

… and then create the file /etc/sudoers.d/01-nopasswd containing the NOPASSWD option …

# allow specified users to execute these commands without password
ADMIN ALL=(ALL) NOPASSWD: SYS_CMDS

I add aliases for the commands in my ~/.bashrc to auto-include sudo

alias bye='sudo /usr/bin/systemctl poweroff'
alias reboot='sudo /usr/bin/systemctl reboot'
alias zzz='sudo /usr/bin/systemctl suspend'

10. Sysctl

If a non-root user runs dmesg to read the contents of the kernel message buffer they will see …

dmesg: read kernel buffer failed: Operation not permitted

Turns out it is a security feature not a bug!

To allow users to read the kernel log without being prompted for a password, modify /etc/sysctl.conf by adding …

kernel.dmesg_restrict = 0

… and reload the configuration …

$ sudo sysctl -p

11. Main, non-free, contrib, and backports

Debian uses three archives to distinguish between software packages based on their licenses. Main is enabled by default and includes everything that satisfies the conditions of the Debian Free Software Guidelines. Non-free contains packages that do not meet all the conditions of the DFSG but can be freely distributed, and contrib packages are open-source themselves but rely on software in non-free to work.

Backports contains packages drawn from the testing (and sometimes unstable) archive and modified to work in the current stable release. All backports are disabled by default (to prevent unintended system upgrades) and are installed on a per PACKAGE basis by running …

# apt -t buster-backports install PACKAGE

Modify /etc/apt/sources.list to add contrib, non-free, and backports

# Base repository
deb http://deb.debian.org/debian/ buster main contrib non-free
deb-src http://deb.debian.org/debian/ buster main contrib non-free

# Security updates
deb http://security.debian.org/debian-security buster/updates main contrib non-free
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free

# Stable updates
deb http://deb.debian.org/debian buster-updates main contrib non-free
deb-src http://deb.debian.org/debian buster-updates main contrib non-free

# Stable backports
deb http://deb.debian.org/debian buster-backports main contrib non-free
deb-src http://deb.debian.org/debian buster-backports main contrib non-free

Any time sources.list is modified its necessary to update the package database …

$ sudo apt update

12. Automatic security updates

Fetch and install the latest fixes courtesy of unattended upgrades. Useful feature for a home server (on workstations I manage updates myself).

13. Command not found

Automatically search the official repositories when entering an unrecognized command, courtesy of the command-not-found package …

$ sudo apt install command-not-found apt-file
$ sudo apt-file update && sudo update-command-not-found

Re-login to activate.

14. Swapfile

Create a 2GB file which will be used for swap

$ sudo fallocate -l 2G /swapfile

Only root should be granted read/write access …

$ sudo chmod 600 /swapfile

Create the swap area and activate …

$ sudo mkswap /swapfile
$ sudo swapon /swapfile && free -h

Make the change permanent by adding to /etc/fstab

/swapfile none swap sw 0 0

15. SSD

Periodic TRIM optimizes performance on SSD storage. Enable a weekly task that discards unused blocks on the drive …

$ sudo systemctl enable fstrim.timer

16. mlocate

Setup the locate command and database for finding files …

$ sudo apt install mlocate && sudo /etc/cron.daily/mlocate

17. Dot bashrc

Modify ~/.bashrc and create a colourful custom prompt …

# colour codes
GREEN="\\[\\e[1;32m\\]"
YELLOW="\\[\\e[1;33m\\]"
BLUE="\\[\\e[1;34m\\]"
MAGENTA="\\[\\e[1;35m\\]"
WHITE="\\[\\e[1;37m\\]"
RESET="\\[\\e[0m\\]"

# Set a two-line prompt. If accessing via ssh include 'ssh-session' message.
if [[ -n "$SSH_CLIENT" ]]; then
    ssh_message="-ssh_session"
fi
PS1="${MAGENTA}\\u ${WHITE}at ${GREEN}\\h${YELLOW}${ssh_message} ${WHITE}in ${BLUE}\\w \\n$WHITE\$${RESET} "

Add aliases and functions, enable unlimited history, and more. See also: My own ~/.bashrc

18. GRUB

Add a bit of colour, a bit of sound, and wallpaper to the bootloader. See also: GNU GRUB.

19. Microcode

Intel and AMD processors may periodically need updates to their microcode firmware. Microcode can be updated (and kept in volatile memory) during boot by installing either intel-microcode or amd64-microcode (AMD) …

$ sudo apt install intel-microcode

Sample output from my laptop before reboot …

$ dmesg | grep microcode
[    0.042819] [Firmware Bug]: TSC_DEADLINE disabled due to Errata; please update microcode to version: 0x20 (or later)
[    1.325081] microcode: sig=0x40651, pf=0x40, revision=0x15
[    1.325137] microcode: Microcode Update Driver: v2.2.
$ grep microcode /proc/cpuinfo 
microcode	: 0x15
microcode	: 0x15

… and after reboot …

$ dmesg | grep microcode
[    0.000000] microcode: microcode updated early to revision 0x24, date = 2018-04-02
[    1.329836] microcode: sig=0x40651, pf=0x40, revision=0x24
[    1.329903] microcode: Microcode Update Driver: v2.2.
$ grep microcode /proc/cpuinfo 
microcode	: 0x24
microcode	: 0x24

See also: Microcode

20. Secure access using SSH keys

Create cryptographic keys, install the OpenSSH server, and configure remote access.

21. Where to go next …

… is up to YOU. A home server? A workstation with your own custom desktop?

Happy hacking! 🐧

Notes


  1. Very helpful! LVM post on the Arch Wiki. [return]
  2. Reserved blocks can be used by privileged system processes to write to disk - useful if a full filesystem blocks users from writing - and reduce disk fragmentation. On large non-root partitions extra space can be gained by reducing the default 5% reserve set aside by Debian to 1%. [return]
  3. Task selection menu can be used post-install by running (as root) tasksel. [return]
  4. Problem: setting the network interface to static address can result in /etc/resolv.conf being overwritten every few minutes with an IPv6 address that breaks DNS. The “fix” is to maually set nameserver 8.8.8.8 in resolv.conf and install the resolvconf package. Note that dns-nameservers entries are ignored if resolvconf is not installed. [return]
  5. Multiple wireless static IP address setups can be created with iface wlp1s0_NAME inet static and [de]activated with if{up.down} wlp1s0=wlp1s0_NAME. [return]