Wednesday, June 13, 2012

Linux Server Hardening Security Tips

This article is a practical step-by-step guide for securing Linux production systems. It discusses basic Linux Security requirements for systems that need to pass various audits in an enterprise environment.

Removing Unnecessary Software Packages (RPMs)

A very important step in securing a Linux system is to determine the primary function or role of the Linux server. You should have a detailed knowledge of what is on your system. Otherwise you will have a difficult time to understand what needs to be secured and hence securing your Linux systems proactively won't be that effective. Therefore, it is very critical to look at the default list of software packages and remove unneeded packages or packages that don't comply with your security policy. If you do that you will have less packages to update and to maintain when security alerts and patches are released. For example, you should not have Apache or Samba installed on your system if you don't use them. Also, it is a good practice not to have development packages, desktop software packages (e.g. X Server) etc. installed on production servers. Other packages like FTP and Telnet daemons should not be installed as well unless there is a justified business reason for it (SSH/SCP/SFTP should be used instead).
rpm -qa
If you want to know more about a particular RPM, run:
rpm -qi <package_name>
To check for and report potential conflicts and dependencies for deleting a RPM, run:
rpm -e --test <package_name>
Patching Linux Systems
Building an infrastructure for patch management is another very important step to proactively secure Linux production environments. It is recommended to have a written security policy and procedure to handle Linux security updates and issues.

For example, a security policy should detail the timeframe for assessment, testing, and rollout of patches. Network related security vulnerabilities should get the highest priority and should be addressed immediately within a short timeframe.

For Red Hat systems I recommend Red Hat Network (RHN) for patch management. In fact, for secure environments you may have to consider Red Hat's Satellite solution. For more information, see Red Hat Network Architectural Overview.
Detecting Listening Network Ports
One of the most important tasks is to detect and close network ports that are not needed.

To get a list of listening network ports (TCP and UDP sockets), you can run the following command:
# netstat –tulpn

Last login: Thu Jun  7 21:40:11 2012 from
root@test-server:~# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q               Local Address  Foreign Address   State   PID/Program name
tcp        0          0               *    LISTEN      1226/python
tcp        0          0             *    LISTEN      10856/xinetd
tcp        0          0             *    LISTEN      22955/sendmail
tcp        0          0             *    LISTEN      30349/sshd

From the output you can see that xinetd, python, sendmail, and sshd are listening.

Another method to list all of the TCP and UDP sockets to which programs are listening is lsof:
# lsof -i -n | egrep 'COMMAND | LISTEN | UDP'

root@ test-server: ~# lsof -i -n | egrep 'COMMAND | LISTEN | UDP'

sshd                   754  root    29r   IPv4    3106912      0t0              TCP        *:ssh  (LISTEN)
xinetd                 881  root    4u    IPv4     3186          0t0              TCP        *:auth (LISTEN)
sendmail            2360 root    5u    IPv4     3204          0t0              TCP        *:smtp (LISTEN)

Closing Network Ports and Disabling Runlevel System Services
One of the most important tasks is to remove any network services from the system startup process that are not needed.

On Red Hat systems you can list all services which are started at bootup using the following command:

chkconfig --list |grep on
You will notice that there are quite a lot of services enabled on your system. But many runlevel services (Stand-Alone Services) are not network related services like kudzu which is responsible for detecting and configuring new and/or changed hardware on your system. This service is only run during the boot process. Ensure not to disable runlevel services that are needed by the system to run smoothly.
To permanently disable e.g. the runlevel service nfs, run:

chkconfig nfs off
To immediately disable the runlevel service nfs, run:

/etc/init.d/nfs stop

Closing Network Ports and Disabling Xinetd Services
The xinetd daemon is a replacement for inetd, the internet services daemon. It monitors the ports for all network services configured in /etc/xinetd.d, and starts the services in response to incoming connections.

To check if xinetd is enabled and running, execute:
# chkconfig --list xinetd
xinetd          0:off   1:off   2:off   3:on    4:on    5:on    6:off
# /etc/init.d/xinetd status
xinetd (pid 2955) is running...

If xinetd is active, it is important to check which Unix services are active and controlled by xinetd. The following command shows all services configured in /etc/xinetd.d and wheter xinetd monitors the ports for these services:
# chkconfig --list | awk '/xinetd based services/,/""/'
xinetd based services:
        krb5-telnet:    off
        rsync:             off
        eklogin:          off
        gssftp:            off
        klogin:            off
        chargen-udp:  off
        kshell:            off
        auth:              on
        chargen:        off
        daytime-udp: off
        daytime:        off
        echo-udp:     off
        echo:            off
        services:       off
        time:            off
        time-udp:     off
        cups-lpd:     off
To get a list of only active services for which xinetd monitors the ports, you could run:
# chkconfig --list | awk '/xinetd based services/,/""/' | grep -v off
xinetd based services:
        auth:   on
In the above example you can see that the telnet-server RPM is not installed on the system. If the Telnet Server package telnet-server would be installed, it would show up on the list whether it's active or not.

Here is an example how to disable a service. Assuming the telnet service is active, run the following commands to disable it and to see how the telnet service entries are being updated:
# chkconfig --list telnet
telnet          on
# cat /etc/xinetd.d/telnet | grep disable
        disable = no
