Cyber Intelligence
System Hardening · Hardening

L11. Reducing Attack Surface: Services, Ports and Daemons

Video generating

Check back soon for the video lesson on Reducing Attack Surface: Services, Ports and Daemons

Every running service is a potential entry point for an attacker. Learn how to audit running services with systemctl, identify open ports with ss, and disable or remove anything your server does not need.

What Is Attack Surface?

Attack surface is the total number of points where an attacker could try to enter or extract data from your system. Every running service, open port, and installed package adds to this surface. A hardened server runs only what it needs and nothing more.

Think of it this way: if your server's only job is to serve a web application, it should not be running a mail server, a print service, or a database it does not use. Each unnecessary service is a liability.

Understanding systemd Services

Most modern Linux distributions use systemd as their init system. systemd manages services (also called units) through the systemctl command.

Service States

StateMeaning
active (running)The service is currently running
active (exited)The service ran a one-time task and finished
inactive (dead)The service is not running
enabledThe service starts automatically at boot
disabledThe service does not start at boot

Listing Running Services

# Show all running services
systemctl list-units --type=service --state=running

# Show all enabled services (start at boot) systemctl list-unit-files --type=service --state=enabled

Managing Services

# Stop a running service immediately
sudo systemctl stop cups.service

# Prevent it from starting at boot sudo systemctl disable cups.service

# Do both in one command sudo systemctl disable --now cups.service

# Check the status of a specific service systemctl status sshd.service

Common Services You Can Safely Disable

On a fresh server install, several services may be running that you do not need:

ServicePurposeDisable If...
cups / cups-browsedPrintingServer has no printers
avahi-daemonmDNS/DNS-SD discoveryNot needed on servers
bluetoothBluetooth supportNo Bluetooth hardware
ModemManagerCellular modem supportNo modems
accounts-daemonUser account info for desktopHeadless server
# Example: disable printing and discovery services
sudo systemctl disable --now cups cups-browsed avahi-daemon

Finding Open Ports

A running service often listens on a network port. Even if you do not know which services are running, you can discover them by checking which ports are open.

Using ss (Socket Statistics)

# Show all listening TCP ports with the process name
sudo ss -tlnp

# Show all listening UDP ports sudo ss -ulnp

# Example output: # LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3)) # LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=5678,fd=6))

The -t flag filters TCP, -l shows only listening sockets, -n shows numeric ports instead of service names, and -p shows the process that owns each socket.

Using netstat (Legacy)

# Equivalent command with netstat
sudo netstat -tlnp
ss is the modern replacement for netstat and is available on all current distributions. Use ss unless you are on a very old system.

Investigating Unknown Services

If you find a port open and do not recognize the service:

# Find which process is using port 8080
sudo ss -tlnp | grep 8080

# Get details about the process ps aux | grep <PID>

# Check which package owns the binary dpkg -S /usr/bin/some-binary # Debian/Ubuntu rpm -qf /usr/bin/some-binary # RHEL/CentOS

Removing Unneeded Packages

Disabling a service stops it from running, but the software remains installed. Removing the package entirely is more thorough:

# Debian/Ubuntu
sudo apt remove --purge telnet rsh-client
sudo apt autoremove

# RHEL/CentOS sudo dnf remove telnet rsh

Removing packages also removes their configuration files (with --purge), which eliminates the risk of a misconfiguration reactivating them later.

A Practical Audit Workflow

  1. List all running services: systemctl list-units --type=service --state=running
  2. List all open ports: sudo ss -tlnp
  3. For each unknown entry, identify the process and decide: does this server need it?
  4. Disable and stop services that are not needed
  5. Remove packages you will never use
  6. Document what you disabled and why

This audit should be part of your initial server setup and repeated periodically. New packages installed by team members can introduce services you did not plan for.

Exam Focus Points
  • Every running service and open port increases the attack surface: run only what the server needs
  • systemctl disable --now stops a service immediately and prevents it from starting at boot
  • ss -tlnp shows all listening TCP ports along with the process name that owns each socket
  • Removing unneeded packages with --purge is more thorough than just disabling the service
Knowledge Check

1. What does the command "systemctl disable --now cups.service" do?

2. Which command shows all listening TCP ports along with the owning process on a modern Linux system?

3. Why is removing an unneeded package more secure than just disabling its service?