Mastering Minimalist Ubuntu Server Setup for Maximum Efficiency
Provisioning servers with a heavy default install is an invitation to unnecessary risk, resource waste, and unpredictable behavior. The smallest possible Ubuntu setup is often the most robust—attack surface shrinks, performance improves, and change management is clearer. Here’s a direct approach to building an efficient, minimal Ubuntu Server 22.04 LTS—just the essentials, with practical attention to operational detail.
Problem: Bloat and Vulnerability in Default Installs
An out-of-the-box Ubuntu Server often includes more than most infrastructure actually needs: extra daemons, default access paths, and dependencies that compound risk. Actual field incidents—from unexpected RPC listeners to auto-started mail services—typically stem from unused components.
Base Image Selection
For predictable behavior and LTS security coverage, start with the official ubuntu-22.04-live-server-amd64.iso
. For more aggressive minimalism, the "Minimal" installation option during setup trims system utilities and background daemons.
- LTS release: Stable API/ABI through 2027.
- Minimal Install: Reduces packages (no snapd by default, for instance).
Note: The "Minimal ISO" quietly skips useful baseline tools (e.g., wget), so be prepared for manual installs.
Installation Workflow
- Network Boot or ISO
- PXE boot or mount ISO, depending on data center policy.
- Disk Partitioning
- LVM is optional; for ephemeral VMs, a single ext4 partition suffices. Encrypt
/
on exposed hardware.
- LVM is optional; for ephemeral VMs, a single ext4 partition suffices. Encrypt
- Profile Selection
- At the "Profile" prompt, deselect “standard system utilities” and skip OpenSSH for now.
Result: systemd, apt, and a shell. No running network-facing services.
Baseline System Update and User Controls
On first boot:
sudo apt update && sudo apt upgrade --with-new-pkgs -y
Establish a non-root administrator:
sudo adduser opsadmin
sudo usermod -aG sudo opsadmin
Enforce sudo-only privilege escalation; disable password-based root login (/etc/ssh/sshd_config
later).
Essential Package Selection
Resist temptation to install convenience utilities preemptively. Install only after defining the server’s role; for generic access and diagnostics, a tight package set is typical:
Purpose | Package(s) |
---|---|
Remote SSH | openssh-server |
Editor | vim-nox/nano |
Network tooling | iproute2 (default), curl |
Firewall | ufw |
sudo apt install --no-install-recommends openssh-server vim curl ufw -y
Tip: --no-install-recommends
omits dependency chains that bloat the install. For example, installing htop
this way skips language packs and systemd docs.
Security Hardening
Service Audit
Check what’s running post-install:
systemctl --type=service --state=running
Disable surplus daemons:
sudo systemctl disable --now systemd-timesyncd
Don’t assume service states—kernel upgrades can sometimes re-enable default units.
SSH Configuration
Security depends on removing password-based login and root access.
Edit /etc/ssh/sshd_config
:
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Apply changes:
sudo systemctl restart sshd
Gotcha: If you change the SSH port, update any security tooling or monitoring immediately to avoid lockouts. Test new sessions before ending your current one.
Default log for SSH denials:
/var/log/auth.log:
sshd[2048]: Authentication refused: bad ownership or modes for directory /home/user/.ssh
- Ownership/mode requirements are strict:
700 ~/.ssh
,600 ~/.ssh/authorized_keys
.
UFW Firewall
Block all inbound except for SSH (replace 2222 with your chosen port):
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp
sudo ufw enable
Side note: UFW is interface for iptables-nft
. For multi-homed or container hosts, evaluate nftables
directly; UFW will not suffice for complex policy.
Package Install Discipline
Avoid accidental bloat during lifecycle. Persist this in apt settings:
Create /etc/apt/apt.conf.d/99lean
:
APT::Install-Recommends "false";
APT::Install-Suggests "false";
Unattended upgrades? Useful, but only for security updates:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades
In /etc/apt/apt.conf.d/50unattended-upgrades
:
Unattended-Upgrade::Allowed-Origins {
"Ubuntu jammy-security";
};
Do not enable automatic reboot unless running single-purpose instances.
Monitoring: Minimal Tooling
Heavy APM and logging agents defeat the point. For lean monitoring:
htop
for process insightss
ornetstat
(rarely needed)- Use
journalctl
for critical logs
Quick install:
sudo apt install --no-install-recommends htop -y
Produce concise, weekly-rotated logs (/etc/logrotate.d/rsyslog
).
Example: Automated Minimal Bootstrap Script
For repeatability, pin execution order and explicit port choice:
#!/bin/bash
apt update && apt upgrade --with-new-pkgs -y
apt install --no-install-recommends openssh-server vim curl ufw -y
systemctl enable --now ssh ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 2222/tcp
ufw enable
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
sed -i 's/^#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
# Partial—should insert your SSH public key here, e.g.:
# mkdir -p /home/opsadmin/.ssh && echo "ssh-ed25519 AAAA... comment" >> /home/opsadmin/.ssh/authorized_keys && chown -R opsadmin:opsadmin /home/opsadmin/.ssh && chmod 700 /home/opsadmin/.ssh && chmod 600 /home/opsadmin/.ssh/authorized_keys
echo "Minimal Ubuntu server bootstrapped"
Known issue: Cloud-init can overwrite sshd_config and firewall settings on VM image redeploy. Validate post-provision state.
Non-Obvious Tip
System CPU usage can spike unexpectedly when unattended-upgrades runs at the same interval across many VMs. Offset via cron randomization:
/etc/cron.d/apt
Add a randomized sleep before invoking apt tasks.
Summary
Minimalist deployments reduce entropy and risk. Ability to audit, upgrade, and maintain is greatly enhanced when only core services run. Not every workload fits this model; specialized appliances may require more. But control, clarity, and tight attack surface are rarely drawbacks, and mistakes are easier to detect and correct.
Not perfect, but for infrastructure that needs to be stable and secure, it works.
Comment if practical edge cases—legacy hardware, container hosts, or production deployment—require coverage here.