# chkconfig telnet off
# chkconfig --list telnet
telnet          off
# cat /etc/xinetd.d/telnet | grep disable
        disable = yes
For the telnet service it would be better to remove the package from the system since SSH should be used instead:
# rpm -e telnet-server

It is important to investigate all active xinetd services and to disable them if they are not needed.

Here is an example how to find out what a service does. Assuming you don't know what the auth service does which is listed as active in the list above, run the following commands:
# grep "  server" /etc/xinetd.d/auth
        server          = /usr/sbin/in.authd
        server_args     = -t60 --xerror --os -E
#  man in.auth
No manual entry for in.auth
# rpm -qf /usr/sbin/in.authd
# rpm -qi authd-1.4.1-1.rhel3 | awk '/Description/,/""/'
Description :
authd is a small and fast RFC 1413 ident protocol daemon
with both xinetd server and interactive modes that
supports IPv6 and IPv4 as well as the more popular features
of pidentd.
# rpm -ql authd-1.4.1-1.rhel3
This example shows what can be done if there exists no online manuals for the binary in.authd that is started by xinetd. The steps above should be helpful for finding out more about services.

The auth service (aka IDENT, see RFC 1413) allows remote daemons to query information about users establishing TCP connections on the local server. In a trusted environment it helps a server to identify who is trying to use it. For example, it can provide vital information for troubleshooting and who has done what. IDENT requests are needed by some applications like IRC. However, IDENT can be a security risk.

To disable the auth service, run the following command:
# chkconfig auth off

The xinetd daemon is quite flexible and has many features. Here are just a few functionalities of Xinetd:
- Acces control for TCP, UDP, and RPC services
- Acess limitations based on time
- Provides mechanisms to prevent DoS attacks

For more information on Xinetd, see and
Reviewing Inittab and Boot Scripts
The inittab file /etc/inittab also describes which processes are started at bootup and during normal operation. For example, Oracle uses it to start cluster services at bootup. Therefore, it is recommended to ensure that all entries in /etc/inittab are legitimate in your environment.

I would at least remove the CTRL-ALT-DELETE trap entry to prevent accidental reboots:
# sed -i 's/ca::ctrlaltdel:/#ca::ctrlaltdel:/g'

The default runlevel should be set to 3 since in my opinion X11 (X Windows System) should not be running on a production server. In fact, it shouldn't even be installed.
# grep ':initdefault' /etc/inittab
And depending on your environment you might want to comment out the UPS entries as well.

To have changes in /etc/inittab become effective immediately, you can run:
# init q

The /etc/rc.local script is used for commands or startup scripts which are pertinent only to a specific server. (/etc/rc.local is a link to /etc/rc.d/rc.local).
Ensure that all startup scripts in /etc/rc.d/rc.local are legitimate.
Restricting System Access from Servers and Networks
Usually a firewall is used to protect a server from other servers and networks. However, in some cases you may also want to protect a server within a network by using a TCP Wrapper.

The Xinetd super server that comes with most Linux distributions includes a built-in TCP wrapper. It can be used to explicitly define network services to accept incoming connections from specified servers and networks. The TCP wrappers implements access control through the use of two files, /etc/hosts.allow and /etc/hosts.deny. Note that the hosts.allow file takes precedence over the hosts.deny file. And you may want to change the permissions on the two configuration files since they are both world readable.

A recommended security-strategy is to block all incoming requests by default, but allow specific hosts or networks to connect. This is the strategy I will describe here.

To deny everything by default, add the following line to /etc/hosts.deny:
    ALL: ALL

To accept incoming SSH connections from e.g. nodes test11cluster, test2cluster and test3cluster, add the following line to /etc/hosts.allow:
    sshd: test1cluster test2cluster test3cluster
 To accept incoming SSH connections from all servers from a specific network, add
the name of the subnet to /etc/hosts.allow: . For example: 
    sshd: test1cluster test2cluster test3cluster

To accept incoming portmap connections from IP address and subnet 192.168.9, add the following line to/etc/hosts.allow:
 portmap: 192.168.9.

To accept connections from all servers on subnet but not from server, you could add the following line to/etc/hosts.allow:

 Here are other examples that show some features of TCP wrapper:

If you just want to restrict ssh connections without configuring or using /etc/hosts.deny, you can add the following entries to
    sshd: test1cluster   test2cluster   test3cluster

    sshd : ALL : DENY

The version of TCP wrapper that comes with Red Hat also supports the extended options documented in the hosts_options(5) man page. Here is an example how an additional program can be spawned  in e.g. the  /etc/hosts.allow file:
sshd: ALL : spawn echo "Login from %c to %s" | mail -s "Login Info for %s" log@testserver

DISCLAIMER: The information provided on this website comes without warranty of any kind and is distributed AS IS. Every effort has been made to provide the information as accurate as possible, but no warranty or fitness is implied. The information may be incomplete, may contain errors or may have become out of date. The use of this information described herein is your responsibility, and to use it in your own environments do so at your own risk.

                                                      Copyright © 2012

No comments:

Post a Comment