Every running service uses memory and CPU, and every service that listens on a network port is something an attacker can probe. A fresh Ubuntu server already runs a few dozen services, and more accumulate as you install and try software. In this tutorial you will list what is running and listening on Ubuntu 24.04, decide what can go, check dependencies, and then stop, disable, mask or uninstall those services safely, with a way to undo each change.

Prerequisites

To follow this tutorial, you will need:

  • A server running Ubuntu 24.04 LTS, for example a CubePath VPS. The systemctl commands work the same on Debian 12 and Rocky Linux 9; only package names differ.
  • A non-root user with sudo privileges.
  • Access to the server console, in case you disable something required for networking or SSH.

Step 1 - Listing running and enabled services

Two lists matter: what is running now, and what will start at boot. Show running services:

systemctl list-units --type=service --state=running
  UNIT                        LOAD   ACTIVE SUB     DESCRIPTION
  cron.service                loaded active running Regular background program processing daemon
  dbus.service                loaded active running D-Bus System Message Bus
  ModemManager.service        loaded active running Modem Manager
  multipathd.service          loaded active running Device-Mapper Multipath Device Controller
  polkit.service              loaded active running Authorization Manager
  rsyslog.service             loaded active running System Logging Service
  ssh.service                 loaded active running OpenBSD Secure Shell server
  systemd-journald.service    loaded active running Journal Service
  systemd-networkd.service    loaded active running Network Configuration
  systemd-resolved.service    loaded active running Network Name Resolution
  systemd-timesyncd.service   loaded active running Network Time Synchronization
  unattended-upgrades.service loaded active running Unattended Upgrades Shutdown
...

Show services enabled at boot:

systemctl list-unit-files --type=service --state=enabled

systemd can also start services on demand through socket units and on a schedule through timer units, so list those as well:

systemctl list-units --type=socket
systemctl list-timers

A service that is stopped but has an active socket (for example cups.socket or multipathd.socket) will start again as soon as something connects to it.

Step 2 - Finding services that listen on the network

Network-facing services are the most important to review. ss lists listening sockets and the process that owns each one:

sudo ss -tulpn
Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
udp   UNCONN 0      0      127.0.0.54:53       0.0.0.0:*         users:(("systemd-resolve",pid=612,fd=16))
udp   UNCONN 0      0      127.0.0.53%lo:53    0.0.0.0:*         users:(("systemd-resolve",pid=612,fd=14))
tcp   LISTEN 0      4096   127.0.0.53%lo:53    0.0.0.0:*         users:(("systemd-resolve",pid=612,fd=15))
tcp   LISTEN 0      4096   0.0.0.0:22          0.0.0.0:*         users:(("sshd",pid=1043,fd=3),("systemd",pid=1,fd=112))
tcp   LISTEN 0      4096   0.0.0.0:111         0.0.0.0:*         users:(("rpcbind",pid=701,fd=4))

Addresses starting with 127. or [::1] are reachable only from the server itself. Anything bound to 0.0.0.0, [::] or a public IP is reachable from outside unless the firewall blocks it. In this example, rpcbind on port 111 is exposed and only needed for NFS, so it is a candidate for removal.

To find the unit behind a process, pass its PID to systemctl status:

systemctl status 701

Step 3 - Deciding what to disable

For each candidate, answer three questions: what does it do, does anything on this server use it, and is it listening on the network? Read the unit's description and documentation:

systemctl status ModemManager.service
systemctl cat ModemManager.service

Then check what depends on it. --reverse lists the units that would be affected:

systemctl list-dependencies --reverse ModemManager.service
ModemManager.service
● └─multi-user.target

If the only reverse dependency is a target such as multi-user.target, nothing else needs it; the target simply starts it at boot.

These services are commonly present on Ubuntu 24.04 servers and are safe to disable in the situations described. Keep anything you are not sure about.

UnitWhat it doesDisable when
ModemManager.serviceManages 3G/4G/5G modemsAlways, on a VPS or server without a modem
multipathd.service and .socketMultipath access to SAN storageThe server does not use iSCSI or Fibre Channel multipath storage
udisks2.serviceAutomounting of removable disks for desktop toolsNothing uses it (common on headless servers)
rpcbind.service and .socketPort mapper for NFS v3 and other RPC servicesThe server is not an NFS client or server
cups.service and .socketPrintingAlways, on a server
avahi-daemon.service and .socketmDNS/Bonjour discovery on the local networkAlways, on a server
snapd.service and .socketSnap packagessnap list shows no snaps you need

