Hardening Linux

From ChekMate Security Group

Contents

Hardware Specifications

  1. How many hard drives do you have?
  2. What size is each hard drive (eg, 15GB)?
  3. If you have more than one hard drive, which is the primary one?
  4. What kind of hard drive do you have (eg, IDE ATA/66, SCSI)?
  5. How much RAM do you have (eg, 256MB RAM)?
  6. Do you have a SCSI adapter? If so, who made it and what model is it?
  7. Do you have a RAID system? If so, who made it and what model is it?
  8. What type of mouse do you have (eg, PS/2, Microsoft, Logitech)?
  9. How many buttons does your mouse have (2/3)?
  10. If you have a serial mouse, what COM port is it connected to (eg, COM1)?
  11. What is the make and model of your video card? How much video RAM do you have (eg, 8MB)?
  12. What kind of monitor do you have (make and model)?
  13. Will you be connected to a network? If so, what will be the following:
    1. Your IP address?
    2. Your netmask?
    3. Your gateway address?
    4. Your domain name server's IP address?
    5. Your domain name?
    6. Your hostname?
    7. Your types of network(s) card(s) (makes and model)?
    8. Your number of card(s) (makes and model)?

Recommended Partition Table

A good partition strategy is to create a seperate partition for each major file system. This enhances security and prevents accidential denial of service or exploit of SUID programs.

Creating multiple partitions offers you the following advantages:

  • Protection against denial of service attack.
  • Protection against SUID programs
  • Faster booting
  • Easy backup and upgrade management
  • Ability for better control of mounted file system
  • Limit each file system's ability to grow
  • Improve performance of some program with special setup

Sample Partition configuration for a SCSI hard drive of 9.1 GB with 256 MB physical RAM:

