OS Hardening

Created by: Jonathan Blanton and Brent ByungHoon Kang, George Mason University, bkang5@gmu.edu
Updated by: Noah Cain, Colorado State University, noah.mason.cain@gmail.com, on 7 September 2017.
  1. Overview
  2. Recommended Reading
  3. Introduction
  4. Terms Used
  5. Assignment Instructions
    1. Setup
    2. Tasks
      1. Part 1: Finding Running Services
      2. Part 2: Shutting Down Services
      3. Part 3: Making It Stick
        1. Part 3.1: Ordinary Services
        2. Part 3.2: systemctl
    3. What Can Go Wrong
  6. Submission Instructions


The purpose of this lab is to demonstrate how services are started and stopped in Linux, and to teach students how to permanently disable unneeded services on Linux. Students will start, stop, and disable services. Unneeded services can be a potential security risk, so students should learn how to disable unneeded services in order to descrease the probability of a security compromise.

Recommended Reading

Introduction to Linux: A Hands On Guide
Chapter 4, sections 4.2.4 and 4.2.5


OS hardening is the practice of configuring a machine to make it more resistant to attack. Most operating systems ship with many unnecessary services and applications running. The more applications and services that run, the greater the chance is that one or more of them will be vulnerable to attack. The purpose of this lab is to demonstrate how to shut down unnecessary services on Linux.

Terms used in this lab

Some of the files and folders you'll encounter in this lab are named confusingly. The following is a brief introduction to the terms you'll see:

This is the "Internet super-server". (The word "inet" stands for "internet".) In the old days, this program was used as a front-end to many services. It's not used as much anymore nowadays.
These directories store symbolic links (shortcuts) to scripts in /etc/init.d/. In this lab, you'll be renaming files in the /etc/rc3.d directory.

Assignment Instructions


Swap in the experiment using /share/education/OSHardening_GMU/oshardening.ns.


Part 1: Find Running Services

  1. SSH to nodeA in your experiment. View the list of open ports with the following command:
    $ netstat -t -u -l
    Netstat is used to show open network connections. The -t option specifies TCP ports, the -u option specifies UDP ports, and the -l option specifies only open (or "listening") ports. Note that there are quite a few ports open.
  2. It would be nice if we knew which programs had those ports open. Netstat's -p option will show the process name that owns each open port. The output will be wide, so maximize the terminal window before running the command. Become root, and run the following:
    # netstat -t -u -l -p
    This shows the same information as before, except now process names and IDs are included. Take a screenshot of this window.

The interesting columns in the netstat output are Proto, Local Address, and PID/Program name. Proto stands for protocol. It will be either TCP or UDP (or sometimes TCP6 or UDP6). Local Address is the IP address and port that the service is listening on. The IP address is usually "*", indicating that the service is listening on all available network connections. PID/Program name gives the process ID and name of the program that is listening on the port.

The name of the service is generally the same as the name of the program in the PID/Program name column. For services controlled by inetd, the program name will be inetd, and the name of the service will be found in the Local Address column.

Each of the network services that is running represents a potential opportunity for an intruder to break into the computer. In order to secure the system, it is necessary to shut down unneeded services. For this lab, we're going to shut down all external services except SSH, pubsubd, and emulab-syncd. You need SSH to access the node. The rest of listed services are used by DeterLab to control or monitor the node.

In Linux, there are multiple ways to start and stop services, and different distributions offer different tools to manage services. In this lab, we'll be using a very low-level method to manage services. The advantage of this method is that it will work on almost all Linux distributions, as well as some Unix systems.

Part 2: Shutting Down Services

Most running services are started or stopped with a script in the /etc/init.d directory. Usually, the script name will be the same as the program name, but not always. To stop a service, run its script with the argument "stop". For example, to stop sendmail, run the following:

# /etc/init.d/sendmail stop

To start or restart a stopped service, run the script with "start" instead of "stop".

# /etc/init.d/sendmail start

To see a list of all the script in that directory, execute the command "ls /etc/init.d/".

  1. In the netstat output from step 2 above, look at the "Program name" column. This will tell you which program to stop.
  2. Go through the list of programs and stop each unnecessary service. There are a few services whose names don't match the script names, but the names are similar, so try to find the script names on your own. If you accidentally stop a service you didn't intend to stop, simply start it again.
  3. Run "netstat -t -u -l -p" again and take a screenshot of the output. If all went well, you should have only a few services running.
  4. Reboot the experiment node. After logging back in, run "netstat -t -u -l -p" and observe the results. What happened to the list of open ports?

Part 3: Making it stick

All of the services you stopped have come back after a reboot. This is because Linux starts all configured services at startup. You stopped the services, but you didn't change the configuration, so all the services came back up. In this part of the lab, we're going to change the configuration so that the services won't start automatically.

Part 3.1: Ordinary Services
The system determines which services to start based on the default runlevel. (For more information on runlevels, see http://wiki.linuxquestions.org/wiki/Run_Levels). In Ubuntu, the default runlevel is 3, so the system services are controlled by the scripts in /etc/rc3.d/. The name of each script is the letter S or K, a two-digit number, and the name of the service. If a script name starts with an S, the service is Started; if it starts with a K, it is Killed. The numbers indicate the order in which the scripts should be run. In this part of the lab, you will disable unneeded services.
  1. Run "netstat -t -u -l -p" to see which services need to be stopped.
  2. For each service that you stopped earlier, rename its script in /etc/rc3.d to start with a K instead of an S. You should also change the number after the S. The new number and the old number should add up to 100. For example,
    # mv S18sendmail K82sendmail
  3. At this point, you've configured the service to not start on boot, but it's still running right now. After you've renamed a script, run it with the "stop" argument to stop the service.
    # /etc/rc3.d/K82sendmail stop
  4. Write down which scripts you renamed and include the list in your lab report.
  5. Run "netstat -t -u -l -p" to see which services are still running.
Part 3.2: systemctl

Some services are run by inetd. To ensure they are started or stopped you would need to edit inetd's configuration file. Alternatively, they can be ported to systemd services and started, stopped, enabled, or disabled with a tool called systemctl.

  1. Read about the tool at its Arch wiki page
  2. Write a small script that would apply your changes from part 3.1 using systemctl. Then swap out your experiment and swap it in again. Run your script and take a screenshot of the output. Submit your script and the screenshot in the lab report.

What can go wrong

Submission Instructions

Submit the following in your report:
  1. Screenshot of netstat's output from part 1
  2. List of commands you ran to stop the unnecessary services, and which service was affected in part 2.
  3. Screenshot of netstat's output from part 2
  4. List of commands you ran to make changes stick in part 3.
  5. List of changes in /etc/rc3.d directory from part 4
  6. Your script using systemctl to remove services and make the changes stick, starting from a freshly swapped in experiment
  7. Screenshot of netstat's output from part 4