OsGate.org Logo

Hardening basics: linux server - hardening server linux

System System

Date 15.12.2010

Visits 4222

"Harden a system is a very important operation especially in the server world. In a default installation there are still some "open doors" that an attacker could use. In this article we will try to close this doors."

Introduction

Hardening a system is a security process that through configurations and changes boost up the security of a system. Hardening your system is a very basic process and should be done in every server or simple client.

Please note that this article doesn't cover all hardening aspects, but only few basic concepts.

BIOS

Hardening can began from secure the bios of our server.

So it recommendable to disable boot from cd-rom, usb pens and network devices, also set the bios password to avoid unwanted changes from other people.

So at the end your bios must have the following configurations:

  • cd-rom, usb and network (pxe) boot disabled
  • bios password
  • if possible set a password for the hard drive too

Useless software

On your production server, don't install software you don't need. This because software errors are the primary way to enter a machine, and less software you've, less possibilities exists to penetrate your system. You must also remember that a small system is much more manageable than one with a lot of packages.

It's better that you don't install software instead of install and then remove a particular program, this because uninstall operation left your system a little dirty and don't linear.

Select only packages relatives to what you want do, for example for a web server, install only apache and the base system, no games, no X server (normally a server doesn't require an UI in the linux/*BSD world) and more over.

Here's a list of useless programs to remove for a basic server installation:

  • X window system
  • Desktop Environment
  • Office suite
  • Multimedia Applications
  • Games
  • Compiler
  • ...

Boot Loader

Boot loaders are the second access door to our system at boot time. Everyone should knows that it's possible to pass to LILO or GRUB parameters at boot time. One of this is the critical "single" parameter that let you boot your system with root privileges without prompting the password. This is very dangerous.

LILO

To disable this easy way to enter, insert this in your LILO configuration (global section):

password=yourpassword
restricted

The password is in clear text so be sure to set the right permissions on lilo.conf, only root should be able to manage this file.

With "restricted" LILO will prompt to you the password only if you insert boot option, like the "single" parameter. Without it you will always prompt for a password.

GRUB

For GRUB things are a bit different.

First we've to generate an MD5 password hash:

bash-4.1$ grub => A grub prompt will appear to you

grub> md5crypt

Password: ********
Encrypted: $1$yOzsg/$z.iFUCOinGHM5uhTG64A60

After the password generation, you must insert this option in grub.conf (global section):

password --md5 $1$yOzsg/$z.iFUCOinGHM5uhTG64A60

Now when you use GRUB, you must first type "p" and then insert your password to boot your system.

Services Startup

At boot time, along with other startup procedures, there are also some services, such as quota manager, cron, anacron, DNS, web server, and so on, that will be started too.

When all these are not used in your server it's a good choice to disable them. Disable services will speed up a bit the boot procedure and will add more linearity and security.

So disable all services you don't need with the init management tool of your distribution (such as update-rc.d in debian).

Inetd

Inetd is a network daemon that lets you run some network services, such as swat, the samba web interface, the popa3d mail service and the most common vsftpd or proftpd. The main difference between a stand-alone daemon and a daemon started through inetd is that if you restart, halt or start inetd all the services are restarted, halted or stared together, so services depends on inetd daemon.

If you look inside the /etc/inted.conf file, you can see all the service started with inted.

For hardening your system, comment all the services you don't need.

Users and groups

Hardening must pass through users, this because users are the first bug in a system so less dangerous things they can do, less possibilities they will have produce a leak in your system, even they're good (your mom) or bad (hacker) users.

Remove useless users and groups

Remove unused users and groups is one of the first operation we will make. If there are users or groups on the system that you will never use, the safety choice is to remove them. This to avoid unwanted access to our server.

You can remove users by looking in the /etc/passwd file where are listed all the users in the system. The file show also the login shell, the home directory, the user and group id and there is a little description of the user.

Short example:

test:x:1002:100:Foo Bar:/home/test:/bin/bash

This line describe:

test => the login name of the user
x => this is the password field, if an "x" is present usually the password is written to /etc/shadow or to another location
1002 => user id
100 => group id
Foo Bar => short description of the user
/home/test => home directory
/bin/bash => the login shell. If you set this to /bin/false the user will never login.

Quite in the same manner for the users, the file used to describe groups is the /etc/group file.

Example:


cdrom:x:19:root,test,foo

cdrom => name of the group
x => the password of the group, Usually you will not set a password for the group.
19 => group id
root,test,foo => the users who belong to this group

So if you want to remove some groups delete the relative line in that file.

Users shell

Another important security note, is to disable the shell access to users who will never use it. For disable shell access edit the /etc/passwd file, and set the last parameter to /bin/false. For example if you set the default shell to /bin/false the user will be unable to login and use a valid shell on the system.

A practical example is an hypothetical ftp users, where the shell is set to /bin/false because we won't and we don't need that the user interact directly with our server through a shell.

Other example are the apache and mysql users:

mysql:x:27:27:MySQL:/var/lib/mysql:/bin/false
apache:x:80:80:User for Apache:/srv/httpd:/bin/false

Password Strength

A basic brick for system hardening. Password strength is often not considered but if you have a very secure password you have done a very large step in the security chain.

Tips for passwords strength are:

  • Don't use dictionary words
  • Don't use any personal data, such as address, telephone number, name, your favorite rock band, etc, #.
  • Use always alpha numeric passwords: number, point, comma, etc, #.
  • Encrypt password with numbers: hello => h3l70
  • Use secure algorithm for real password encryption: SHA256, SHA512, DES based, etc, #
  • set if you want a password age, this to force password changes. You can use the "chage" username command

The /etc/login.defs file

The /etc/login.defs is a very useful file for mange the parameters of the shadow package (the shadow package is responsible for password encryption in the /etc/shadow file).

Here we've some examples of the directive you could find in this file:

# Path settings

ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin
ENV_PATH PATH=/usr/local/bin:/bin:/usr/bin

# Password aging options

PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7

# Userd ID
UID_MIN 1000
UID_MAX 60000
# System accounts IDy
SYS_UID_MIN 101
SYS_UID_MAX 999

#
# Max number of login retries if password is bad
#
LOGIN_RETRIES 5

#
# Maximum number of attempts to change password if rejected (too easy)
#
PASS_CHANGE_TRIES 5

Software Updates

Update lets you run the latest version, bug "aware" of your software.

It's very important to update software with a critical bug as speed as you can to avoid a possible attack. But is also important to check which changes an update brings to the existing software. If you update the software and are presents important modifications it's possible that it doesn't work anymore, so double check.

When you use the update tool of your distribution remember, if you want, to verify the MD5 sum of downloaded packages, specially when using non official repositories (you should always use official repo).

Below you will find an example with the famous apt-get tool:

apt-get update
apg-get upgrade

This will first update your packages list, and then it will upgrade your current packages with the new packages. Apt-get check automatically file integrity so you don't have to worry about that.

But if you want to check the md5sum of installed packages you can install the debsums package, that lets you to check the md5 signature:

debsums package_name

This will give you a list of md5 signature along with a positive/negative response:

debsums bash

debian:~# debsums bash

/bin/bash OK
/usr/share/doc/bash/README.abs-guide OK
/usr/share/doc/bash/inputrc.arrows OK
/usr/share/doc/bash/copyright OK
/usr/share/doc/bash/FAQ OK
/usr/share/doc/bash/changelog.Debian.gz OK
/usr/share/doc/bash/CHANGES.gz OK
/usr/share/doc/bash/NEWS.gz OK
/usr/share/doc/bash/COMPAT.gz OK
/usr/share/doc/bash/INTRO.gz OK
/usr/share/doc/bash/POSIX.gz OK
...

Accounting

The accounting process is a technique that collect useful information about users, commands and resources on the system.

There are two basics accounting types:

  • process accounting, that collects information about commands executed on the system
  • users accounting, that collects information about users, like their logged time or the console where they're logged

You can find some useful tools for accounting in the "acct" package:

accton	 	 => it simply turns process accounting on or off
sa => summarizes accounting information
lastcomm => it prints information about last executed commands
ac => statistics about users connect time
last-acct / last => lists logins on the system

Process accounting

The process accounting operations, lets you to collect useful information about command used on the system. With this powerful tracking tool, you can know what command are used on the system, who started it (process or user) and other useful data.

Usually data about process accounting are collect from the /var/log/pacct file, where are stored all the operations about commands.

accton

When you want to start your process accounting, you have to use the accton command:

touch /var/log/pacct
accton /var/log/pacct

First we have to create the file where we want to collect accounting information. Then second command will turn process accounting on, and tell the system to collect information in the /var/log/pacct file.

sa

Sa is one of the best tool in the process accounting packages. In fact, it prints a summary of the commands executed on the system along with other parameters, such as the number of times the command has been executed:

bash-4.1# sa

345976 -nanre -nancp -nanavio 1950k
163600 -nanre -nancp -nanavio 469k ifconfig
80418 -nanre -nancp -nanavio 469k iwconfig
7720 -nanre -nancp -nanavio 482k rm
6990 -nanre -nancp -nanavio 666k xdg-icon-resour*
4698 -nanre -nancp -nanavio 457k logger
4548 -nanre -nancp -nanavio 697k acpi_handler.sh

Another useful option is the "-m":

bash-4.1# sa -m

346073 -nanre -nancp -nanavio 1949k
root 320105 -nanre -nancp -nanavio 605k
user 24536 -nanre -nancp -nanavio 19188k
user2 1250 -nanre -nancp -nanavio 8051k
messagebus 178 -nanre -nancp -nanavio 701k
sshd 4 infre -nancp -nanavio 1384k

We've a table summarized per user and we can also see, in the second column the number of command used.

lastcomm

This command prints on the screen a list of the last executed commands on the system and if no arguments are given it simply displays last command for all the users.

You can choose to display last commands per users by adding the username:

lastcomm myuser

playonlinux F myuser __ 0.00 secs Mon Nov 29 15:45
grep myuser __ 0.00 secs Mon Nov 29 15:45
sleep myuser __ 0.00 secs Mon Nov 29 15:45
cat myuser __ 0.00 secs Mon Nov 29 15:45
sleep myuser __ 0.00 secs Mon Nov 29 15:45
basename myuser __ 0.00 secs Mon Nov 29 15:45
soffice F myuser __ 0.00 secs Mon Nov 29 15:45
dirname myuser __ 0.00 secs Mon Nov 29 15:45
dirname myuser __ 0.00 secs Mon Nov 29 15:45
soffice F myuser __ 0.00 secs Mon Nov 29 15:45
sed myuser __ 0.00 secs Mon Nov 29 15:45
ls myuser __ 0.00 secs Mon Nov 29 15:45
basename myuser __ 0.00 secs Mon Nov 29 15:45

Or display commands by terminal:

lastcomm terminal_name

With this command are also displayed some additional information, like execution time.

User accounting

ac

Ac simply print on our console user connect time. If you use the command without options you get the total time in hours of user connect time:

bash-4.1# ac

total 4048.14

Useful options are "-p", which displays connect time per user:

bash-4.1# ac -p

user1 3964.79
user2 69.84
root 13.79

total 4048.42

And "-d", which gives you a daily report:

bash-4.1# ac -d

Jul 2 total 26.41
Jul 3 total 42.23
Jul 4 total 38.39
Jul 5 total 50.01
Jul 6 total 64.64
Jul 7 total 46.38
Jul 8 total 53.47
Jul 9 total 18.80
Jul 10 total 27.55

Very useful tool if you want to gather some statistics.

last

The last command, from the man page, "list login on the system". All the information about login are gathered from the /var/log/wtmp file, where are recorded all logins and logouts. Last will print on your console a simple list like this:

bash-4.1# last user -n 5

user pts/2 :0.0 Thu Nov 11 18:30 still logged in
user pts/1 :0.0 Thu Nov 11 18:25 still logged in
user pts/0 :0 Thu Nov 11 17:56 still logged in
user :0 Thu Nov 11 17:56 still logged in
user pts/1 :0.0 Thu Nov 11 15:16 - down (00:28)

wtmp begins Fri Jul 2 04:49:00 2010

As you can see, this command displays for each line, the user, the console, the display, and the login time followed by a short description.

Disabling console

When the system starts up, usually you are able to log in using different console.

The number of console started is controlled by the /etc/securetty file, usually this file looks like:

# This file defines which devices root can log in on.
# These are the ttys on the physical console:

console
tty1
tty2
tty3
tty4
tty5
tty6

# These are some remote ttys, and uncommenting them might be less than fully secure:

#ttyS0
#ttyS1
#ttyS2
#ttyS3
#ttyp0
#ttyp1
#ttyp2
#ttyp3
#ttyp4
#ttyp5
#ttyp6
#ttyp7
#pts/0
#pts/1
#pts/2
#pts/3
#pts/4
#pts/5
#pts/6
#pts/7

In our case to increase security we will disable all the consoles except one in order to obtain:

console
#tty1
#tty2
#tty3
#tty4
#tty5
#tty6

Final thoughts

We have seen that the hardening process isn't a simple process and requires a lot of steps and attention in order to get the best results. This because in a modern system are present too many components and it's easy to forget something.

Anyhow, every production server that provide sensible data or a services, such as a web server, must be hardened in order to complicate life to any kind of attackers.

Please pay attention that hardening is related to any kind of host in a network, these can be server, normal client, router, switch and so on.