Never disable these on a working server: ssh, systemd-journald, systemd-networkd (or NetworkManager where used), systemd-resolved, systemd-logind, dbus, cron, rsyslog, systemd-timesyncd or chrony, and unattended-upgrades, which installs security updates. On a VPS, also keep cloud-init and qemu-guest-agent if they are installed, since the platform may rely on them for provisioning and graceful shutdown.

Step 4 - Stopping and disabling a service

disable --now stops the service and removes it from boot in one command. Using ModemManager as the example:

sudo systemctl disable --now ModemManager.service
Removed "/etc/systemd/system/multi-user.target.wants/ModemManager.service".
Removed "/etc/systemd/system/dbus-org.freedesktop.ModemManager1.service".

For services that also have a socket unit, disable both, or the socket will start the service again on the next connection:

sudo systemctl disable --now multipathd.service multipathd.socket

Verify the result:

systemctl is-active ModemManager.service
systemctl is-enabled ModemManager.service
inactive
disabled

Step 5 - Masking services that keep coming back

A disabled service can still be started manually, by another unit that requires it, or through D-Bus activation. Masking links the unit to /dev/null so nothing can start it:

sudo systemctl mask --now cups.service cups.socket
Created symlink /etc/systemd/system/cups.service → /dev/null.
Created symlink /etc/systemd/system/cups.socket → /dev/null.

Attempts to start it now fail with a clear message:

sudo systemctl start cups.service
Failed to start cups.service: Unit cups.service is masked.

Use masking for services you have decided must never run. For everything else, disable is enough and easier to reason about.

Step 6 - Removing packages you do not need

If a service will never be used, removing its package is cleaner than disabling it: there is nothing left to patch or accidentally re-enable. Find the package that provides a unit:

dpkg -S /usr/lib/systemd/system/rpcbind.service
rpcbind: /usr/lib/systemd/system/rpcbind.service

Check what else would be removed before confirming:

sudo apt purge rpcbind

apt lists the packages that depend on it. If the list includes something you use, answer n and fall back to disabling the service instead.

For snapd, confirm first that no snaps are installed:

snap list
No snaps are installed yet. Try 'snap install hello-world'.

Then remove it:

sudo apt purge snapd

After removing packages, clean up dependencies that are no longer needed:

sudo apt autoremove --purge

Step 7 - Checking the result

Reboot so the change is tested under real boot conditions:

sudo reboot

After reconnecting, confirm that no services failed and review the listening ports again:

systemctl --failed
sudo ss -tulpn
  UNIT LOAD ACTIVE SUB DESCRIPTION

0 loaded units listed.

You can also compare memory use and boot time with what you had before:

free -h
systemd-analyze
systemd-analyze blame | head -n 10

Undoing a change

Every step above is reversible:

sudo systemctl unmask cups.service cups.socket
sudo systemctl enable --now ModemManager.service
sudo apt install rpcbind

A reinstalled package enables its services again through its own post-install scripts, as on a fresh install.

Troubleshooting

  • A disabled service is running again after reboot: another unit starts it, or its socket is still enabled. Run systemctl list-dependencies --reverse name.service and systemctl list-units --type=socket, then disable the socket or mask the service.
  • Failed to disable unit: Unit file name.service does not exist: the name is wrong or the package is not installed. Check with systemctl list-unit-files | grep -i name.
  • A disabled service is still listed as static: static units have no [Install] section and are only started by other units. Disable or mask the unit that pulls it in instead.
  • Lost network or SSH after a change: log in through the server console and run sudo systemctl enable --now on the unit you disabled, for example systemd-networkd or ssh.

Conclusion

Your server now runs only the services it needs, with fewer processes exposed on the network and a smaller set of software to keep updated. As next steps, restrict the remaining open ports with a firewall such as UFW, harden the SSH configuration, and repeat this audit whenever you install new software or change the server's role.