How To Secure Your Linux Server or Workstation - Linux Best Security Practices
One of the foremost requisites of a secure Linux server is the boot disk. Nowadays, this has become rather simple as most Linux distributions are on bootable CD/DVD/USB sticks. Other options are, to use rescue disks such as the ‘TestDisk’, ‘SystemRescueCD’, ‘Trinity Rescue Kit’ or ‘Ubuntu Rescue Remix’. These will enable you to gain access to your system, if you are unable to gain entry, and also to recover files and partitions if your system is damaged. They can be used to check for virus attacks and to detect rootkits.
Next requirement is for patching your system. Distributions issue notices for security updates, and you can download and patch your system using these updates. RPM users can use the ‘up2date’ command, which automatically resolves dependencies, rather than the other rpm commands, since these only report dependencies and do not help to resolve them.
Patch Your System
While RedHat/CentOS/Fedora users can patch their systems with a single command, 'yum update', Debian users can patch their systems with the ‘sudo apt-get update’ command, which will update the sources list. This should be followed by the command ‘sudo apt-get upgrade’, which will install the newest version of all packages on the machine, resolving all the dependencies automatically.
New vulnerabilities are being discovered all the time, and patches follow. One way to learn about new vulnerabilities is to subscribe to the mailing list of the distribution used.
Disable Unnecessary Services
Your system becomes increasingly insecure as you operate more services, since every service has its own security issues. For improving the overall system performance and for enhancing security, it is important to detect and eliminate unnecessary running services. To know which services are currently running on your system, you can use commands like:
Following is an example output of the above command:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 2828 1400 ? Ss Feb08 0:02 /sbin/init
root 2 0.0 0.0 0 0 ? S Feb08 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S Feb08 0:00 [migration/0]
root 4 0.0 0.0 0 0 ? S Feb08 0:00 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S Feb08 0:00 [watchdog/0]
root 6 0.0 0.0 0 0 ? S Feb08 0:00 [events/0]
root 7 0.0 0.0 0 0 ? S Feb08 0:00 [cpuset]
root 8 0.0 0.0 0 0 ? S Feb08 0:00 [khelper]
root 9 0.0 0.0 0 0 ? S Feb08 0:00 [netns]
root 10 0.0 0.0 0 0 ? S Feb08 0:00 [async/mgr]
root 11 0.0 0.0 0 0 ? S Feb08 0:00 [pm]
root 12 0.0 0.0 0 0 ? S Feb08 0:00 [sync_supers]
apache 17250 0.0 0.9 37036 10224 ? S Feb08 0:00 /usr/sbin/httpd
apache 25686 0.0 0.9 37168 10244 ? S Feb08 0:00 /usr/sbin/httpd
apache 28290 0.0 0.9 37168 10296 ? S Feb08 0:00 /usr/sbin/httpd
postfix 30051 0.0 0.2 10240 2136 ? S 23:35 0:00 pickup -l -t fifo -u
postfix 30060 0.0 0.2 10308 2280 ? S 23:35 0:00 qmgr -l -t fifo -u
root 31645 0.1 0.3 11120 3112 ? Ss 23:45 0:00 sshd: root@pts/1
The following command will list all start-up scripts for RunLevel 3 (Full multiuser mode):
[root@gateway~]# ls -l /etc/rc3.d/S*
lrwxrwxrwx. 1 root root 23 Jan 16 17:45 /etc/rc.d/rc3.d/S00microcode_ctl -> ../init.d/microcode_ctl
lrwxrwxrwx. 1 root root 17 Jan 16 17:44 /etc/rc.d/rc3.d/S01sysstat -> ../init.d/sysstat
lrwxrwxrwx. 1 root root 22 Jan 16 17:44 /etc/rc.d/rc3.d/S02lvm2-monitor -> ../init.d/lvm2-monitor
lrwxrwxrwx. 1 root root 19 Jan 16 17:39 /etc/rc.d/rc3.d/S08ip6tables -> ../init.d/ip6tables
lrwxrwxrwx. 1 root root 18 Jan 16 17:38 /etc/rc.d/rc3.d/S08iptables -> ../init.d/iptables
lrwxrwxrwx. 1 root root 17 Jan 16 17:42 /etc/rc.d/rc3.d/S10network -> ../init.d/network
lrwxrwxrwx. 1 root root 16 Jan 27 01:04 /etc/rc.d/rc3.d/S11auditd -> ../init.d/auditd
lrwxrwxrwx. 1 root root 21 Jan 16 17:39 /etc/rc.d/rc3.d/S11portreserve -> ../init.d/portreserve
lrwxrwxrwx. 1 root root 17 Jan 16 17:44 /etc/rc.d/rc3.d/S12rsyslog -> ../init.d/rsyslog
lrwxrwxrwx. 1 root root 18 Jan 16 17:45 /etc/rc.d/rc3.d/S13cpuspeed -> ../init.d/cpuspeed
lrwxrwxrwx. 1 root root 20 Jan 16 17:40 /etc/rc.d/rc3.d/S13irqbalance -> ../init.d/irqbalance
lrwxrwxrwx. 1 root root 17 Jan 16 17:38 /etc/rc.d/rc3.d/S13rpcbind -> ../init.d/rpcbind
lrwxrwxrwx. 1 root root 19 Jan 16 17:43 /etc/rc.d/rc3.d/S15mdmonitor -> ../init.d/mdmonitor
lrwxrwxrwx. 1 root root 20 Jan 16 17:38 /etc/rc.d/rc3.d/S22messagebus -> ../init.d/messagebus
To disable services, you can either stop a running service or change the configuration in a way that the service will not start on the next reboot. To stop a running service, RedHat/CentOS users can use the command -
Stopping httpd: [ OK ]
In order to stop the service from starting up at boot time, you could use -
You can also remove a service from the startup script by using the following commands which will remove the httpd (Apache Web server) service:
During startup on of the Linux operating system, the rc program looks in the /etc/rc.d/rc3.d directory (when configured with Runlevel 3), executing any K* scripts with an option of stop. Then, all the S* scripts are started with an option of start. Scripts are started in numerical order—thus, the S08iptables script is started before the S85httpd script. This allows you to choose exactly when your script starts without having to edit files. The same rule applies with the K* scripts.
In some rare cases, services may have to be removed from /etc/xinetd.d or /etc/inetd.conf file.
Debian users can use the following commands to stop, start and restart a service -
$ sudo service httpd start
$ sudo service httpd restart
Remove the startup script by -
Host-based Firewall Protection with IPtables
Using iptables firewall, you could limit access to your server by IP address or by host/domain name. RedHat/CentOS users have a file /etc/sysconfig/iptables based on the services that were ‘allowed’ during installation. The file can be edited to accept some services and block others. In case the requested service does not match any of the ACCEPT lines in the iptables file, the packet is logged and then rejected.
RedHat/CentOS/Fedora users will have to install the iptables with:
Debian users will need to install the iptables with the help of:
• INIVIDUAL REJECTS FIRST
• THEN OPEN IT UP
• BLOCK ALL
As it is a table of rules, the first rule takes precedence. If the first rule dis-allows everything nothing else following later will matter.In practice, a firewall script is needed which is created using the following sequence:
1) Create your script
2) Make it executable
3) Run the script
Following are the commands used for the above order:
[root@gateway~]# chmod 755 /root/firewall.sh
Updating the firewall script is simply a matter of re-editing to make the necessary changes and running it again. Since iptables does not run as a daemon, instead of stopping, the rules are only flushed with the '-F' option:
[root@gateway~]# iptables -F OUTPUT
[root@gateway~]# iptables -F FORWARD
[root@gateway~]# iptables -F POSTROUTING -t nat
[root@gateway~]# iptables -F PREROUTING -t nat
At startup/reboot, all that is needed is to execute the script to flush the iptables rules. The simplest way to do this is to add the script (/root/firewall.sh) to the file /etc/rc.local file.
Apart from the above, a number of steps need to be taken to keep your Linux server safe from outside attackers. Key files should be checked for security and must be set to root for both owner and group:/etc/fstab
The above should be owned by root and and their permission must be 644 (rw-r--r--), except /etc/shadow which should have the permission of 400 (r--------).
You can read more on how to set permissions on your Linux files in our Linux File & Folder Permissions article
Limiting Root Access
Implement a password policy, which forces users to change their login passwords, for example, every 60 to 90 days, starts warning them within 7 days of expiry, and accepts passwords that are a minimum of 14 characters in length.
Root access must be limited by using the following commands for RedHat/CentOS/Fedora -
Password: <enter root password>
Or for RedHat/CentOS/Fedora/Debian,
Password: <enter root password>
Only root should be able to access CRON. Cron is a system daemon used to execute desired tasks (in the background) at designated times.
A crontab is a simple text file with a list of commands meant to be run at specified times. It is edited with a command-line utility. These commands (and their run times) are then controlled by the cron daemon, which executes them in the system background. Each user has a crontab file which specifies the actions and times at which they should be executed, these jobs will run regardless of whether the user is actually logged into the system. There is also a root crontab for tasks requiring administrative privileges. This system crontab allows scheduling of systemwide tasks (such as log rotations and system database updates). You can use the man crontab command to find more information about it.
Lastly, the use of SSH is recommended instead of Telnet for remote accesses. The main difference between the two is that SSH encrypts all data exchanged between the user and server, while telnet sends all data in clear-text, making it extremely easy to obtain root passwords and other sensitive information. All unused TCP/UDP ports must also be blocked using IPtables.