Minimal Debian
Debian 10 aka “buster” is the latest stable release of the popular Linux operating system. I use Debian’s (unofficial) network installer image (which includes non-free firmware for pesky wifi cards) to create a minimal, console-only base configuration that can be customized for various tasks and 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 an installation that makes use of the entire disk divided into two partitions: a small boot
partition, with the remaining storage dedicated to a Linux Unified Key Setup (LUKS) encrypted partition used by the Logical Volume Manager (LVM) to create “virtual partitions” (Logical Volumes or LVs) for separate root
and home
.
Installing LVM on top of the encrypted partition allows:
- creation of multiple LVs protected by a single passphrase
- dynamic resizing of LVs as needed
- snapshots of LVs that can be used as backups or to restore a previous state
Sample device (my Thinkpad X230) uses BIOS MBR and boots in legacy boot mode. I don’t have any devices using UEFI; search online about extrapolating from these steps to deal with /boot/efi
.
1. Prepare install media
Download and verify firmware-10.7.0-amd64-netinst.iso
…
$ wget -c https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/current/amd64/iso-cd/firmware-10.7.0-amd64-netinst.iso
$ wget https://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/current/amd64/iso-cd/SHA256SUMS
$ sha256sum -c --ignore-missing SHA256SUMS
firmware-10.7.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.7.0-amd64-netinst.iso of=/dev/sde status=progress oflag=sync
2. Launch
3. Partitions
Select the guided partitioning option to make use of the entire disk configured with LVM on LUKS. I also recommend creating a separate /home
. By default, this creates:
- a small, unencrypted
boot
- remaining storage dedicated to a LUKS-encrypted partition with LVM
- logical volumes created for
root
,swap
, andhome
Settings can be altered (alternate filesystems, mount options, etc) before writing the partition layout to disk. 1 If finer-grained control is desired, select manual partitioning.
4. Install packages and finish up
Use the Debian global mirrors service deb.debian.org …
Select only [*] standard system utilities
and leave the remaining tasks 2 unmarked …
Packages are downloaded and the installer makes its finishing touches …
5. First boot
User is prompted for the passphrase to unlock the encrypted partition …
Login and welcome to Buster!
6. Optional: Full disk encryption (including /boot)
GRUB2 supports booting from an encrypted boot courtesy of its cryptodisk
module. Debian’s installer does not provide the option of creating a bootable system with an encrypted boot
. But it is possible - after installation - to move the contents of unencrypted boot
into root
residing on the LUKS-encrypted device. Read more
7. 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
. 3 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
.
To create a wireless interface connection to WPA2-encrypted access points 4 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
Optional: once a link is established install a 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
.
8. Upgrade
Install any upgrades …
# apt update && apt full-upgrade
9. Keyboard
If you desire a different default language/keymap, either modify /etc/default/keyboard
or run …
# dpkg-reconfigure keyboard-configuration
I use the colemak keyboard layout.
10. Console fonts
Discover available fonts in /usr/share/consolefonts
. Set and display a font (example: Lat15-Terminus20x10
) for the current session …
# setfont Lat15-Terminus20x10
# showconsolefont
To make the selection persistent, either modify /etc/default/console-setup
or run …
# dpkg-reconfigure console-setup
11. 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'
12. 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
13. 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 https://deb.debian.org/debian/ buster main contrib non-free
deb-src https://deb.debian.org/debian/ buster main contrib non-free
# Security updates
deb https://security.debian.org/debian-security buster/updates main contrib non-free
deb-src https://security.debian.org/debian-security buster/updates main contrib non-free
# Stable updates
deb https://deb.debian.org/debian buster-updates main contrib non-free
deb-src https://deb.debian.org/debian buster-updates main contrib non-free
# Stable backports
deb https://deb.debian.org/debian buster-backports main contrib non-free
deb-src https://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
14. Automatic security updates
Fetch and install the latest fixes courtesy of unattended upgrades. Useful feature especially for a home server.
15. 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.
16. Swapfile
In lieu of a dedicated swap
partition, an alternative is to create a 2GB swapfile …
$ 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
17. SSD
Periodic TRIM optimizes performance on SSD storage. Enable a weekly task that discards unused blocks on the drive …
$ sudo systemctl enable fstrim.timer
18. mlocate
Setup the locate
command and database for finding files …
$ sudo apt install mlocate && sudo /etc/cron.daily/mlocate
19. 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. My own ~/.bashrc.
20. GRUB
Add a bit of colour, a bit of sound, and wallpaper to the bootloader. GNU GRUB.
21. 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
Link: Microcode
22. Secure access using SSH keys
Create cryptographic keys, install the OpenSSH server, and configure remote access.
23. Where to go next …
… is up to YOU. I created a setup script that has some ideas.
Happy hacking!
- GPL-2.0+ image of “bestFriend” courtesy of Alex Makas.
Notes
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 this reserve. Example: highlight and select
/home
partition, selectReserved blocks:
and reduce the default5%
reserve set aside by Debian to1%
.↩Task selection menu can be used post-install by running the command
tasksel
.↩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 setnameserver 8.8.8.8
in resolv.conf and install theresolvconf
package. Note thatdns-nameservers
entries are ignored if resolvconf is not installed.↩Multiple wireless static IP address setups can be created with
iface wlp1s0_NAME inet static
and [de]activated withif{up.down} wlp1s0=wlp1s0_NAME
.↩