LinuxXXIX · Linux Security HardeningService minimisation
Service minimisation - reducing the attack surface
What you'll learn
- Audit listening services with ss
- Disable unnecessary systemd services
- Recognise services that should not be running
- Document the baseline and audit for drift
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
Every running service is a potential attack surface. The smaller the surface, the smaller the risk. This lesson covers auditing services and disabling what is not needed.
Audit the current surface
# Listening sockets
ss -tlnp
ss -ulnp
# Enabled services (will start on boot)
systemctl list-unit-files --state=enabled
# Running services
systemctl list-units --type=service --state=running
# Failed services
systemctl list-units --type=service --state=failed
Document the baseline:
Listening TCP: 22 (sshd), 80 (nginx), 443 (nginx), 9090 (node_exporter)
Listening UDP: 53 (systemd-resolved)
Enabled services: sshd, nginx, systemd-resolved, systemd-journald, ...
The baseline is what should be running on a healthy host. Any deviation is a candidate for investigation.
Common services to disable
On a typical server, disable:
- Avahi (mDNS / Bonjour): rarely needed on servers.
systemctl disable --now avahi-daemon. - Bluetooth: not needed on servers.
systemctl disable --now bluetooth. - CUPS: print server.
systemctl disable --now cups. - ModemManager: irrelevant on servers.
- Multipathd: only on hosts with multipath storage.
- PackageKit: GUI tool for updates; unnecessary on servers.
- Avahi-daemon, avahi-daemon.socket: not needed on servers.
- chrony (if using systemd-timesyncd, or vice versa): keep one, not both.
sudo systemctl disable --now avahi-daemon
sudo systemctl disable --now bluetooth
sudo systemctl disable --now cups
sudo systemctl disable --now ModemManager
sudo systemctl disable --now packagekit
Services to keep
Do not disable services you depend on:
- sshd: SSH access.
- systemd-journald: logging.
- systemd-resolved or chronyd: time sync.
- NetworkManager or systemd-networkd: networking.
- Application services: nginx, postgresql, etc.
Detect unexpected services
After the baseline is established, monitor for deviations:
# What services are running that are NOT in the baseline?
comm -23 <(systemctl list-units --type=service --state=running --no-legend | awk '{print $1}') \
<(cat /etc/baseline-enabled-services.txt)
In configuration management (Ansible, Puppet), the baseline is in code. Drift detection catches ad-hoc changes.
Run services in containers
For non-critical services, run them in containers:
- The service has its own filesystem (no host access).
- The service runs as a non-root user inside the container.
- Updates are atomic (pull a new image).
- A misbehaving service cannot affect the host.
This is the principle of least privilege at the service level.
Listening sockets vs running services
A service can be “running” but not listening on any socket (systemd-resolved is often this way). Or it can be “active (scheduled)” but not running. To find the real attack surface, look at listening sockets:
ss -tlnp
This shows every TCP socket a process is listening on. The attack surface is the set of (process, port) pairs.
Common pitfalls
- Disabling sshd: required for remote access. Always verify before disabling.
- Disabling systemd-journald: breaks all logging. Do not disable.
- Disabling networking: the host becomes unreachable.
- Disabling chronyd or systemd-timesyncd: clock skew causes Kerberos and TLS failures.
Knowledge check
Knowledge check · 3 questions
Q1. Which command shows the listening sockets on a host?
Q2. Disabling Avahi on a server is a valid hardening step.
Q3. Which of the following services should generally be disabled on a server? Select all that apply.
Passing score: 75%. Answers are checked in this browser.