How To Harden a Linux or OpenBSD Installation

If you are more interested in how to break in as opposed to defense, you might prefer my page on Linux root console break-ins, how to break in and how to defend against that.

Many of these work on both Linux and OpenBSD. Some are only relevant on Linux. Suggestions here are divided into:

Green
Everyone should apply these! Unless you really want to be hacked.
Yellow
For the more cautious — do these if you are a little worried about being hacked.
Red
For the truly paranoid.

There are no guarantees for what's here. Remember that security and convenience are usually inversely proportional. Good luck...

Before you start

Green — everyone
Make sure that you have rescue media available.
Especially before continuing with these suggestions.

Linux — try the Knoppix rescue media: http://www.knoppix.org/
OpenBSD — remember that the install CD functions as rescue media

Update your kernel and applications

Update the kernel, applications, and shared libraries

Green — everyone
Make sure that you apply all security updates!

Red Hat, Fedora, CentOS, and other Red Hat derivatives:
# yum upgrade
Really old Red Hat and Fedora:
# up2date -u

Debian, Ubuntu, Knoppix, and other Debian derivatives:
# apt-get update
# apt-get dist-upgrade

Mandriva:
# urpmi.update -a
# urpmi --auto-select

OpenBSD — something like this, assuming you use either csh or tcsh as root:
# setenv PKG_PATH ftp://ftp.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/
# pkg_add -u
Also see my page on how to patch and rebuild the OpenBSD kernel.

Harden the kernel's TCP/IP stack

Yellow
See my page on kernel stack hardening suggestions.

Protect against network threats

Disable unneeded accounts

Green — everyone

Attackers are attempting to login to your system via SSH as common default accounts like test, admin, guest, and root. Browse through /etc/passwd and disable all unneeded accounts. At least disable these, if they exist.

Remember that you should do both:
— Set the user's shell to /bin/false or similar
— Lock the account so that it has no valid password, see passwd -l on Linux.

Also make very certain that root has a strong password!
Red — paranoid

Do the above, and also disable remote root access over SSH.

Make /etc/ssh/sshd_config contain the line:
PermitRootLogin no
and restart your SSH daemon:
# /etc/init.d/sshd restart

Disable unneeded network services

Green — everyone

Use lsof to list your system's open TCP and UDP ports. Run this as root since unprivileged users may not be allowed to view sockets they do not own:
# lsof -i

Every one of those open ports is a risk. Do you really need to run every TCP/UDP service? Turn off what you do not need! You definitely should not run Telnet or any of the Berkeley R* services (rlogin, rcp, rsh).

For standalone services like HTTP/HTTPS, stop and disable the boot script:
Linux:
   # /etc/init.d/httpd stop
   # chkconfig --del httpd
OpenBSD:
   # pkill -TERM httpd
   Then edit /etc/rc.conf and insert:
   httpd_flags="NO"

For services run out of inetd (some Linux distributions, OpenBSD), comment out the line in /etc/inetd.conf and signal inetd to re-read its configuration:
# vi /etc/inetd.conf
# pkill -HUP inetd

For services run out of xinetd (most Linux distributions), edit the specific configuration script and signal xinetd to reload its configuration:
# vi /etc/xinetd.d/wu-ftpd
(change disable = no to disable = yes)
# pkill -HUP xinetd
Yellow

If you must run HTTP, then do not also run HTTPS unless you really need a secure server (avoid some complication and reliance on the OpenSSL shared libraries).

Find your httpd.conf Apache configuration file:
# find /etc /var -name httpd.conf
Edit httpd.conf and comment out the line reading:
# Listen 443
Then restart Apache:
/etc/init.d/httpd restart
Red — paranoid

By the time you finish, your lsof -i output contains only the following. Note that you may get one line each for IPv4 and IPv6 (OpenBSD) or just one line saying "IPv6" if it's running a dual stack or "IPv4" if it's IPv4-only (Linux):

COMMAND  PID USER  FD TYPE DEVICE SIZE NODE NAME
sshd    6502 root  3u IPv4 64002       TCP  *:ssh (LISTEN)
sshd    6502 root  3u IPv6 64003       TCP  *:ssh (LISTEN)

Protect your machine with iptables rules (Linux only)

Green — everyone Assuming there is no reference to /etc/rc.d/rc.firewall in any existing boot script, do the following. And if there is a reference, then either remove those references or use a different name in the following.

1 — Start a firewall script:
touch /etc/rc.d/rc.firewall
chmod 700 /etc/rc.d/rc.firewall


2 — Let's say your goal is: Write your firewall script something like the following. Modify the IP ranges and services, and add ACCEPT rules as needed:
#!/bin/sh