Partition 01 :  256 MB      /          (Root File System)
Partition 02 :  512 MB      Linux Swap (Virtual File System)
Partition 03 :    5 MB      /boot      (Linux Kernel partition)
Partition 04 :  512 MB      /usr       (Shared Binaries partition)
Partition 05 : 5700 MB      /home      (User Partition)
Partition 06 :  256 MB      /chroot    (Chroot Jail Partition)
Partition 07 :  256 MB      /var       (Accounting & Administrative
Partition 08 : 1000 MB      /var/lib   (Databases partition)
Partition 09 :  227 MB      /tmp       (Temporary file partition)

Base Linux Installation

text acpi=off
custom installation
Do not install ANY packages 

Allow SSH to server

vi /etc/sysconfig/iptables
 Insert:
  -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 22 -j ACCEPT
/etc/init.d/iptables restart

Set up YUM

rpm --import /usr/share/RPM-GPG-KEY*
yum install emacs



Software that must be uninstalled after installation

Red Hat Linux installs other programs on your system by default and doesn't give you the choice to uninstall them during the install setup or programs which are going to be compiled from tarballs (source code). For this reason, you must uninstall the following software on your system after the installation of your Linux server. In the table below, you'll find a partial list of software that must be uninstalled once the installation of your Linux server has been completed.

anacron		apmd		at	 	dosfstools
eject		setserial 

Use the following YUM command to uninstall them:

[root@server /]# yum remove <softwarenames>

The command to uninstall RPM's software is:

Where <softwarenames> is the name of the software you want to uninstall e.g. (foo).

Step 1

Programs like apmd, Sendmail, at and anacron are daemons that run as process. It is better to stop those processes before uninstalling them from the system.

[root@server /]# /etc/rc.d/init.d/apmd stop 
Shutting down APM daemon: [OK]

To stop those processes, use the following commands:

[root@server /]# /etc/rc.d/init.d/sendmail stop 
Shutting down sendmail: [OK] 
[root@server /]# /etc/rc.d/init.d/atd stop 
Stopping at daemon: [OK] 
[root@server /]# /etc/rc.d/init.d/anacron stop 
Shutting down anacron: [OK]

Step 2

Once the processes apmd, sendmail, at and anacron programs have been stopped, you can safely uninstall them, and all the other packages, as shown below:

To remove all the unneeded packages together, use the following commands:

[root@server /]# yum remove --nodeps anacron apmd at dosfstools eject setserial
[root@server /]# rm -rf /var/spool/anacron/

Step 3

The program hdparm is needed by IDE hard disks but not SCSI hard disks. If you have an IDE disk on your system you must keep this program (hdparm), but if you don't have an IDE hard disk you can remove it safely from your system. hdparm is used to optimize your IDE hard drive. SCSI hard drives doesn't need to be optimized since they are capable to run at their full speed (80 Mps to 160 Mps) without modification.

To remove the hdparm package from your system, use the following command:

[root@server /]# yum remove hdparm

Step 4 - ** This is a SCSI Server - Ignore this step **

The program mkinitrd is needed by SCSI or RAID hard disk but not IDE hard disks. If you have a SCSI or RAID disk on your system you must keep this program (mkinitrd), but if you don't have a SCSI or RAID hard disk you can safely remove it from your system.

To remove the mkinitrd package from your system, use the following command:

[root@server /]# rpm -e --nodeps mkinitrd

Step 5

Use the programs authconfig, ntsysv, and setuptool in order to set your NIS and shadow passwords, your numerous symbolic links in /etc/rc.d directory, and text mode menu utility which allow you to access all of these features. After those configurations have been set during the installation stage of your Linux server it's rare that you would need to change them again. So, you can uninstall them, and if in the future you need to change your keyboard, mouse, default time, etc again via test mode menu, all you have to do is to install the program with the RPM from your original CD-ROM.

To remove all the above programs from your system, use the following command:

[root@server /]# yum remove authconfig ntsysv setuptool

Step 6

The program quota is a system administration tools for monitoring and limiting user/group disk usage, per file system. This program must be installed only on servers where the need for monitoring and restricting amount of disk space in users directories is require.

To remove the quota package from your system, use the following command:

[root@server /]# yum remove quota

Step 7

The ash package is a smaller version of the Bourne shell (sh). Since we already use sh, we can uninstall this package from our system. If you use this program in your regular administration task, then keep it installed on your server.

To remove the ash package from your system, use the following command:

[root@server /]# yum remove ash

Step 8

The time package is a utility for monitoring a program's use of system resources and can be used by developer to optimize their programs. This program is useful for developers.

To remove the time package from your system, use the following command:

[root@server /]# yum remove time

Descriptions of programs that must be uninstalled after installation of the server

Below is the list of programs and a short description of their purpose. We must uninstall them for increased security and to make more space on our server. For more information and an explanation of their capabilities and uses, please see your Red Hat manual or query the package by making an "rpm -qi foo" command before uninstalling it.

  • The anacron package is similar to the cron package but differ in the way that it does not assume that the system is running continuously and it is a good command scheduler for system which don't run 24 hours a day. [Unnecessary for a server]
  • The apmd package, or advanced Power Management daemon utilities, can watch your notebook's battery and warn all users when the battery is low. [Unnecessary for a server]
  • The at package is a utility that will do time-oriented job control by scheduling a command to run later. Unfortunately, it has had a rich history of problems and we can achieve the same functionality with the more secure vixie-cron package. For this reason I recommend you to uninstall it. [Security Risks]
  • The dosfstools package contains utilities for making and checking MS-DOS FAT file systems on Linux. Remember that we want to install a Linux server on our system and not a PC with two different operating systems on it. Therefore we must uninstall this program from our computer. [Unnecessary, we run a server]
  • The eject package contains an eject program that allows the user to eject removable media (typically CD-ROMs, floppy disks, Iomega Jaz or Zip disks) using software. [Necessary only if you have a tape backup on this server]
  • The setserial package is a basic system utility for displaying or setting serial port information. [Unnecessary]

Additional Packages to remove

These packages have been reviewed against the XSUT001 server configuration and can be removed. As the RPM packages are dependent on the server requirements, remove the packages that will not impact the server's services.

If these packages are dependencies, please comment here so that we can properly maintain the package list.

acl                  anacron                    apmd                             ash            at
attr                 autofs                     bc                               bind-utils     comps
cups                 cups-libs                  cyrus-sasl-plain                 dhcpv6_client  dos2unix
dosfstools           dump                       fbset                            finger         ftp
gettext              htmlview                   ipsec-tools                      irda-utils     isdn4k-utils
jwhois               kernel-utils               krb5-workstation                 lftp           lha
libwvstreams         lockdev                    logwatch                         lsof           man-pages
mdadm                mgetty                     minicom                          mtr            mt-st
nano                 nc                         netconfig                        netdump        nfs-utils
nscd                 nss_ldap                   pam_smb                          parted         pax
pdksh                pinfo                      portmap                          ppp            procmail
psacct               rdate                      rdist                            redhat-lsb     redhat-menus
rhnlib               rhpl                       rmt                              rp-pppoe       schedutils
setarch              specspo                    stunnel                          symlinks       sysreport
system-config-mouse  system-config-network-tui  system-config-securitylevel-tui  talk           tcpdump
telnet               time                       traceroute                       unix2dos       unzip
up2date              wireless-tools             wvdial                           xinetd         ypbind
yp-tools             zip

Remove unnecessary documentation files

By default the majority of each RPM's packages installed under Linux comes with documentation files related to the software. This documentation contains original files from the program tar archive like README, FAQ, BUG, INSTALL, NEWS, PROJECTS and more.

Many of them can be easily retrieved from the website where the program has been downloaded and it makes no sense for them to be kept on your system. I know that hard drives costs have come down considerably recently, but why keep this kind of documentation on a secure server if it unlikely they will not be read more than once. Anyway, have a look inside those files and decide for yourself if you want to remove them or not.

To remove all documentation files from your system, use the following commands:

[root@server /]# cd /usr/share/doc/ 
[root@server doc]# rm -rf *

Installed RPMs

To verify the list of all installed RPM package on your system, use the command:

[root@server /]# rpm -qa > installed_rpm

The "-qa" option will query all installed RPM packages on your system and the special character ">" will redirect the output to the file named installed_rpm.


Linux General System Security

A secure Linux server depends on how the administrator makes it. Once we have eliminated the potential security risk by removing unneeded services, we can start to secure our existing services and software on our server. Within a few hours of installing and configuring your system, you can prevent many attacks before they occur. In this chapter we will discuss some of the more general, basic techniques used to secure your system. The following is a list of features that can be used to help prevent attacks from external and internal sources.

BIOS

It is recommended to disallow booting from floppy drives and set passwords on BIOS features. You can check your BIOS manual or look at it thoroughly the next time you boot up your system to find out how to do this. Disabling the ability to boot from floppy drives and being able to set a password to access the BIOS features will improve the security of your system.

This will block unauthorized people from trying to boot your Linux system with a special boot disk and will protect you from people trying to change BIOS features like allowing boot from floppy drive or booting the server without prompt password. It is important to note that there is a possibility to bypass this security measure if someone has a physical access to your server since they can open the computer and unplug the BIOS battery. This will reset all features to their initial values.

Choose a right password

The starting point of our Linux General Security tour is the password. Many people keep their valuable information and files on a computer, and the only thing preventing others from seeing it is the eight-character string called a password. An unbreakable password, contrary to popular belief, does not exist. Given time and resources all passwords can be guessed either by social engineering or by brute force.

Social engineering of server passwords and other access methods are still the easiest and most popular way to gain access to accounts and servers. Often, something as simple as acting as a superior or executive in a company and yelling at the right person at the right time of the day yields terrific results.

Running a password cracker on a weekly basis on your system is a good idea. This helps to find and replace passwords that are easily guessed or weak. Also, a password checking mechanism should be present to reject a weak password when choosing an initial password or changing an old one. Character strings that are plain dictionary words, or are all in the same case, or do not contain numbers or special characters should not be accepted as a new password.

We recommend the following rules to make passwords effective:

  • They should be at least six characters in length, preferably eight characters including at least one numeral or special character.
  • They must not be trivial; a trivial password is one that is easy to guess and is usually based on the user's name, family, occupation or some other personal characteristic.
  • They should have an aging period, requiring a new password to be chosen within a specific time frame.
  • They should be revoked and reset after a limited number of concurrent incorrect retries.

The root account

The "root" account is the most privileged account on a Unix system. The "root" account has no security restrictions imposed upon it. This means the system assumes you know what you are doing, and will do exactly what you request -- no questions asked. Therefore it is easy, with a mistyped command, to wipe out crucial system files. When using this account it is important to be as careful as possible. For security reasons, never log in on your server as "root" unless it is absolutely an instance that necessitates root access. Also, if you are not on your server, never sign in and leave yourself on as "root"--this is VERY, VERY. VERY BAD.

Set login time out for the root account

Despite the notice to never, if they are not on the server, sign in as "root" and leave it unattended, administrators still stay on as "root" or forget to logout after finishing their work and leave their terminals unattended.

The answer to solve this problem is to make the bash shell automatically logout after not being used for a period of time. To do that, you must set the special variable of Linux named "TMOUT" to the time in seconds of no input before logout.

Edit your profile file (vi /etc/profile) and add the following line somewhere after the line that read "HISTSIZE=" on this file:

TMOUT=7200

The value we enter for the variable "TMOUT=" is in seconds and represents 2 hours (60 * 60 = 3600 * 2 = 7200 seconds). It is important to note that if you decide to put the above line in your /etc/profile file, then the automatic logout after two hours of inactivity will apply for all users on the system. So, instead, if your prefer to control which users will be automatically logged out and which ones are not, you can set this variable in their individual .bashrc file.

After this parameter has been set on your system, you must logout and login again (as root) for the change to take effect.

The /etc/exports file

If you are exporting file systems using the NFS service, be sure to configure the /etc/exports file with the most restrictive access possible. This means not using wildcards, not allowing root write access, and mounting read-only wherever possible.

Step 1

Edit the exports file (vi /etc/exports) and add:

As an example:

/dir/to/export host1.mydomain.com(ro,root_squash) 
/dir/to/export host2.mydomain.com(ro,root_squash)


Where /dir/to/export is the directory you want to export, host1.mydomain.com is the machine allowed to log in this directory, the <ro> option mean mounting read-only and the <root_squash> option for not allowing root write access in this directory.

Step 2

For this change to take effect you will need to run this command on your terminal:

[root@server ]# /usr/sbin/exportfs -a

WARNING: Please be aware that having an NFS service available on your system can be a security risk. Personally, I don't recommend using it. If you are follow our installation, the NFS service is not installed in your system.

The single-user login mode of Linux

Linux has a special command (linux single) also known as `single-user mode', which can be entered at the boot prompt during startup of the system. The single-user mode is generally used for system maintenance. You can boot Linux in single-user mode by typing at the LILO boot prompt the following command:

LILO: linux single

This will place the system in Run level 1 where you'll be logged in as the super-user 'root', and where you won't even have to type in a password!

Step 1

Requiring no password to boot into root under single-user mode is a bad idea! You can fix this by editing the inittab file (vi /etc/inittab) and change the following line:

id:3:initdefault:

To read:

id:3:initdefault: 
~~:S:wait:/sbin/sulogin

The addition of the above line will require to enter the root password before continuing to boot into single-user mode by making init (8) run the program sulogin (8) before dropping the machine into a root shell for maintenance.

Step 2

Now, for the change to take effect type in the following at a prompt:

[root@server /]# /sbin/init q

The LILO and /etc/lilo.conf file

LILO is the most commonly used boot loader for Linux. It manages the boot process and can boot Linux kernel images from floppy disks, hard disks or can even act as a "boot manager" for other operating systems.

LILO is very important in the Linux system and for this reason, we must protect it the best we can. The most important configuration file of LILO is the lilo.conf file, and it resides under the /etc directory. It is with this file that we can configure and improve the security of our LILO program and Linux system. Following are three important options that will improve the security of our valuable LILO program.

  • Adding: timeout=00
This option controls how long (in seconds) LILO waits for user input before booting to the default selection. One of the requirements of C2 security is that this interval be set to 0 unless the system dual boots something else.
  • Adding: restricted
This option asks for a password only, if parameters are specified on the command line (e.g. linux single). The option "restricted" can only be used together with the "password" option. Make sure you use this one on each additional image you may have.
  • Adding: password=<password>
This option asks the user for a password when trying to load the image. Actually the effect of using the password parameter in /etc/lilo.conf will protect the Linux image from booting. This means, it doesn't matter if you load Linux in single mode or if you just do a normal boot. It will always ask you for the password.

Now this can have a very bad effect, namely you are not able to reboot Linux remotely any more since it won't come up until you type in the root password at the console. It is for this reason that adding "restricted" with "password" is very important since the option "restricted" relaxes the password protection and a password is required only if parameters are specified at the LILO prompt, (e.g. single).

Passwords are always case-sensitive, also make sure the /etc/lilo.conf file is no longer world readable, or any user will be able to read the password. Here is an example of our protected LILO with the lilo.conf file.

Step 1

Edit the lilo.conf file (vi /etc/lilo.conf) and add or change the three options above as show:

boot=/dev/sda 
map=/boot/map 
install=/boot/boot.b 
prompt <- remove this line if you don't want to pass options at the LILO prompt. 
timeout=00 <- change this line to 00 to disable the LILO prompt. 
linear 
message=/boot/message <- remove this line if you don't want the welcome screem. 
default=linux 
restricted <- add this line to relaxes the password protection. 
password=<password> <- add this line and put your password. 
image=/boot/vmlinuz-2.4.2-2 
 label=linux 
 initrd=/boot/initrd-2.4.2-2.img 
 read-only 
 root=/dev/sda6

Step 2

Because the configuration file /etc/lilo.conf now contains unencrypted passwords, it should only be readable for the super-user "root".

To make the /etc/lilo.conf file readable only by the super-user "root", use the following command:

[root@server /]# chmod 600 /etc/lilo.conf (will be no longer world readable).

Step 3

Now we must update our configuration file /etc/lilo.conf for the change to take effect.

To update the /etc/lilo.conf file, use the following command:

[root@server /]# /sbin/lilo -v 
 LILO version 21.4-4, copyright  1992-1998 Wernerr Almesberger 
 `lba32' extentions copyright  1999,2000 John Coffman

  Reading boot sector from /dev/sda
  had : ATAPI 32X CD-ROM drive, 128kB Cache
  Merging with /boot/boot.b
  Mapping message file /boot/message
  Boot image : /boot/vmlinuz-2.2.16-22
  Mapping RAM disk /boot/initrd-2.2.16-22.img
  Added linux *
  /boot/boot.0800 exists  no backup copy made.
  Writing boot sector.

Step 4

One more security measure you can take to secure the lilo.conf file is to set it immutable, using the chattr command.

To set the file immutable simply, use the following command:

[root@server /]# chattr +i /etc/lilo.conf

And this will prevent any changes (accidental or otherwise) to the lilo.conf file. If you wish to modify the lilo.conf file you will need to unset the immutable flag:

To unset the immutable flag, use the following command:

[root@server /]# chattr -i /etc/lilo.conf

WARNING: When you use the password option, then LILO will always ask you for the password, regardless if you pass options at the LILO prompt (e.g. single) or not EXCEPT when you set the "restricted" option in /etc/lilo.conf.

The option "restricted" relaxes the password protection and a password is required only if parameters are specified at the LILO prompt, (e.g. single).

If you didn't had this option set "restricted", Linux will always ask you for the password and you will not be able to remotely reboot your system, therefore don't forget to add the option "restricted" with the option "password" into the /etc/lilo.conf file.

Disabling Ctrl-Alt-Delete keyboard shutdown command

Commenting out the line (with a "#") listed below in your /etc/inittab file will disable the possibility of using the Control-Alt-Delete command to shutdown your computer. This is pretty important if you don't have the best physical security to the machine.

Step 1

To do this, edit the inittab file (vi /etc/inittab) and change/comment the line:

ca::ctrlaltdel:/sbin/shutdown -t3 -r now 

To read:

#ca::ctrlaltdel:/sbin/shutdown -t3 -r now

Step 2

Now, for the change to take effect type in the following at a prompt:

[root@server /]# /sbin/init q


The /etc/services file

The port numbers on which certain "standard" services are offered are defined in the RFC 1700 "Assigned Numbers". The /etc/services file enables server and client programs to convert service names to these numbers (ports). The list is kept on each host and it is stored in the file /etc/services. Only the "root" user is allowed to make modifications to this file. It is rare to edit the /etc/services file. since it already contains the more common service names / port numbers. To improve security, we can set the immutable flag on this file to prevent unauthorized deletion or modification.

To immunize the /etc/services file, use the following command:

[root@server /]# chattr +i /etc/services


The /etc/securetty file

The /etc/securetty file allows you to specify which TTY and VC (virtual console) devices the "root" user is allowed to login on. The /etc/securetty file is read by the login program (usually /bin/login). Its format is a list of the tty and vc devices names allowed, and for all others that are commented out or do not appear in this file, root login is disallowed. Disable any tty and vc devices that you do not need by commenting them out (# at the beginning of the line) or by removing them.

Edit the securetty file (vi /etc/securetty) and comment out or remove the following lines:

vc/1     tty1 
#vc/2    #tty2
#vc/3    #tty3
#vc/4    #tty4
#vc/5    #tty5
#vc/6    #tty6
#vc/7    #tty7
#vc/8    #tty8
#vc/9    #tty9
#vc/10   #tty10
#vc/11   #tty11

Which means root is allowed to login on only tty1 and vc/1. This is my recommendation, allowing "root" to log in on only one tty or vc device and use the su command to switch to "root" if you need more devices to log in as "root".


Special accounts

It is important to DISABLE ALL default vendor accounts that you don't use on your system (some accounts exist by default even if you have not installed the related services on your server). This should be checked after each upgrade or new software installation. Linux provides these accounts for various system activities, which you may not need if the services are not installed on your server. If you do not need the accounts, remove them. The more accounts you have, the easier it is to access your system.

We assume that you are using the Shadow password suite on your Linux system. If you are not, you should consider doing so, as it helps to tighten up security somewhat. This is already set if you've followed our Linux installation procedure and selected, under the "Authentication Configuration", the option to "Enable Shadow Passwords" (see the chapter related to the "Installation of your Linux Server" for more information).

To delete user on your system, use the following command:

[root@server /]# userdel username

To delete group on your system, use the following command:

[root@server /]# groupdel username

Step 1

First we will remove all default vendor accounts into the /etc/passwd file that are unnecessary for the operation of the secure server configuration that we use in this book.

Type the following commands to delete all default users accounts listed below:

[root@server /]# userdel adm
[root@server /]# userdel lp
[root@server /]# userdel shutdown
[root@server /]# userdel halt
[root@server /]# userdel news
[root@server /]# userdel mail
[root@server /]# userdel uucp
[root@server /]# userdel operator
[root@server /]# userdel games
[root@server /]# userdel gopher
[root@server /]# userdel ftp

WARNING: By default, the userdel command will not delete a user's home directory. If you want the home directories of accounts to be deleted too, then add the -r option to the userdel command. Finally, the -r option must be used only when you have added a new user to the server and want to remove them. It doesn't need to be used for the removal of the above default users accounts. The user account called "mail" must be removed from the system only if you don't use Sendmail as your default Mail Server with mailx package. This user is related to mailx and not Sendmail.

Once the above list of users has been deleted from your Linux system, the /etc/passwd file will look like this:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
sync:x:5:0:sync:/sbin:/bin/sync
nobody:x:99:99:Nobody:/:

Step 2

After that we have removed all the unnecessary default vendor accounts into the /etc/passwd file from our system, we will remove all default vendor accounts into the /etc/group file.

Type the following commands to delete all default usersgroups accounts listed below:

[root@server /]# groupdel adm
[root@server /]# groupdel lp
[root@server /]# groupdel news
[root@server /]# groupdel mail
[root@server /]# groupdel uucp
[root@server /]# groupdel games
[root@server /]# groupdel dip

NOTE: The group account called "mail" must be removed from the system only if you don't use the mailx program for "mail". This is probably not what you want except if you use qmail.

Once the above list of group users has been deleted from your Linux system the /etc/group file will like this:

root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin
tty:x:5: disk:x:6:root
mem:x:8: kmem:x:9:
wheel:x:10:root
man:x:15:
nobody:x:99:
users:x:100:
floppy:x:19:
slocate:x:21:
utmp:x:22:

Step 3

Finally it is time to add the necessary and allowed users into the system:

To add a new user on your system, use the following command:

[root@server /]# useradd username

For example:

[root@server /]# useradd admin

To add or change password for user on your system, use the following command:

[root@server /]# passwd username

For example:

[root@server /]# passwd admin

The output should look something like this:

Changing password for user admin
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully


Step 4

The immutable bit can be used to prevent accidentally deleting or overwriting a file that must be protected. It also prevents someone from creating a symbolic link to this file, which has been the source of attacks involving the deletion of /etc/passwd, /etc/shadow, /etc/group or /etc/gshadow files.

To set the immutable bit on the passwords and groups files, use the following commands:

[root@server /]# chattr +i /etc/passwd
[root@server /]# chattr +i /etc/shadow
[root@server /]# chattr +i /etc/group
[root@server /]# chattr +i /etc/gshadow

WARNING: In the future, if you intend to add or delete users, passwords, usergroups, or group files, you must unset the immutable bit on all those files or you will not be able to make and update your changes. Also if you intend to install an RPM program that will automatically add a new user to the different immunized passwd and group files, then you will receive an error message during the install if you have not unset the immutable bit from those files.

To unset the immutable bit on the passwords and groups files, use the commands:

[root@server /]# chattr -i /etc/passwd
[root@server /]# chattr -i /etc/shadow
[root@server /]# chattr -i /etc/group
[root@server /]# chattr -i /etc/gshadow

Control mounting a file system

You can have more control on mounting file systems like /cache/, /home/ or /tmp/ partitions with some nifty options like noexec, nodev, and nosuid. This can be setup in the /etc/fstab text file. The fstab file contains descriptive information about the various file system mount options; each line addresses one file system. Information related to security options in the fstab text file are:

  • defaults - Allow everything (quota, read-write, and suid) on this partition.
  • noquota - Do not set users quotas on this partition.
  • nosuid - Do not set SUID/SGID access on this partition.
  • nodev - Do not set character or special devices access on this partition.
  • noexec - Do not set execution of any binaries on this partition.
  • quota - Allow users quotas on this partition.
  • ro - Allow read-only on this partition.
  • rw - Allow read-write on this partition.
  • suid - Allow SUID/SGID access on this partition.

NOTE: For more information on options that you can set in this file (fstab), see the man pages about mount (8).


Step 1

Edit the fstab file (vi /etc/fstab) and change it depending on your needs.

For example change:

LABEL=/cache /cache ext2 defaults 1 2 
LABEL=/home  /home  ext2 defaults 1 2 
LABEL=/tmp   /tmp   ext2 defaults 1 2

To read:

LABEL=/cache /cache ext2 defaults,nodev 1 2 
LABEL=/home  /home  ext2 defaults,nosuid 1 2 
LABEL=/tmp   /tmp   ext2 defaults,nosuid,noexec 1 2

Meaning, <nosuid>, do not allow set-user-identifier or set-group-identifier bits to take effect, <nodev>, do not interpret character or block special devices on this file system partition, and <noexec>, do not allow execution of any binaries on the mounted file system.

Step 2

Once you have made the necessary adjustments to the /etc/fstab file, it is time to inform the Linux system about the modifications.

This can be accomplished with the following commands:

[root@server /]# mount /cache -oremount 
[root@server /]# mount /home -oremount 
[root@server /]# mount /tmp -oremount

Each file system that has been modified must be remounted with the command show above. In our example we have modified the /cache, /home, and /tmp file system and it is for this reason that we remount these files systems with the above commands.

You can verify if the modifications have been correctly applied to the Linux system with the following command:

[root@server /]# cat /proc/mounts
/dev/root /      ext2 rw 0 0 
/proc /proc      proc rw 0 0 
/dev/sda1        /boot     ext2  rw 0 0
/dev/sda10       /cache    ext2  rw,nodev 0 0
/dev/sda9        /chroot   ext2  rw 0 0
/dev/sda8        /home     ext2  rw,nosuid 0 0
/dev/sda13       /tmp      ext2  rw,noexec,nosuid 0 0
/dev/sda7        /usr      ext2  rw 0 0 
/dev/sda11       /var      ext2  rw 0 0 
/dev/sda12       /var/lib  ext2  rw 0 0
none /dev/pts  devpts  rw 0 0

This command will show you all the files systems on your Linux server with parameters applied to them.

Mounting the /boot directory of Linux as read-only

The /boot directory is where the Linux kernel and some of its related files are kept. On many Linux variants this directory resides in its own partition and the default parameter is to mount it as read-write. We can change this parameter to make it read-only for better security.

Mounting the /boot partition as read-only eliminates possible problems that someone may try to change or modify vital files inside it. To mount the /boot file system of Linux as read-only, follow the simple steps below.

Step 1

Edit the fstab file (vi /etc/fstab) and change the line:

LABEL=/boot /boot ext2 defaults 12

To read:

LABEL=/boot /boot ext2 defaults,ro 12 

We add the "ro" option to this line to specify to mount this partition as read-only.

Step 2

Make the Linux system aware about the modification you have made to the /etc/fstab file.

This can be accomplished with the following command:

[root@server /]# mount /boot -oremount

Then test your results with the following command:

[root@server /]# cat /proc/mounts 
/dev/root /      ext2 rw 0 0 
/proc /proc      proc rw 0 0 
/dev/sda1        /boot     ext2  ro 0 0
/dev/sda10       /cache    ext2  rw,nodev 0 0
/dev/sda9        /chroot   ext2  rw 0 0
/dev/sda8        /home     ext2  rw,nosuid 0 0
/dev/sda13       /tmp      ext2  rw,noexec,nosuid 0 0
/dev/sda7        /usr      ext2  rw 0 0 
/dev/sda11       /var      ext2  rw 0 0 
/dev/sda12       /var/lib  ext2  rw 0 0
none /dev/pts  devpts  rw 0 0

If you see something like: /dev/sda1 /boot ext2 ro 0 0, congratulations!

WARNING: If in the future you want to upgrade your Linux kernel, it is important to reset the modification you have made to the /boot directory to its initial state (read-write) or you will not be able to install the new kernel because the /boot partition is set as read-only. All you have to do if you want to put the /boot partition to its original state is to edit the /etc/fstab file again and remove the "ro" option then remount the /boot file system with the "mount -oremount" command again.


Conceal binary RPM

Once you have installed all the software that you need on your Linux server with the RPM command, it's a good idea to move it to a safe place like a floppy disk or other safe place of your choice. With this method if someone accesses your server and has the intention to install nasty software with the RPM command, he wouldn't be able to. Of course, if in the future you want to install or upgrade new software via RPM, all you have to do is to replace the RPM binary to its original directory again.

To move the RPM binary on the floppy disk, use the command:

[root@server /]# mount /dev/fd0H1440 /mnt/floppy/ 
[root@server /]# mv /bin/rpm /mnt/floppy/ 
[root@server /]# umount /mnt/floppy/


WARNING: Never uninstall the RPM program completely from your system or you will be unable to reinstall it again later, since to install RPM or other software you need to have RPM commands available.

One more thing you can do is change the default permission of the "rpm" command from 755 to 700. With this modification, non-root users can't use the "rpm" program to query, install etc; in case you forget to move it to a safe place after installation of new programs.

To change the default permission of /bin/rpm, use the command:

[root@server /]# chmod 700 /bin/rpm


Shell logging

To make it easy for you to repeat long commands, the bash shell stores up to 500 old commands in the ~/.bash_history file (where "~/" is your home directory). Each user that has an account on the system will have this file .bash_history in their home directory. Reducing the number of old commands the .bash_history files can hold may protect users on the server who enter by mistake their password on the screen in plain text and have their password stored for a long time in the .bash_history file.

Step 1

The HISTSIZE line in the /etc/profile file determine the size of old commands the .bash_history file for all users on your system can hold. For all accounts I would highly recommend setting the HISTSIZE in /etc/profile file to a low value such as 10.

Edit the profile file (vi /etc/profile) and change the line:

HISTSIZE=1000

To read:

HISTSIZE=10

Which means, the .bash_history file in each users home directory can store 10 old commands and no more. Now, if a cracker tries to see the ~/.bash_history file of users on your server to find some password typed by mistake in plain text, he or she has less chance to find one.


Step 2

The administrator should also add into the /etc/profile file the "HISTFILESIZE=0" line, so that each time a user logs out, its .bash_history file will be deleted so crackers will not be able to use .bash_history file of users who are not presently logged into the system.

Edit the profile file (vi /etc/profile) and add the following parameter below the "HISTSIZE=" line:

HISTFILESIZE=0

After this parameter has been set on your system, you must logout and login again (as root) for the change to take effect.


Physical hard copies of all-important logs

One of the most important security considerations is the integrity of the different log files under the /var/log/ directory on your server. If despite each of the security functions put in place on our server, a cracker can gain access to it, our last defense is the log file system, so it is very important to consider a method of being sure of the integrity of our log files.

If you have a printer installed on your server, or on a machine on your network, a good idea would be to have actual physical hard copies of all-important logs. This can be easily accomplished by using a continuous feed printer and having the syslog program sending all logs you seem important out to /dev/lp0 (the printer device). Cracker can change the files, programs, etc on your server, but can do nothing when you have a printer that prints a real paper copy of all of your important logs.

As an example:

For logging of all telnet, mail, boot messages and ssh connections from your server to the printer attached to THIS server, you would want to add the following line to the /etc/syslog.conf file:

Step 1

Edit the syslog.conf file (vi /etc/syslog.conf) and add at the end of this file the following line:

authpriv.*;mail.*;local7.*;auth.*;daemon.info /dev/lp0

Step 2

Now restart your syslog daemon for the change to take effect:

[root@server /]# /etc/rc.d/init.d/syslog restart
Shutting down kernel logger: [OK]
Shutting down system logger: [OK]
Starting system logger: [OK]
Starting kernel logger: [OK]

As an example:

For logging of all telnet, mail, boot messages and ssh connections from your server to the printer attached to a REMOTE server in your local network, then you would want to add the following line to /etc/syslog.conf file on the REMOTE server.

Step 1

Edit the syslog.conf file (vi /etc/syslog.conf) on the REMOTE server (for example: printer.openna.com) and add at the end of this file the following line:

authpriv.*;mail.*;local7.*;auth.*;daemon.info /dev/lp0

If you don't have a printer in your network, you can also copy all the log files to another machine; simply omit the above first step of adding /dev/lp0 to your syslog.conf file on remote and go directly to the "-r" option second step on remote. Using the feature of copying all the log files to another machine will give you the possibility to control all syslog messages on one host and will tear down administration needs.

Step 2

Since the default configuration of the syslog daemon is to not receive any messages from the network, we must enable on the REMOTE server the facility to receive messages from the network. To enable the facility to receive messages from the network on the REMOTE server, add the following option "-r" to your syslog daemon script file (only on the REMOTE host):

Edit the syslog daemon (vi +24 /etc/rc.d/init.d/syslog) and change:

daemon syslogd -m 0 

To read:

daemon syslogd -r -m 0

Step 3

Restart your syslog daemon on the remote host for the change to take effect:

[root@syslogsvr /]# /etc/rc.d/init.d/syslog restart
Shutting down kernel logger: [OK]
Shutting down system logger: [OK]
Starting system logger: [OK]
Starting kernel logger: [OK]

Step 4

If we have a firewall on the REMOTE server (you are supposed to have one), we must add or verify the existence of the following lines:

# SYSLOG server (514) 
# ----------------
# Provides full remote logging. Using this feature you're able to 
# control all syslog messages on one host.
iptables -A INPUT -i $EXTERNAL_INTERFACE -p udp \
         -s $SYSLOG_CLIENT --source-port $UNPRIVPORTS \
         -d $IPADDR --destination-port 514 -j ACCEPT
  • Where EXTERNAL_INTERFACE="eth0" # Internet or Internal connected interface
  • Where IPADDR="208.164.186.10" # Your IP address
  • Where SYSLOG_CLIENT="208.164.168.0/24" # Your syslog clients IP ranges

Step 5

Now restart your firewall on the remote host for the change to take effect:

[root@printer /]# /etc/rc.d/init.d/iptables restart
Shutting Firewalling Services: [OK]
Starting Firewalling Services: [OK]

This firewall rule will allow incoming UDP packets on port 514 (syslog port) on the remote server that comes from our internal client to be accepted. For more information on Firewalls see the chapter relating to network firewalls.

Step 6

Edit the syslog.conf file (vi /etc/syslog.conf) on the LOCAL server, and add at the end of this file the following line:

authpriv.*;mail.*;local7.*;auth.*;daemon.info @printer

Where "printer" is the hostname of the REMOTE server. Now if anyone ever hacks your machine and attempts to erase vital system logs, you still have a hard copy of everything. It should then be fairly simple to trace where they came from and deal with it accordingly.

Step 7

Restart your syslog daemon on the LOCAL server for the change to take effect:

[root@server /]# /etc/rc.d/init.d/syslog restart
Shutting down kernel logger: [OK]
Shutting down system logger: [OK]
Starting system logger: [OK]
Starting kernel logger: [OK]

Step 8

Same as on the REMOTE host, we must add or verify the existence of the following lines in our firewall script file on the LOCAL host:

# SYSLOG client (514) 
# ----------------
iptables -A OUTPUT -o $EXTERNAL_INTERFACE -p udp \
         -s $IPADDR --source-port 514 \ -d $SYSLOG_SERVER --destination-port $UNPRIVPORTS -j ACCEPT
  • Where EXTERNAL_INTERFACE="eth0" # Internet or Internal connected interface
  • Where IPADDR="208.164.186.1" # Your IP address
  • Where SYSLOG_SERVER="printer.openna.com" # Your Printer Server in our example

Step 9

Finally restart your firewall on the LOCAL host for the change to take effect:

[root@server /]# /etc/rc.d/init.d/iptables restart Shutting Firewalling Services: [OK] Starting Firewalling Services: [OK]

This firewall rule will allow outgoing UDP packets on unprivileged ports on the local server destined to the remote syslog server to be accepted. Repeat step 6 through steps 9 for each additional server you may have and want all-important logs to be logged on remote printer server.

WARNING: Never use your Gateway Server as a host to control all syslog messages; this is a very bad idea. More options and strategies exist with the sysklogd program, see the man pages about sysklogd (8), syslog(2), and syslog.conf(5) for more information.

Tighten scripts under /etc/rc.d/init.d/

Fix the permissions of the script files that are responsible for starting and stopping all your normal processes that need to run at boot time.

To fix the permissions of those files, use the following command:

[root@server /]# chmod -R 700 /etc/init.d/*

Which means just the super-user "root" is allowed to Read, Write, and Execute scripts files on this directory. I don't think regular users need to know what's inside those script files.

WARNING: If you install a new program or update a program that use the init system V script located under /etc/rc.d/init.d/ directory, don't forget to change or verify the permission of this script file again.


The /etc/rc.local file

By default, when you login to a Linux machine, it tells you the Linux distribution name, version, kernel version, and the name of the server. This is giving away too much info. We'd rather just prompt users with a "Login:" prompt.

Step 1

To do this, edit the rc.local file (vi /etc/rc.local) and place "#" in front of the following lines as shown:

--
# This will overwrite /etc/issue at every boot. So, make any changes you 
# want to make to /etc/issue here or you will lose them when you reboot. 
#echo "" > /etc/issue 
#echo "$R" >> /etc/issue 
#echo "Kernel $(uname -r) on $a $(uname -m)" >> /etc/issue 
# 
#cp -f /etc/issue /etc/issue.net 
#echo >> /etc/issue 
--


Step 2

Then, remove the following files: issue.net and issue under /etc/ directory:

[root@server /]# rm -f /etc/issue
[root@server /]# rm -f /etc/issue.net

WARNING: The /etc/issue.net file is the login banner that users will see when they make a networked (i.e. telnet, SSH) connection to your machine. You will find it in the /etc directory, along with a similar file called issue, which is the login banner that gets displayed to local users.

It is simply a text file and can be customized to your own tastes, but be aware that as noted above, if you do change it or remove it like we do, you'll also need to modify the /etc/rc.d/rc.local shell script, which re-creates both the issue and issue.net files every time the system boots.


Bits from root-owned programs

A regular user will be able to run a program as root if it is set to SUID root. All programs and files on your computer with the 's' bits appearing on its mode, have the SUID (-rwsr-xr-x) or SGID (-r-xr-sr-x) bit enabled. Because these programs grant special privileges to the user who is executing them, it is important to remove the 's' bits from root-owned programs that won't absolutely require such privilege. This can be accomplished by executing the command chmod a-s with the name(s) of the SUID/SGID files as its arguments.

Such programs include, but aren't limited to:

  • Programs you never use.
  • Programs that you don't want any non-root users to run.
  • Programs you use occasionally, and don't mind having to su (1) to root to run.

We've placed an asterisk (*) next to each program we personally might disable and consider to be not absolutely required for the duty work of the server. Remember that your system needs some suid root programs to work properly, so be careful.

Step 1

To find all files with the `s' bits from root-owned programs, use the command:

[root@server ]# find / -type f \( -perm -04000 -o -perm -02000 \) -exec ls l {} \;
* /usr/bin/chage 
* /usr/bin/gpasswd 
/usr/bin/man 
/usr/bin/passwd 
/usr/bin/suidperl 
/usr/bin/sperl5.6.0 
/usr/bin/slocate 
* /usr/bin/wall 
* /usr/bin/chfn 
* /usr/bin/chsh 
* /usr/bin/newgrp 
* /usr/bin/write 
* /usr/sbin/usernetctl 
/usr/sbin/utempter 
* /bin/ping 
/bin/su 
* /bin/mount 
* /bin/umount 
* /sbin/netreport 
/sbin/pwdb_chkpwd 
/sbin/unix_chkpwd 


Step 2

To disable the suid bits on selected programs above, type the following commands:

[root@server /]# chmod a-s /usr/bin/chage 
[root@server /]# chmod a-s /usr/bin/gpasswd 
[root@server /]# chmod a-s /usr/bin/wall 
[root@server /]# chmod a-s /usr/bin/chfn 
[root@server /]# chmod a-s /usr/bin/chsh 
[root@server /]# chmod a-s /usr/bin/newgrp 
[root@server /]# chmod a-s /usr/bin/write 
[root@server /]# chmod a-s /usr/sbin/usernetctl 
[root@server /]# chmod a-s /bin/ping 
[root@server /]# chmod a-s /bin/mount 
[root@server /]# chmod a-s /bin/umount 
[root@server /]# chmod a-s /sbin/netreport

If you want to know what those programs do, type "man program-name" and read the man page.

As an example:

To read the netreport man page, use the following command:

[root@server /]# man netreport

Finding all files with the SUID/SGID bit enabled

All SUID and SGID files that still exist on your system after we have removed those that won't absolutely require such privilege are a potential security risk, and should be monitored closely. Because these programs grant special privileges to the user who is executing them, it is necessary to ensure that insecure programs are not installed.

A favorite trick of crackers is to exploit SUID "root" programs, and leave a SUID program as a backdoor to get in the next time. Find all SUID and SGID programs on your system, and keep track of what they are so that you are aware of any changes, which could indicate a potential intruder.

Use the following command to find all SUID/SGID programs on your system:

[root@server /]# find / -type f \( -perm -04000 -o -perm -02000 \) -exec ls -l {} \;

When you have, for example, the home directories of the users accounts mountable on all servers, then this find command will check the same home directory on every server (SUIDs on mounted file systems are not effective). If there are more mounted file systems on the servers, then this can take some time which actually a waste of time.

In this case, you can avoid this by executing the following command (see '-fstype'):

[root@server /]# find / \( ! -fstype nfs -o -prune \) -type f \( -perm 04000 -o -perm -02000 \) -exec ls -l {} \;

NOTE: See the software named "sXid" that will do the job for you automatically each day and report the results via mail.


Don't let internal machines tell the server what their MAC address is

To avoid the risk that a user could easily change a computers IP address and appear as someone else to the firewall, you can force the ARP cache entries of Linux using the arp command utility. A special option can be used with the arp utility to avoid letting INTERNAL machines tell the server what their MAC (Media Access Control) address is and the IP address associated with it. ARP is a small utility, which manipulates the kernel's ARP (Address Resolution Protocol) cache. Through all possible options associated with this utility, the primary one is clearing an address mapping entry and manually setting up one. In the hope to more secure our server from the INTERNAL, we will manually set MAC address (sometimes called Hardware addresses) of all know computers in our network statically by using static ARP entries.

Step 1

For each IP address of INTERNAL computers in your network, use the following command to know the MAC address associate with the IP address:

[root@server /]# ifconfig 

The MAC (Media Access Control) address will be the letters and numbers that come after "HWaddr" (the Hardware Address). In the above example our MAC address are: 00:50:DA:C6:D3:FF for the interface eth0 and 00:50:DA:C6:D3:09 for the interface eth1.

Step 2

Once we know the MAC (Media Access Control) address associated with IP address, we can add them manually to the ARP entries of the Linux server.

To add manually MAC address to ARP entries, use the following command:

[root@server /]# arp -s 207.35.78.3 00:50:DA:C6:D3:FF 
[root@server /]# arp -s 192.168.1.11 00:50:DA:C6:D3:09

The "-s" option means to manually create an ARP address mapping entry for host hostname with hardware address set to hw_addr class. You can add you ARP commands to the /etc/rc.d/rc.local file if you want to keep your configuration if the system reboot.

Step 3

To verify if the modifications have been added to the system, use the following command:

[root@server /]# arp 
  Address      Hwtype  Hwaddress          Flags Mask  Iface
  207.35.78.3  ether   00:20:78:13:86:92  CM          eth1
  192.168.1.11 ether   00:E0:18:90:1B:56  CM          eth1

WARNING: If you receive error message like: SIOCSARP: Invalid argument, it is because the MAC (Media Access Control) address you want to add is the one of your server. You must add only MAC address of INTERNAL computers in your private network. This hack doesn't apply to external node on the Internet.


You can now be reassured that someone will not change the system's IP address of an INTERNAL system and get through. If they do change the IP address, the server simply won't talk to them. With the new iptables tool of Linux, which replace the old ipchains utility for packet filter administration and firewall setup, MAC addresses can be filtered and configured in the firewall rules too.


Unusual or hidden files

It is important to look everywhere on the system for unusual or hidden files (files that start with a period and are normally not shown by the "ls" command), as these can be used to hide tools and information (password cracking programs, password files from other systems, etc.). A common technique on UNIX systems is to put a hidden directory or file in a user's account with an unusual name, something like '...' or '.. ' (dot dot space) or '..^G' (dot dot control-G). The find program can be used to look for hidden files.

To look for hidden files, use the following commands:

[root@server /]# find / -name ".. " -print -xdev 
[root@server /]# find / -name ".*" -print -xdev | cat -v

WARNING: Files with names such as '.xx' and '.mail' have been used (that is, files that might appear to be normal).



Finding Group and World Writable files and directories

Group and world writable files and directories, particularly system files (partions), can be a security hole if a cracker gains access to your system and modifies them. Additionally, worldwritable directories are dangerous, since they allow a cracker to add or delete files as he or she wishes in these directories. In the normal course of operation, several files will be writable, including some from the /dev/, /var/catman/ directories, and all symbolic links on your system.

To locate all group & world-writable files on your system, use the command:

[root@server /]# find / -type f \( -perm -2 -o -perm -20 \) -exec ls -lg {} \;

To locate all group & world-writable directories on your system, use the command:

[root@server /]# find / -type d \( -perm -2 -o -perm -20 \) -exec ls -ldg {} \;

WARNING: A file and directory integrity checker like "Tripwire" software can be used regularly to scan, manage and find modified group or world writable files and directories easily. See later in this book the chapter related to "Securities Software - System Integrity" for more information about Tripwire.



Unowned Files

Don't permit any unowned file. Unowned files may also be an indication that an intruder has accessed your system. If you find unowned file or directory on your system, verify its integrity, and if all looks fine, give it an owner name. Some time you may uninstall a program and get an unowned file or directory related to this software; in this case you can remove the file or directory safely.

To locate files on your system that do not have an owner, use the following command:

[root@server /]# find / -nouser -o -nogroup

WARNING: It is important to note that files reported under /dev/ directory don't count.


Finding .rhosts files

Finding all existing .rhosts files that could exist on your server should be a part of your regular system administration duties, as these files should not be permitted on your system. Remember that a cracker only needs one insecure account to potentially gain access to your entire network.

Step 1

You can locate all existing .rhosts files on your system with the following command:

[root@server /]# find /home -name .rhosts

If the result returns nothing, then you are safe and your system contain no .rhosts files in the /home/ directory at this time. If you are doing a new install of Linux (like we did), you should not have any .rhosts files on your system.

Step 2

You can also use a cron job to periodically check for, report the contents of, and delete $HOME/.rhosts files. Also, users should be made aware that you regularly perform this type of audit, as directed by your security policy.

To use a cron job to periodically check and report via mail all .rhosts files, create as "root" the find_rhosts_files script file under /etc/cron.daily/ directory (touch /etc/cron.daily/find_rhosts_files) and add the following lines in this script:

#!/bin/sh 
/usr/bin/find /home -name .rhosts | (cat <<EOF
This is an automated report of possible existent ".rhosts" files on the server
deep.openna.com, generated by the find utility command.

New detected ".rhosts" files under the "/home/" directory include: 
EOF
cat
) | /bin/mail -s "Content of .rhosts file audit report" root


Now make this script executable, verify the owner, and change the group to "root".

[root@server /]# chmod 755 /etc/cron.daily/find_rhosts_files 
[root@server /]# chown 0.0 /etc/cron.daily/find_rhosts_files

Each day mail will be sent to "root" with a subject:" Content of .rhosts file audit report" containing potential new .rhosts files.


Linux Pluggable Authentication Modules

The Pluggable Authentication Modules (PAM) consists of shared libraries, which enable administrators to choose how applications authenticate users.

Basically, PAM enables the separation of authentication schemes from the applications. This is accomplished by providing a library of functions that applications can use for requesting user authentications. ssh, pop, imap, etc. are PAM-aware applications, hence these applications can be changed from providing a password to providing a voice sample or fingerprint by simply changing the PAM modules without having to rewrite any code in these applications.

The configuration files of the PAM modules are located in the directory /etc/pam.d and the modules (shared libraries) themselves are located in the directory /lib/security. The /etc/pam.d directory has a collection of named files of its own, e.g. ssh, pop, imap, etc. PAMaware applications that do not have a configuration file will automatically be pointed to the default configuration file 'other'. The following contain the minimum-security restrictions using PAM.

The password length

The minimum acceptable password length by default when you install your Linux system is 5. This means that when a new user is given access to the server, his/her password length will be at minimum 5 mixes of character strings, letter, number, special character etc. This is not enough and must be 8 or more. The password length under Linux by the use of its PAM feature is controlled by 5 arguments minlen, dcredit, ucredit, lcredit, and ocredit.

Step 1

To prevent non-security-minded people or administrators from being able to enter just 5 characters for the valuable password, edit the rather important /etc/pam.d/passwd file and enforce the minimum password length.

Edit the passwd file (vi /etc/pam.d/passwd) and remove the following line:

password required /lib/security/pam_stack.so service=system-auth

Step 2

Once the above line has been removed from the passwd file, we must remove the following three lines as shown below from the system-auth file. This is a bug in the PAM RPM package of Red Hat that we must correct here to be able to use this feature with Linux.

Edit the system-auth file (vi /etc/pam.d/system-auth) and remove the lines:

password  required   /lib/security/pam_cracklib.so retry=3 
password  sufficient /lib/security/pam_unix.so nullok use_authtok md5 shadow 
password  required   /lib/security/pam_deny.so

Step 3

Now add the following lines to /etc/pam.d/passwd. We use the PAM "pam_cracklib" module here with the argument "minlen" to enforce the password length.

password  required   /lib/security/pam_cracklib.so retry=3 minlen=12 
password  sufficient /lib/security/pam_unix.so nullok use_authtok md5 shadow
password  required   /lib/security/pam_deny.so

After adding the above lines, the /etc/pam.d/passwd file should look like this:

#%PAM-1.0  
auth      required   /lib/security/pam_stack.so service=system-auth 
account   required   /lib/security/pam_stack.so service=system-auth 
password  required   /lib/security/pam_cracklib.so retry=3 minlen=12 
password  sufficient /lib/security/pam_unix.so nullok use_authtok md5 shadow
password  required   /lib/security/pam_deny.so

And the /etc/pam.d/system-auth file should look like this:

#%PAM-1.0 
# This file is auto-generated. 
# User changes will be destroyed the next time authconfig is run. 
auth required /lib/security/pam_env.so 
auth sufficient /lib/security/pam_unix.so likeauth nullok 
auth required /lib/security/pam_deny.so 
account required /lib/security/pam_unix.so 
session required /lib/security/pam_limits.so 
session required /lib/security/pam_unix.so

WARNING: It is important to note that when you set the password for a user under `root', then these restrictions don't apply!! This is the case on all Unix OS. The user `root' can override pretty much everything. Instead, log as the user account from which you apply this restriction and try to change the password. You will see that it works.

You need to keep in mind that this module includes a credit mechanism. E.g. if you define minlen=12, then you will get 1 credit for e.g. including a single digit number in your password, or for including a non-alphanumeric character. Getting 1 credit means that the module will accept a password of the length of minlen-credit. When you check the parameters of the cracklib module, you will see that it has some parameters that let you define what a credit is (http://www.us.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html).

For example:

minlen    The following password was accepted
--------  --------------------------------------------------
 14        gjtodgsdf1$

You can see that I got 1 credit for a alphanumeric character and a credit for each nonalphanumeric character. "gjtodgsdf1$" has a length of 11, 1 credit for alpha-numeric, 2 credits for non-alphanumeric character (1 and $) which gives me a credit of 3, hence the password length of 14 was accepted.

At any rate, the minimum length is adjusted by the mixture of types of characters used in the password. Using digits (up to the number specified with the "dcredit=" parameter, which defaults to 1) or uppercase letters "ucredit" or lowercase letters "lcredit" or other types of letters "ocredit" will decrease the minimum length by up to four since the default parameter for these arguments is 1 and there is four different arguments that you can add.

A password with 9 lowercase letters in it will pass a minimum length set to 10 unless "lcredit=0" is used, because a credit is granted for the use of a lowercase letter. If the mixture includes an uppercase letter, a lowercase letter, and a digit, then a minlength of 8 effectively becomes 5.

NOTE: With the new MD5 passwords capability, which is installed by default in all modern Linux operating system, a long password can be used now (up to 256 characters), instead of the Unix standard eight letters or less. If you want to change the password length of 8 characters to example 16 characters, all you have to do is to replace the number 12 by 20 in the "minlen=12" line of the /etc/pam.d/passwd file.

Disabling console program access

In a safe environment, where we are sure that console is secured because passwords for BIOS and LILO are set and all physical power and reset switches on the system are disabled, it may be advantageous to entirely disable all console-equivalent access to programs like shutdown, reboot, and halt for regular users on your server.

To do this, run the following command:

 rm -f /etc/security/console.apps/<servicename>

Where <servicename> is the name of the program to which you wish to disable consoleequivalent access. Unless you use xdm, however, be careful to not remove the xserver file or no one but only `root' will be able to start the X server. (If you always use xdm to start the X server, `root' is the only user that needs to start X, in which case you might actually want to remove the xserver file).

To disable console program access, use the following commands:

[root@server /]# rm -f /etc/security/console.apps/halt 
[root@server /]# rm -f /etc/security/console.apps/poweroff 
[root@server /]# rm -f /etc/security/console.apps/reboot 
[root@server /]# rm -f /etc/security/console.apps/shutdown 
[root@server /]# rm -f /etc/security/console.apps/xserver (if removed, root will be the only user able to start X).

This will disable console-equivalent access to programs halt, poweroff, reboot, and shutdown. Once again, the program xserver applies only if you installed the Xwindow interface on your system.

WARNING: If you are following our setup installation, the Xwindow interface is not installed on your server and all the files described above will not appear in the /etc/security/console.apps directory, so don't pay attention to the above step.

Disabling all console access

The Linux-PAM library installed by default on your system allows the system administrator to choose how applications authenticate users, such as for console access, program and file access. In order to disable all these accesses for the users, you must comment out all lines that refer to pam_console.so in the /etc/pam.d directory. This step is a continuation of the hack "Disabling console program access". The following script will do the trick automatically for you.

Step 1

As `root' creates the disabling.sh script file (touch disabling.sh) and add the following lines inside:

#!/bin/sh 
cd /etc/pam.d 
for i in * ; do 
sed '/[^#].*pam_console.so/s/^/#/' < $i > foo && mv foo $i 
done

Step 2

Make this script executable with the following command and execute it:

[root@server /]# chmod 700 disabling.sh 
[root@server /]# ./disabling.sh

This will comment out all lines that refer to pam_console.so for all files located under /etc/pam.d directory. Once the script has been executed, you can remove it from your system.

The Login access control table

On a server environment where authorized and legitimate logins can come from everywhere, it is important to have the possibility to use a security file which allow us to have more control over users who can connect to the server. What we are looking here is to have more control on not allowing some legitimated accounts to login from anywhere. Fortunately, this file exists and is called "access.conf", you can find it under your /etc/security directory.

The access.conf file which comes already installed with your native Linux system allow us to control which authorized users can/cannot log in to the server or to the console and from where. Don't forget that users access can come everywhere from remote host or directly from the console of the system. Configuration of the access.conf file of Linux is not complicated to understand. Below I show you how to configure it to be very restrictive and secure.

Step 1

By default denying access to every one, is the first step of a reliable security policy. In this way we eliminate the possibility of forgetting someone or to making a mistake.

Edit the access.conf file (vi /etc/security/access.conf) and add the following line at the end of the file.

-:ALL EXCEPT root smcnaught:ALL

This access policy means to disallow console logins as well as remote accounts login to all from anywhere except for user `root' and `smcnaught'. With this choice of policy, we deny nonnetworked and remote logins to every user with a shell account on the system from everywhere and allow only the selected users.

Take a note that many possibilities exist as for example allowing the same users `root' and `smcnaught' to log only to the system from remote host with IP address 206.35.78.2. To enable this policy, all we need to do is to change the above policy to this one:

Edit the access.conf file (vi /etc/security/access.conf) and add the following lines at the end of the file.

-:ALL EXCEPT root smcnaught:206.35.78.2 
-:ALL:LOCAL

Here the second policy line means to disallow all local access to the console for every users even for the super-user `root', therefore if you want to log as `root' you need first to log as user `smcnaught' from remote host with IP address 206.35.78.2 and su to `root' (this is why I added `root' to the users allowed to connect from remote host 206.35.78.2).

Step 2

To be able to use the access.conf feature of Linux, make sure to add the following line to /etc/pam.d/login and sshd if you use this service or it will not work.

Edit the login file (vi /etc/pam.d/login) and add the following line.

account required /lib/security/pam_access.so

After adding the above line, the /etc/pam.d/login file should look like this:

#%PAM-1.0 
auth      required  /lib/security/pam_securetty.so 
auth      required  /lib/security/pam_stack.so service=system-auth 
auth      required  /lib/security/pam_nologin.so 
account   required  /lib/security/pam_stack.so service=system-auth 
account   required  /lib/security/pam_access.so 
password  required  /lib/security/pam_stack.so service=system-auth 
session   required  /lib/security/pam_stack.so service=system-auth

NOTE: Please read information about possible configurations of this file inside the access.conf file since your policies will certainly differ from the example that I show you above.


Tighten console permissions for privileged users

The console.perms security file of Linux, which use the pam_console.so module to operate, is designed to give to privileged users at the physical console (virtual terminals and local xdmmanaged X sessions) capabilities that they would not otherwise have, and to take those capabilities away when they are no longer logged in at the console.

It provides two main kinds of capabilities: file permissions and authentication. When a user logs in at the console and no other user is currently logged in at the console, the pam_console.so module will change permissions and ownership of files as described in the file /etc/security/console.perms.

Please note that privileged users are nothing in common with regular users you may add to the server, they are special users like floppy, cdrom, scanner, etc which in an networking server environment are also considered and treated as users.

Step 1

The default console.perms configuration file of Linux is secure enough for regular use of the system where an Xwindow interface is considered to be installed but in a highly secure environment where the Graphical User Interface (GUI) is not installed or where some special devices like sound, jaz, etc have no reason to exist, we can tighten the console.perms security file of Linux to be more secure by eliminating non-existent or unneeded privileged users to have capabilities that they would not otherwise have.

Edit the console.perms file (vi /etc/security/console.perms), and change the default lines inside this file:

# file classes -- these are regular expressions 
<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
<xconsole>=:[0-9]\.[0-9] :[0-9] 

# device classes -- these are shell-style globs 
<floppy>=/dev/fd[0-1]* 
<sound>=/dev/dsp* /dev/audio* /dev/midi* \
        /dev/mixer* /dev/sequencer 
<cdrom>=/dev/cdrom* /dev/cdwriter* 
<pilot>=/dev/pilot 
<jaz>=/dev/jaz 
<zip>=/dev/zip 
<scanner>=/dev/scanner 
<fb>=/dev/fb /dev/fb[0-9]* 
<kbd>=/dev/kbd 
<joystick>=/dev/js* 
<v4l>=/dev/video* /dev/radio* /dev/winradio* /dev/vtx* /dev/vbi* 
<gpm>=/dev/gpmctl 
<dri>=/dev/dri/* /dev/nvidia* 

# permission definitions 
<console>  0660 <floppy>     0660 root.floppy
<console>  0600 <sound>      0640 root.sys
<console>  0600 <cdrom>      0600 root.disk
<console>  0600 <pilot>      0660 root.tty
<console>  0600 <jaz>        0660 root.disk
<console>  0600 <zip>        0660 root.disk
<console>  0600 <scanner>    0600 root
<console>  0600 <fb>         0600 root
<console>  0600 <kbd>        0600 root
<console>  0600 <joystick>   0600 root 
<console>  0600 <v4l>        0600 root
<console>  0700 <gpm>        0700 root 
<xconsole> 0600 /dev/console 0600 root.root 
<xconsole> 0600 <dri>        0600 root

To read :

# file classes -- these are regular expressions 
<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 

# device classes -- these are shell-style globs 
<floppy>=/dev/fd[0-1]* 
<cdrom>=/dev/cdrom* /dev/cdwriter* 
<pilot>=/dev/pilot 
<fb>=/dev/fb /dev/fb[0-9]* 
<kbd>=/dev/kbd 
<gpm>=/dev/gpmctl  
<dri>=/dev/dri/* /dev/nvidia* 

# permission definitions 
<console> 0660 <floppy> 0660 root.floopy
<console> 0600 <cdrom>  0600 root.disk
<console> 0600 <pilot>  0660 root.tty
<console> 0600 <fb>     0600 root
<console> 0600 <kbd>    0600 root
<console> 0700 <gpm>    0700 root

Here we removed every privileged user related to the Graphical User Interface and others related to sound, zip drive, jaz drive, scanner, joystick and video media at the physical console on the server.

Putting limits on resource

The limits.conf file located under the /etc/security directory can be used to control and limit resources for the users on your system. It is important to set resource limits on all your users so they can't perform denial of service attacks (number of processes, amount of memory, etc) on the server. These limits will have to be set up for the user when he or she logs in.

For example, limits for all users on your system might look like this.

Step 1

Edit the limits.conf file (vi /etc/security/limits.conf) and add or change the lines to read:

* hard core  0
* hard rss   5000
* hard nproc 35

This says to prohibit the creation of core files "core 0", restrict the number of processes to 20 "nproc 20", and restrict memory usage to 5M "rss 5000" for everyone except the super user "root". All of the above only concerns users who have entered through the login prompt on your system. With this kind of quota, you have more control on the processes, core files, and memory usage that users may have on your system. The asterisk "*" mean: all users that logs in on the server.

Putting an asterisk "*" to cover all users can pose problem with daemon users account like "www" for a Web Server, "mysql" for a SQL Database Server, etc. If we put an asterisk, then, these users will be affected by the restriction and limitation of processes or memory usage.

To solve the problem, we can choose an existing group name in our system and add every regular user to this group. In this manner, the restrictions and limitations will apply to all users who are members of this group name only. A special group account named "users" can be used for this purpose.

Edit the limits.conf file (vi /etc/security/limits.conf) and add or change the lines to read:

@users hard core  0  
@users hard rss   5000
@users hard nproc 35

If you decide to use a group name like "@users" to control and limit resources for the users on your system, then it is important to not forget to change the GUI (Group User ID) of these users to be "100". "100" is the numeric value of the user's ID "users".

The command to create a new user with group name which is set by default to users is:

[root@server /]# useradd -g100 admin

WARNING: The "-g100" option represents the number of the user's initial login group and in our case "100" is the group account name "users". The "admin" parameter is the user name we want to add to the group name "users". Use the same command above for all users on your system you want to be member of the "users" group account. It is also preferable to set this parameter first before adding users to the system.

Step 2

You must also edit the /etc/pam.d/login file and add the following line to the bottom of the file:

session required /lib/security/pam_limits.so

After adding the line above, the /etc/pam.d/login file should look like this:

#%PAM-1.0 
auth     required  /lib/security/pam_securetty.so 
auth     required  /lib/security/pam_stack.so services=system-auth 
auth     required  /lib/security/pam_nologin.so 
account  required /lib/security/pam_stack.so services=system-auth 
account  required /lib/security/pam_access.so 
password required /lib/security/pam_stack.so services=system-auth 
session  required /lib/security/pam_stack.so services=system-auth 
session  required /lib/security/pam_limits.so


Controlling access time to services

As the Linux-PAM system said, running a well-regulated system occasionally involves restricting access to certain services in a selective manner. The time.conf security file, which is provided by the pam_time.so module of Linux, offers some time control for access to services offered by a system. Its actions are determined through the configuration file called time.conf and located under /etc/security directory.

Step 1

The time.conf file can be configured to deny access to (individual) users based on their name, the time of day, the day of week, the service they are applying for and their terminal from which they are making their request.

Edit the time.conf file (vi /etc/security/time.conf), and add the following line:

login ; tty* & !ttyp* ; !root !smcnaught ; !Al0000-2400

The above time control access line means to deny all user access to console-login at all times except for the super-user 'root' and the user 'smcnaught'.

Take a note that many combinations exist as described in the time.conf file, we can, for example, allow user `admin' to access the console-login any time except at the weekend and on Tuesday from 8AM to 6PM with the following statement.

Edit the time.conf file (vi /etc/security/time.conf), and add the following line:

login ; * ; !admin ; !Wd0000-2400 !Tu0800-1800

Step 2

To be able to use the time.conf feature of Linux, make sure to add the following line to /etc/pam.d/login and sshd if you use this service or nothing will work. Edit the login file (vi /etc/pam.d/login) and add the following line.

account required /lib/security/pam_time.so

After adding the line above, the /etc/pam.d/login file should look like this:

#%PAM-1.0 
auth     required /lib/security/pam_securetty.so 
auth     required /lib/security/pam_stack.so services=system-auth 
auth     required /lib/security/pam_nologin.so 
account  required /lib/security/pam_stack.so services=system-auth 
account  required /lib/security/pam_access.so
account  required /lib/security/pam_time.so 
password required /lib/security/pam_stack.so services=system-auth 
session  required /lib/security/pam_stack.so services=system-auth 
session  required /lib/security/pam_limits.so

NOTE: Please read information about possible configurations of this file inside the time.conf file since your policies will certainly differ from the examples that I show you above.

Blocking; su to root, by one and sundry

The su (Substitute User) command allows you to become other (existing) users on the system. For example you can temporarily become `root' and execute commands as the super-user `root'. If you don't want anyone to su to root or want to restrict the su command to certain users then uncomment the following line of your su configuration file in the /etc/pam.d directory. We highly recommend that you limit the persons allowed to su to the root account.

Step 1

Edit the su file (vi /etc/pam.d/su) and uncomment the following line in the file:

auth required /lib/security/pam_wheel.so use_uid

After this line has been uncommented, the /etc/pam.d/su file should look like this:

#%PAM-1.0 
auth      sufficient /lib/security/pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth      sufficient /lib/security/pam_wheel.so trust use_uid 
# Uncomment the following line to require a user to be in the "wheel" group.
auth      required   /lib/security/pam_wheel.so use_uid
auth      required   /lib/security/pam_stack.so service=system-auth 
account   required   /lib/security/pam_stack.so service=system-auth
password  required   /lib/security/pam_stack.so service=system-auth 
session   required   /lib/security/pam_stack.so service=system-auth 
session   optional   /lib/security/pam_xauth.so

Which means only those who are members of the "wheel" group can su to root; it also includes logging. Note that the "wheel" group is a special account on your system that can be used for this purpose. You cannot use any group name you want to make this hack. This hack combined with specifying which TTY and VC devices root is allowed to login on will improve your security a lot on the system.

Step 2

Now that we have defined the "wheel" group in our /etc/pam.d/su file configuration, it is time to add some users who will be allowed to su to "root" account.

If you want to make, for example, the user "admin" a member of the "wheel" group, and thus be able to su to root, use the following command:

[root@server /]# usermod -G10 admin

Which means "G" is a list of supplementary groups, where the user is also a member of. "10" is the numeric value of the user's ID "wheel", and "admin" is the user we want to add to the "wheel" group. Use the same command above for all users on your system you want to be able to su to "root" account.

NOTE: For Linux users, who use the Xwindow interface, it is important to note that if you can't su in a GNOME terminal, it's because you've used the wrong terminal. (So don't think that this advice doesn't work simply because of a GNOME terminal problem!)

Facultative: With the latest Linux operating system, a special line exists in the su file /etc/pam.d/su which allows you to implicitly trust users in the "wheel" group (for security reasons, I don't recommend using this option). This mean that all users who are members of the "wheel" group can su to root without the need to enter the "root" password.

To allow users who are members of the "wheel" group to su to root account without the need to enter the "root" password, edit the su file (vi /etc/pam.d/su) and uncomment the following line in the file:

auth sufficient /lib/security/pam_wheel.so trust use_uid

After this line has been uncommented, the /etc/pam.d/su file should look like this:

#%PAM-1.0 a
auth      sufficient /lib/security/pam_rootok.so 
# Uncomment the following line to implicitly trust users in the "wheel" group.
auth      sufficient /lib/security/pam_wheel.so trust use_uid 
# Uncomment the following line to require a user to be in the "wheel" group.
auth      required   /lib/security/pam_wheel.so use_uid 
auth      required   /lib/security/pam_stack.so service=system-auth 
account   required   /lib/security/pam_stack.so service=system-auth 
password  required   /lib/security/pam_stack.so service=system-auth 
session   required   /lib/security/pam_stack.so service=system-auth 
session   optional   /lib/security/pam_xauth.so


KickStart Lockdown for Fedora Core 2 : http://www.giac.org/certified_professionals/practicals/gcux/0267.php