System hardening: the case of Linux
Hardening is a fundamental task to strengthen the security of systems and protect them against internal and external attacks. By applying different techniques combined, it becomes more difficult for an attacker to compromise the system, ensuring the confidentiality, integrity and availability of the data stored in it. Systems hardening is often applied in enterprise environments, where critical business data and resources need to be protected. However, it is equally important in any context where you need to secure your system and control access to resources.
What is system hardening?
Systems hardening is a process of strengthening the default security of a system by applying principles such as minimum exposure, defense in depth, minimum privilege or zero trust.
- Minimum exposure: consists of minimizing the number of components and services of the system that are exposed to the outside, hiding or eliminating those that are not essential for the operation of the system or are not used. In this way, the attack surface of the system is reduced, that is, the number of components and services that can be attacked by an attacker.
- Defense in depth: implementation of security measures at various layers or levels of the system. The idea is that in case an attacker manages to overcome a security layer; he will find other additional layers that protect the system.
- Minimum privilege: This practice is based on the concept that each user or process has the minimum privileges, only those necessary to perform their work. This means that each user or process should have access only to the resources and features they need for their work, and not more.
- Zero trust: also known as zero trust, it is an approach that is based on the idea that, by default, all users or devices should be distrusted, which requires verifying the identity and activity of all users and devices.
Basic hardening on Linux systems
Linux-based systems are widely used in servers and embedded IoT devices. Next, some recommendations are proposed to apply on these systems, always bearing in mind that to carry out a hardening it is necessary to organize and plan, assigning priorities, since it requires time and resources on the part of the responsible teams.
From the BIOS, disable the autoboot of external devices in the boot (such as USB or external disks), or the ability to modify the default boot partition. Also, if you use a bootloader, such as GRUB, protect it by using passwords. Finally, it is a best practice not to log in, as root. Sudo greatly improves system security without sharing credentials with other users and administrators.
Configuring users and groups:
It is important to set appropriate permissions to protect the security and integrity of files and directories. File and directory permissions determine who has access to them and what actions can be performed with them. In Linux, the permissions, or rights that users can have over certain files and/or contents are set at three clearly differentiated levels (owner, group, and others).
- System files: System files, such as kernel configuration files and system program files, should have read and execute permissions for the administrator owner and group, and restrictive read permissions for others. This allows the operating system to access and use these files, but prevents users from accidentally accessing, modifying, or deleting these important files.
- User files: User files such as documents, images, and files should have read, write, and execute permissions for the owner and restrictive or selective read permissions for the group and others. This allows the owner of the file to access and modify it, but prevents other users from accessing, modifying, or deleting it without authorization.
By default, in Linux, when you create a new file, it is assigned some permissions with which you are allowing another user of the system to at least read that file. And when you create a directory, you can make a list of the files it contains.
To correctly configure these permissions by default, you would have to modify the file "/etc/bash.bashrc" or "/etc/profile" and add "umask 027" at the end, to change the mask of the files and directories. This completely blocks the access of other users of the machine to all files that are created in the future in our user accounts.
In addition, it is interesting to mention the additional tools, such as SE Linux and the Apparmor, which can be used to restrict the permissions and actions of processes and programs on the system, thus protecting the kernel.
We recommend that you configure password policies that set minimum requirements, such as their length and complexity. This can help protect users' passwords.
- For a user: For example, to force a user to change their password when logging in the next time, you can use the following command:
This command sets the password expiration date to the current date, which will force the user to change it when logging in the next time. You can also use the "chage" command to set a password policy such as how often password should be changed. For example, to set a policy that forces the user to change their password every 90 days, you can use the following command:
This command sets the maximum password period to 90 days, which means that the user will need to change their password every 90 days to comply with the policy.
- For all users: To force all users on the system to change their passwords when logging in next time, you can use the "chage" command, along with the "awk" command and the "/etc/shadow" file. The "/etc/shadow" file stores information about system users' passwords, including the expiration date. Similarly, also use the "awk" command to process this file and modify the expiration date of the passwords of all users at the same time. For example, to force all users to change them when signing in next time, you can use the following command:
This command uses "awk" to process the "/etc/shadow" file and extract the usernames from each line. It then uses "xargs" to send each username as an argument to the "chage" command to set the password expiration date to the current date.
Configuration of services:
It is important to insist that each system and environment of use is different and will require a unique set of security services and configurations. Therefore, there is no default list of services that must be disabled in all cases to achieve optimal security hardening on Linux. however, some services that might be considered for disabling in a general service production environment are as follows:
- Unnecessary services: It is important to evaluate which services are really necessary for the operation of the system and disable those that are not essential. For example, pasting insecure text into the terminal.
- Insecure network services: it is significant to avoid using insecure network protocols, such as telnet, rsh, rlogin, vsftpd... There are more secure alternatives available, such as SSH or SFTP.
- Services that expose known vulnerabilities: If a service has a known vulnerability that has not been patched, it may need to be temporarily disabled until a security patch is released.
File system configuration:
The Ext2, Ext3, and Ext4 file systems are systems used in Linux. Ext4 is the latest version of the Ext file system and offers relevant improvements in terms of performance and security compared to its predecessors. Some of Ext4's security enhancements include verification of file system integrity, the ability to recover deleted files, and the ability to protect files from unintentional writeback. Therefore, its use is more recommended.
Some security measures that can be useful to protect the network in a Linux environment are the following:
- IDS: Several options are available for using a host intrusion detection system (HIDS) or network intrusion detection system (NIDS) for Linux, such as OSSEC, Tripwire, and AIDE. Each option has its own features and functionalities and can be chosen according to the needs and requirements of the environment.
- SSH: Secure Shell (SSH) should be used to remotely connect and manage servers securely. It is recommended:
- Use SSH keys instead of passwords: SSH keys provide a more secure form of authentication than passwords because they use public/private key cryptography instead of plaintext passwords.
- Configure the SSH server to use a port other than the default port (22): This can help prevent port scanning attacks that search for SSH servers using the default port.
- Configure the SSH server to allow only authorized user access: Access control lists (ACLs) can be used to allow only authorized user access to the SSH server.
- VPN: A virtual private network (VPN) should be used to protect the privacy and security of the network connection. There are several options available for configuring and using a VPN on Linux, such as OpenVPN, PPTP, and L2TP/IPSec. OpenVPN, which is a popular and secure choice, while PPTP and L2TP/IPSec are less secure, but widely supported options. Network Manager is a network configuration tool that can make it easy to set up and use a VPN on Linux.
- Two-factor authentication: implement two-factor authentication to improve network connection security and prevent unauthorized access.
A firewall should be used to block unwanted traffic and protect the network from external attacks. Iptables is a firewall software tool, which is used in Linux-based operating systems to filter network traffic and protect the system from external attacks. It works at the packet level and allows you to define rules to allow or block incoming or outgoing traffic based on different criteria, such as the source or destination of the packet, the network protocol used, or the destination port.
Entrenching the security of operating system boot involves implementing security measures that protect the kernel from known vulnerabilities and prevent unauthorized access or modification. Use the respective package managers based on Linux distributions, such as yum, apt-get, or dpkg, to apply all security updates.
- Kernel updates: It is important to keep the kernel up to date with the latest bug fixes and security patches to minimize exposure to known vulnerabilities.
- Use of signed drivers: Signed drivers should be used to ensure that those loaded into the kernel are legitimate and have not been modified. This will prevent the installation of rootkits on the system.
To configure logging and auditing components on Linux to improve system security, you can:
- Configure event logging: It is important to configure the event log system (syslog) so that logs are stored properly and can be analyzed effectively. This includes configuring the level of detail of logs and defining where they should be stored (for example, on an external log server).
- Configure system auditing: It is important to enable system auditing so that you can log and track suspicious changes and activity on the system. This includes defining which actions should be audited and where audit logs should be stored. You may need to install the audit package if it is not available. For example, on systems like Ubuntu you can install the "auditd" package or on Red Hat the "audit" package.
Stages of bastion
The system hardening process involves several stages and steps that must be followed to strengthen system security, some of which are:
- Plan the intervention on the target systems: to be able to anticipate the availability of the necessary resources and to notify the interested parties of the duration of the intervention in advance.
- Identify essential components and services: You must know what the system functionality requirements are. At this stage, you should evaluate which components and services are essential to the operation of the system and which are not necessary.
- Make a backup of the system: before applying any security configuration it is necessary to have a copy of the system that allows us to restore it, if necessary.
- Performing the hardening in a test environment: the application of any configuration on a system, whether safety or not can impact on its operation, therefore, it is convenient to perform a first hardening on that system, in a test or pre-production environment.
- Evaluate the result of the hardening: at this point we will have to evaluate if the security configuration meets the planned objective, and if the operation of the system is still as expected. Performing functional and safety tests is usually very useful at this point.
- Apply hardening in the production environment: If the results of the hardening tests in the safe environment are successful, it is time to apply the security settings in the production environment.
- Ensure the correct functioning of everything: finally, we will carry out a final evaluation that the production environment is functioning correctly in harmony with the rest of its ecosystem. We will notify users of the availability of the same, and we will conclude the intervention.
Unfortunately, there is no magic recipe for hardening a system. Each hardening must be done considering aspects, such as the type of target system, the ecosystem where it is framed and the level of service it is expected to offer, even within Linux, configurations can vary between different existing distributions.
The compromise between security and functionality is another important consideration in the hardening of systems, since on the one hand, it is important to strengthen the security of the system to protect it from attacks, and on the other, it is also important that the system is functional and provides the necessary features to perform its function. Therefore, it will be necessary to find the balance between security and functionality. For example, removing non-essential components from the system can improve security, but you can also remove some basic system functionality, with potential business impacts. It is very important to evaluate which components and services are essential to the system and which can be removed without significantly affecting the functionality of the system.