# Flush any existing rules and set the default policies
iptables -F
iptables -P INPUT   ACCEPT
iptables -P OUTPUT  ACCEPT
iptables -P FORWARD ACCEPT 

# Accept anything from myself
iptables -A INPUT -s 127.0.0.1/32 --jump ACCEPT 
# Allow myself to be a non-passive FTP client
iptables -A INPUT -p tcp --dport ftp-data --jump ACCEPT 

# Do not allow a local user to connect to a remote Telnet
# server and thus give away login and password information:
iptables -A OUTPUT -p tcp --dport telnet --jump REJECT 

# Accept SSH connections from 128.46.0.0/16 and 44.48.40.12
iptables -A INPUT -s 128.46.0.0/16  -p tcp --dport ssh --jump ACCEPT 
iptables -A INPUT -s 44.48.40.12/32 -p tcp --dport ssh --jump ACCEPT 

# Accept HTTP connections from 128.46.144.0/24
iptables -A INPUT -s 128.46.144.0/16  -p tcp --dport http  --jump ACCEPT 
iptables -A INPUT -s 128.46.144.0/16  -p tcp --dport https --jump ACCEPT 

# If it's not one of the above allowed cases, block connection
# attempts to privileged TCP and UDP ports.
#
# Send the client an ICMP Destination Unreachable (Port Unreachable)
# packet to be polite and allow its application to quickly shut
# down.
iptables -A INPUT -p tcp --dport 1:1023 --jump REJECT 
iptables -A INPUT -p udp --dport 1:1023 --jump REJECT 

# If you want to allow this machine to be a client,
# uncomment the following command:
# iptables  -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Otherwise, drop inbound TCP packets with ICMP messages
iptables -A INPUT -p tcp --jump REJECT 

# Report what happened
echo 'Firewall rules installed:' 
iptables -L 
3 — Experiment with running that script directly and testing.

3 — When you are certain it works, add a line to the end of /etc/rc.d/rc.local:
   /etc/rc.d/rc.firewall
Red — paranoid

As above, but change the next-to-last block of code to the following (DROP vs REJECT):

# If it's not one of the above allowed cases, block connection
# attempts to privileged TCP and UDP ports.
#
# Send the client an ICMP Destination Unreachable (Port Unreachable)
# packet to be polite and allow its application to quickly shut
# down.
iptables -A INPUT -p tcp --dport 1:1023 --jump REJECT 
iptables -A INPUT -p udp --dport 1:1023 --jump REJECT 
# If it's not one of the above allowed cases, block connection
# attempts to privileged TCP and UDP ports.
#
# Silently drop unwanted packets to waste the attacker's time.
iptables -A INPUT -p tcp --dport 1:1023 --jump DROP 
iptables -A INPUT -p udp --dport 1:1023 --jump DROP 

Configure SSH securely

I have more about setting up and using SSH on a dedicated page.

Green — everyone

Put the following directives in /etc/ssh/sshd_config to configure the SSH server. Note that many of the SSH defaults are secure, so include the following but comment out any other directives currently used.

# Only the more secure SSH2 protocol
Protocol 2
X11Forwarding yes
Subsystem sftp /usr/libexec/sftp-server

And for the SSH client configuration in /etc/ssh/ssh_config:
# Only the more secure SSH2 protocol
Protocol 2
# Although read "man ssh_config" first...
ForwardX11 yes
Red — paranoid

Put the following directives in /etc/ssh/sshd_config. Note that many of the SSH defaults are secure, so include the following but comment out any other directives currently used in your SSH daemon configuration:


# Only the more secure SSH2 protocol
Protocol 2
# List users allowed to connect via SSH
# Also see "AllowGroups", "DenyUsers",
# and "DenyGroups" in "man sshd_config".
AllowUsers joe jane ....
# Only the strongest ciphers
Ciphers blowfish-cbc,aes256-cbc,aes256-ctr
# Only accept authentication via cryptographic
# challenge-response (remote client must have
# cryptographic keys)
PasswordAuthentication no
# Do not allow root login -- first login
# as ordinary user, then su to root
PermitRootLogin no
Subsystem sftp /usr/libexec/sftp-server

And for the SSH client configuration in /etc/ssh/ssh_config:
# Only the more secure SSH2 protocol
Protocol 2

Hide BIND version

Green — everyone

Add the line "version ..." to the file /etc/named.conf, within the "options{...};" block:

other directives appear here...

options {
     other options appear here...
     version "VERSION NOT PROVIDED";

} ;

other directives appear here...

Otherwise a would-be attacker could figure out your BIND version with this command:
$ dig @yourserver version.bind chaos txt

Prevent trivial root console break-in (Linux only)

