Simple checklist to help you deploying the most important areas of the GNU/Linux production systems - work in progress.
1,649
84 commits
updated Nov 19, 2024
In computing, hardening is usually the process of securing a system by reducing its surface of vulnerability, which is larger when a system performs more functions; in principle a single-function system is more secure than a multipurpose one. The main goal of systems hardening is to reduce security risk by eliminating potential attack vectors and condensing the systemβs attack surface.
This list contains the most important hardening rules for GNU/Linux systems.
Still work in progress... π·
I also created another repository (in a more detailed way): the-practical-linux-hardening-guide.
I'm not advocating throwing your existing hardening and deployment best practices out the door but I recommend is to always turn a feature from this checklist on in pre-production environments instead of jumping directly into production.
All items in this checklist contains three levels of priority:
means that the item has a low priority.
means that the item has a medium priority. You shouldn't avoid tackling that item.
means that the item has a high priority. You can't avoid following that rule and implement the corrections recommended.
SCAP (Security Content Automation Protocol) provides a mechanism to check configurations, vulnerability management and evaluate policy compliance for a variety of systems. One of the most popular implementations of SCAP is OpenSCAP and it is very helpful for vulnerability assessment and also as hardening helper.
Some of the external audit tools use this standard. For example Nessus has functionality for authenticated SCAP scans.
I tried to make this list compatible with OpenSCAP standard and rules. However, there may be differences.
Ensure /boot located on separate partition.
Ensure /home located on separate partition.
Ensure /usr located on separate partition.
Ensure /var located on separate partition.
Ensure /var/log and /var/log/audit located on separate partitions.
Ensure /tmp and /var/tmp located on separate partitions.
Restrict /usr partition mount options.
Example:
UUID=<...> /usr ext4 defaults,nodev,ro 0 2
Restrict /var partition mount options.
Example:
UUID=<...> /var ext4 defaults,nosuid 0 2
Restrict /var/log and /var/log/audit partitions mount options.
Example:
UUID=<...> /var/log ext4 defaults,nosuid,noexec,nodev 0 2
UUID=<...> /var/log/audit ext4 defaults,nosuid,noexec,nodev 0 2
Restrict /proc partition mount options.
Example:
proc /proc proc defaults,hidepid=2 0 0
Restrict /boot partition mount options.
Example:
LABEL=/boot /boot ext2 defaults,nodev,nosuid,noexec,ro 1 2
Restrict /home partition mount options.
Example:
UUID=<...> /home ext4 defaults,nodev,nosuid 0 2
Restrict /var and /var/tmp partitions mount options.
Example:
mv /var/tmp /var/tmp.old
ln -s /tmp /var/tmp
cp -prf /var/tmp.old/* /tmp && rm -fr /var/tmp.old
UUID=<...> /tmp ext4 defaults,nodev,nosuid,noexec 0 2
Restrict /dev/shm partition mount options.
Example:
tmpfs /dev/shm tmpfs rw,nodev,nosuid,noexec,size=1024M,mode=1777 0 0
Setting up polyinstantiated /var and /var/tmp directories.
Example:
# Create new directories:
mkdir --mode 000 /tmp-inst
mkdir --mode 000 /var/tmp/tmp-inst
# Edit /etc/security/namespace.conf:
/tmp /tmp-inst/ level root,adm
/var/tmp /var/tmp/tmp-inst/ level root,adm
# Set correct SELinux context:
setsebool polyinstantiation_enabled=1
chcon --reference=/tmp /tmp-inst
chcon --reference=/var/tmp/ /var/tmp/tmp-inst
Set group for /dev/shm.
Example:
tmpfs /dev/shm tmpfs rw,nodev,nosuid,noexec,size=1024M,mode=1770,uid=root,gid=shm 0 0
Encrypt swap partition.
Example:
# Edit /etc/crypttab:
sdb1_crypt /dev/sdb1 /dev/urandom cipher=aes-xts-plain64,size=256,swap,discard
# Edit /etc/fstab:
/dev/mapper/sdb1_crypt none swap sw 0 0
| Rule | Priority | Checkbox |
|---|---|---|
Separate /boot | ![]() | π² |
Separate /home | ![]() | π² |
Separate /usr | ![]() | π² |
Separate /var | ![]() | π² |
Separate /var/log and /var/log/audit | ![]() | π² |
Separate /tmp and /var/tmp | ![]() | π² |
Restrict /usr mount options | ![]() | π² |
Restrict /var mount options | ![]() | π² |
Restrict /var/log and /var/log/audit mount options | ![]() | π² |
Restrict /proc mount options | ![]() | π² |
Restrict /boot mount options | ![]() | π² |
Restrict /home mount options | ![]() | π² |
Restrict /tmp/ and /var/tmp mount options | ![]() | π² |
Restrict /dev/shm mount options | ![]() | π² |
Polyinstantiated /tmp and /var/tmp | ![]() | π² |
Set group for /dev/shm | ![]() | π² |
Encrypt swap | ![]() | π² |
Protect Single User Mode with root password.
Example:
# Edit /etc/sysconfig/init.
SINGLE=/sbin/sulogin
| Rule | Priority | Checkbox |
|---|---|---|
| Protect Single User Mode. | ![]() | π² |
Ensure bootloader config files are set properly permissions.
Example:
# Set the owner and group of /etc/grub.conf to the root user:
chown root:root /etc/grub.conf
chown -R root:root /etc/grub.d
# Set permissions on the /etc/grub.conf or /etc/grub.d file to read and write for root only:
chmod og-rwx /etc/grub.conf
chmod -R og-rwx /etc/grub.d
| Rule | Priority | Checkbox |
|---|---|---|
| Protect bootloader config files | ![]() | π² |
Restricting access to kernel logs.
Example:
echo "kernel.dmesg_restrict = 1" > /etc/sysctl.d/50-dmesg-restrict.conf
Restricting access to kernel pointers.
Example:
echo "kernel.kptr_restrict = 1" > /etc/sysctl.d/50-kptr-restrict.conf
ExecShield protection.
Example:
echo "kernel.exec-shield = 2" > /etc/sysctl.d/50-exec-shield.conf
Randomise memory space.
echo "kernel.randomize_va_space=2" > /etc/sysctl.d/50-rand-va-space.conf
| Rule | Priority | Checkbox |
|---|---|---|
| Restricting access to kernel logs | ![]() | π² |
| Restricting access to kernel pointers | ![]() | π² |
| ExecShield protection | ![]() | π² |
| Randomise memory space. | ![]() | π² |
Ensure syslog service is enabled and running.
Example:
systemctl enable rsyslog
systemctl start rsyslog
Send syslog data to external server.
Example:
# ELK
# Logstash
# Splunk
# ...
| Rule | Priority | Checkbox |
|---|---|---|
| Ensure syslog service is enabled and running. | ![]() | π² |
| Ensure syslog service is enabled and running. | ![]() | π² |
Update password policy (PAM).
Example:
authconfig --passalgo=sha512 \
--passminlen=14 \
--passminclass=4 \
--passmaxrepeat=2 \
--passmaxclassrepeat=2 \
--enablereqlower \
--enablerequpper \
--enablereqdigit \
--enablereqother \
--update
Limit password reuse (PAM).
Example:
# Edit /etc/pam.d/system-auth
# For the pam_unix.so case:
password sufficient pam_unix.so ... remember=5
# For the pam_pwhistory.so case:
password requisite pam_pwhistory.so ... remember=5
Secure /etc/login.defs password policy.
Example:
# Edit /etc/login.defs
PASS_MIN_LEN 14
PASS_MIN_DAYS 1
PASS_MAX_DAYS 60
PASS_WARN_AGE 14
Set auto logout inactive users.
Example:
echo "readonly TMOUT=900" >> /etc/profile.d/idle-users.sh
echo "readonly HISTFILE" >> /etc/profile.d/idle-users.sh
chmod +x /etc/profile.d/idle-users.sh
Set last logon/access notification.
Example:
# Edit /etc/pam.d/system-auth
session required pam_lastlog.so showfailed
Lock out accounts after a number of incorrect login (PAM).
Example:
# Edit /etc/pam.d/system-auth and /etc/pam.d/password-auth
# Add the following line immediately before the pam_unix.so statement in the AUTH section:
auth required pam_faillock.so preauth silent deny=3 unlock_time=never fail_interval=900
# Add the following line immediately after the pam_unix.so statement in the AUTH section:
auth [default=die] pam_faillock.so authfail deny=3 unlock_time=never fail_interval=900
# Add the following line immediately before the pam_unix.so statement in the ACCOUNT section:
account required pam_faillock.so
| Rule | Priority | Checkbox |
|---|---|---|
| Update password policy | ![]() | π² |
| Limit password reuse | ![]() | π² |
Secure /etc/login.defs password policy | ![]() | π² |
| Set auto logout inactive users. | ![]() | π² |
| Set last logon/access notification | ![]() | π² |
| Lock out accounts after a number of incorrect login | ![]() | π² |
Enable hard/soft link protection.
Example:
echo "fs.protected_hardlinks = 1" > /etc/sysctl.d/50-fs-hardening.conf
echo "fs.protected_symlinks = 1" >> /etc/sysctl.d/50-fs-hardening.conf
Disable uncommon filesystems.
Example:
echo "install cramfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install freevxfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install jffs2 /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install hfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install hfsplus /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install squashfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install udf /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install fat /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install vfat /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install nfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install nfsv3 /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install gfs2 /bin/false" > /etc/modprobe.d/uncommon-fs.conf
| Rule | Priority | Checkbox |
|---|---|---|
| Enable hard/soft link protection. | ![]() | π² |
| Disable uncommon filesystems. | ![]() | π² |
Set SELinux Enforcing mode.
Example:
# Edit /etc/selinux/config.
SELINUXTYPE=enforcing
| Rule | Priority | Checkbox |
|---|---|---|
| Set SELinux Enforcing mode. | ![]() | π² |
Enable TCP SYN Cookie protection.
Example:
echo "net.ipv4.tcp_syncookies = 1" > /etc/sysctl.d/50-net-stack.conf
Disable IP source routing.
Example:
echo "net.ipv4.conf.all.accept_source_route = 0" > /etc/sysctl.d/50-net-stack.conf
Disable ICMP redirect acceptance.
Example:
echo "net.ipv4.conf.all.accept_redirects = 0" > /etc/sysctl.d/50-net-stack.conf
Enable ignoring to ICMP requests.
Example:
echo "net.ipv4.icmp_echo_ignore_all = 1" > /etc/sysctl.d/50-net-stack.conf
Enable ignoring broadcasts request.
Example:
echo "net.ipv4.icmp_echo_ignore_broadcasts = 1" > /etc/sysctl.d/50-net-stack.conf
| Rule | Priority | Checkbox |
|---|---|---|
| Enable TCP SYN Cookie protection. | ![]() | π² |
| Disable IP source routing. | ![]() | π² |
| Disable ICMP redirect acceptance. | ![]() | π² |
| Enable ignoring to ICMP requests. | ![]() | π² |
| Enable ignoring broadcasts request. | ![]() | π² |
247 followers Β· starred Jan 2022
1,285 followers Β· starred Jan 2019
176 followers Β· starred Jul 2024
107 followers Β· starred Mar 2019
Simple checklist to help you deploying the most important areas of the GNU/Linux production systems - work in progress.
1,649
84 commits
updated Nov 19, 2024
In computing, hardening is usually the process of securing a system by reducing its surface of vulnerability, which is larger when a system performs more functions; in principle a single-function system is more secure than a multipurpose one. The main goal of systems hardening is to reduce security risk by eliminating potential attack vectors and condensing the systemβs attack surface.
This list contains the most important hardening rules for GNU/Linux systems.
Still work in progress... π·
I also created another repository (in a more detailed way): the-practical-linux-hardening-guide.
I'm not advocating throwing your existing hardening and deployment best practices out the door but I recommend is to always turn a feature from this checklist on in pre-production environments instead of jumping directly into production.
All items in this checklist contains three levels of priority:
means that the item has a low priority.
means that the item has a medium priority. You shouldn't avoid tackling that item.
means that the item has a high priority. You can't avoid following that rule and implement the corrections recommended.
SCAP (Security Content Automation Protocol) provides a mechanism to check configurations, vulnerability management and evaluate policy compliance for a variety of systems. One of the most popular implementations of SCAP is OpenSCAP and it is very helpful for vulnerability assessment and also as hardening helper.
Some of the external audit tools use this standard. For example Nessus has functionality for authenticated SCAP scans.
I tried to make this list compatible with OpenSCAP standard and rules. However, there may be differences.
Ensure /boot located on separate partition.
Ensure /home located on separate partition.
Ensure /usr located on separate partition.
Ensure /var located on separate partition.
Ensure /var/log and /var/log/audit located on separate partitions.
Ensure /tmp and /var/tmp located on separate partitions.
Restrict /usr partition mount options.
Example:
UUID=<...> /usr ext4 defaults,nodev,ro 0 2
Restrict /var partition mount options.
Example:
UUID=<...> /var ext4 defaults,nosuid 0 2
Restrict /var/log and /var/log/audit partitions mount options.
Example:
UUID=<...> /var/log ext4 defaults,nosuid,noexec,nodev 0 2
UUID=<...> /var/log/audit ext4 defaults,nosuid,noexec,nodev 0 2
Restrict /proc partition mount options.
Example:
proc /proc proc defaults,hidepid=2 0 0
Restrict /boot partition mount options.
Example:
LABEL=/boot /boot ext2 defaults,nodev,nosuid,noexec,ro 1 2
Restrict /home partition mount options.
Example:
UUID=<...> /home ext4 defaults,nodev,nosuid 0 2
Restrict /var and /var/tmp partitions mount options.
Example:
mv /var/tmp /var/tmp.old
ln -s /tmp /var/tmp
cp -prf /var/tmp.old/* /tmp && rm -fr /var/tmp.old
UUID=<...> /tmp ext4 defaults,nodev,nosuid,noexec 0 2
Restrict /dev/shm partition mount options.
Example:
tmpfs /dev/shm tmpfs rw,nodev,nosuid,noexec,size=1024M,mode=1777 0 0
Setting up polyinstantiated /var and /var/tmp directories.
Example:
# Create new directories:
mkdir --mode 000 /tmp-inst
mkdir --mode 000 /var/tmp/tmp-inst
# Edit /etc/security/namespace.conf:
/tmp /tmp-inst/ level root,adm
/var/tmp /var/tmp/tmp-inst/ level root,adm
# Set correct SELinux context:
setsebool polyinstantiation_enabled=1
chcon --reference=/tmp /tmp-inst
chcon --reference=/var/tmp/ /var/tmp/tmp-inst
Set group for /dev/shm.
Example:
tmpfs /dev/shm tmpfs rw,nodev,nosuid,noexec,size=1024M,mode=1770,uid=root,gid=shm 0 0
Encrypt swap partition.
Example:
# Edit /etc/crypttab:
sdb1_crypt /dev/sdb1 /dev/urandom cipher=aes-xts-plain64,size=256,swap,discard
# Edit /etc/fstab:
/dev/mapper/sdb1_crypt none swap sw 0 0
| Rule | Priority | Checkbox |
|---|---|---|
Separate /boot | ![]() | π² |
Separate /home | ![]() | π² |
Separate /usr | ![]() | π² |
Separate /var | ![]() | π² |
Separate /var/log and /var/log/audit | ![]() | π² |
Separate /tmp and /var/tmp | ![]() | π² |
Restrict /usr mount options | ![]() | π² |
Restrict /var mount options | ![]() | π² |
Restrict /var/log and /var/log/audit mount options | ![]() | π² |
Restrict /proc mount options | ![]() | π² |
Restrict /boot mount options | ![]() | π² |
Restrict /home mount options | ![]() | π² |
Restrict /tmp/ and /var/tmp mount options | ![]() | π² |
Restrict /dev/shm mount options | ![]() | π² |
Polyinstantiated /tmp and /var/tmp | ![]() | π² |
Set group for /dev/shm | ![]() | π² |
Encrypt swap | ![]() | π² |
Protect Single User Mode with root password.
Example:
# Edit /etc/sysconfig/init.
SINGLE=/sbin/sulogin
| Rule | Priority | Checkbox |
|---|---|---|
| Protect Single User Mode. | ![]() | π² |
Ensure bootloader config files are set properly permissions.
Example:
# Set the owner and group of /etc/grub.conf to the root user:
chown root:root /etc/grub.conf
chown -R root:root /etc/grub.d
# Set permissions on the /etc/grub.conf or /etc/grub.d file to read and write for root only:
chmod og-rwx /etc/grub.conf
chmod -R og-rwx /etc/grub.d
| Rule | Priority | Checkbox |
|---|---|---|
| Protect bootloader config files | ![]() | π² |
Restricting access to kernel logs.
Example:
echo "kernel.dmesg_restrict = 1" > /etc/sysctl.d/50-dmesg-restrict.conf
Restricting access to kernel pointers.
Example:
echo "kernel.kptr_restrict = 1" > /etc/sysctl.d/50-kptr-restrict.conf
ExecShield protection.
Example:
echo "kernel.exec-shield = 2" > /etc/sysctl.d/50-exec-shield.conf
Randomise memory space.
echo "kernel.randomize_va_space=2" > /etc/sysctl.d/50-rand-va-space.conf
| Rule | Priority | Checkbox |
|---|---|---|
| Restricting access to kernel logs | ![]() | π² |
| Restricting access to kernel pointers | ![]() | π² |
| ExecShield protection | ![]() | π² |
| Randomise memory space. | ![]() | π² |
Ensure syslog service is enabled and running.
Example:
systemctl enable rsyslog
systemctl start rsyslog
Send syslog data to external server.
Example:
# ELK
# Logstash
# Splunk
# ...
| Rule | Priority | Checkbox |
|---|---|---|
| Ensure syslog service is enabled and running. | ![]() | π² |
| Ensure syslog service is enabled and running. | ![]() | π² |
Update password policy (PAM).
Example:
authconfig --passalgo=sha512 \
--passminlen=14 \
--passminclass=4 \
--passmaxrepeat=2 \
--passmaxclassrepeat=2 \
--enablereqlower \
--enablerequpper \
--enablereqdigit \
--enablereqother \
--update
Limit password reuse (PAM).
Example:
# Edit /etc/pam.d/system-auth
# For the pam_unix.so case:
password sufficient pam_unix.so ... remember=5
# For the pam_pwhistory.so case:
password requisite pam_pwhistory.so ... remember=5
Secure /etc/login.defs password policy.
Example:
# Edit /etc/login.defs
PASS_MIN_LEN 14
PASS_MIN_DAYS 1
PASS_MAX_DAYS 60
PASS_WARN_AGE 14
Set auto logout inactive users.
Example:
echo "readonly TMOUT=900" >> /etc/profile.d/idle-users.sh
echo "readonly HISTFILE" >> /etc/profile.d/idle-users.sh
chmod +x /etc/profile.d/idle-users.sh
Set last logon/access notification.
Example:
# Edit /etc/pam.d/system-auth
session required pam_lastlog.so showfailed
Lock out accounts after a number of incorrect login (PAM).
Example:
# Edit /etc/pam.d/system-auth and /etc/pam.d/password-auth
# Add the following line immediately before the pam_unix.so statement in the AUTH section:
auth required pam_faillock.so preauth silent deny=3 unlock_time=never fail_interval=900
# Add the following line immediately after the pam_unix.so statement in the AUTH section:
auth [default=die] pam_faillock.so authfail deny=3 unlock_time=never fail_interval=900
# Add the following line immediately before the pam_unix.so statement in the ACCOUNT section:
account required pam_faillock.so
| Rule | Priority | Checkbox |
|---|---|---|
| Update password policy | ![]() | π² |
| Limit password reuse | ![]() | π² |
Secure /etc/login.defs password policy | ![]() | π² |
| Set auto logout inactive users. | ![]() | π² |
| Set last logon/access notification | ![]() | π² |
| Lock out accounts after a number of incorrect login | ![]() | π² |
Enable hard/soft link protection.
Example:
echo "fs.protected_hardlinks = 1" > /etc/sysctl.d/50-fs-hardening.conf
echo "fs.protected_symlinks = 1" >> /etc/sysctl.d/50-fs-hardening.conf
Disable uncommon filesystems.
Example:
echo "install cramfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install freevxfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install jffs2 /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install hfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install hfsplus /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install squashfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install udf /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install fat /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install vfat /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install nfs /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install nfsv3 /bin/false" > /etc/modprobe.d/uncommon-fs.conf
echo "install gfs2 /bin/false" > /etc/modprobe.d/uncommon-fs.conf
| Rule | Priority | Checkbox |
|---|---|---|
| Enable hard/soft link protection. | ![]() | π² |
| Disable uncommon filesystems. | ![]() | π² |
Set SELinux Enforcing mode.
Example:
# Edit /etc/selinux/config.
SELINUXTYPE=enforcing
| Rule | Priority | Checkbox |
|---|---|---|
| Set SELinux Enforcing mode. | ![]() | π² |
Enable TCP SYN Cookie protection.
Example:
echo "net.ipv4.tcp_syncookies = 1" > /etc/sysctl.d/50-net-stack.conf
Disable IP source routing.
Example:
echo "net.ipv4.conf.all.accept_source_route = 0" > /etc/sysctl.d/50-net-stack.conf
Disable ICMP redirect acceptance.
Example:
echo "net.ipv4.conf.all.accept_redirects = 0" > /etc/sysctl.d/50-net-stack.conf
Enable ignoring to ICMP requests.
Example:
echo "net.ipv4.icmp_echo_ignore_all = 1" > /etc/sysctl.d/50-net-stack.conf
Enable ignoring broadcasts request.
Example:
echo "net.ipv4.icmp_echo_ignore_broadcasts = 1" > /etc/sysctl.d/50-net-stack.conf
| Rule | Priority | Checkbox |
|---|---|---|
| Enable TCP SYN Cookie protection. | ![]() | π² |
| Disable IP source routing. | ![]() | π² |
| Disable ICMP redirect acceptance. | ![]() | π² |
| Enable ignoring to ICMP requests. | ![]() | π² |
| Enable ignoring broadcasts request. | ![]() | π² |
247 followers Β· starred Jan 2022
1,285 followers Β· starred Jan 2019
176 followers Β· starred Jul 2024
107 followers Β· starred Mar 2019