With some Linux distributions moving from traditional SVR4 Init to Upstart, this explanation gets complicated. See the dedicated page on how this exploit works and how to prevent it. The very short version is:

On a traditional init based system (e.g., RHEL/CentOS 5, Mandriva):
Add the following line to the file /etc/inittab right after the line referencing /etc/rc.d/rc.sysinit

ss:S:respawn:/sbin/sulogin

On an upstart based system (e.g., RHEL/CentOS 6, Fedora):
Change a line in the file file /etc/sysconfig/init to read:

SINGLE=/sbin/sulogin

On Ubuntu: This has already been done for you!

Yellow — cautious

Reconfigure the BIOS to disable booting from media and set a BIOS password, as discussed on the Linux break-in and defense page.

Red — paranoid

Consider alarming the system case, as discussed on the Linux break-in and defense page.

Harden the file system

Green — everyone

Make /tmp a RAM-based filesystem. RAM is much faster than a disk, and any data stored there is truly temporary and is lost at shutdown.

Yellow — cautious

Do the above, but prevent an attacker from doing many things by making /tmp less useful to them. Make the /etc/fstab entry say:
Linux:
 none /tmp tmpfs rw,noexec,nosuid,nodev,size=100000000 0 0
OpenBSD:
 swap /tmp mfs rw,noexec,nosuid,nodev,-s=128000 0 0

Red — paranoid

Do all the above, and also use the noexec, nosuid, and nodev options on other partitions as appropriate — maybe something like this:

/varnosuid,nodev,noexec
/homenosuid,nodev
/usrnodev

Harden root authentication

Yellow — cautious

Best practice for the root account is:

Do the following. Be very careful, this is where you can lock yourself out and only be able to break in with rescue media.

Disallow direct root login on the console

Prevent root network authentication

Prevent unencrypted transmission of the root password

Limit the set of people able to attempt to become root (uneeded on OpenBSD)

At this point you could write the root password on the monitor, and ordinary users still would be unable to become root — not that this is a good idea, but root privileges now require knowledge of a privileged account's password plus knowledge of the root password.

Harden user authentication

Enforce password quality (Linux only)

Green — everyone

Linux distributions have typically enforced password quality through the pam_cracklib.so PAM module. However, this only provides limited control — the newer pam_passwdqc.so module is much better.

The pam_passwdqc.so module groups characters into four classes:
   Lower-case letters
   Upper-case letters
   Digits
   Everything else
Some things are too obvious to the password creator and the password guesser, and are not given any credit:
   Starting the password with an upper-case letter
   Adding a digit to the end of the password
So, these are all single-character-class passwords:
   dog Dog dog7 Dog7
The module also considers pass phrases (unless you tell it not to), the following would be a three-word pass phrase with 11 characters, using 3 character classes (lower-case, the upper case B, and the blank spaces):
   The Big Dog

Make sure that the file /etc/pam.d/system-auth contains the following line:
password required /lib/security/pam_passwdqc.so min=12,10,10,8,6
Users will now be required to make their new passwords at least this long:
   12 characters, if using just one character class
   10 characters, if using just two character classes
   10 characters, if it is a pass phrase
   8 characters, if it uses three character classes
   6 characters, if it uses all four character classes
These rules will also apply to root since you did not loosen up security by saying the rules only applied to users, with the added parameter:
   enforce=users
See the pam_passwdqc.so web page for more details.

Yellow — cautious

No, simply use:
password required /lib/security/pam_passwdqc.so

The defaults are:
   No single-character-class passwords allowed
   Two-character-class passwords must contain at least 24 characters
   Pass phrases must contain at least 12 characters
   Three-character-class passwords must contain at least 8 characters
   Three-character-class passwords must contain at least 7 characters

Red — paranoid

You know, if you really want to take full advantage of the security offered by the 128-bit MD5 cryptographic hash used to authenticate the login pass phrase, you should consider the fact that English text contains about 1.2 bits of entropy per character, and 128/1.2 = 106.66666:
password required /lib/security/pam_passwdqc.so min=disabled,107,107,100,80
Yeah, good luck convincing anyone that this is a good idea...


To the Computer / Network Security Page

To the Unix / Linux Page

Click here to inquire about advertising on this or any page on this site.
Home Unix/Linux Networking Cybersecurity Travel Technical Radio Site Map Contact


Use /bin/vi! Manipulate images with ImageMagick! Hosted on OpenBSD
Hosted on Apache This site is viewable with any browser Valid XHTML 1.0! Valid CSS!
© Bob Cromwell Feb 2012. Created with /bin/vi and ImageMagick, hosted on OpenBSD with Apache.    Root password available here, privacy policy here.