Some of the Best practices include
-
Ensure mounting of freevxfs filesystems is disabled (Automated)
Removing support for unnecessary file system types reduces the server's local attack surface. If this type of file system is not needed, disable it.
modprobe -n -v freevxfs | grep -E '(freevxfs|install)' # output install /bin/true lsmod | grep freevxfs #<No output> #Create vi /etc/modprobe.d/freevxfs.conf install freevxfs /bin/true #Then reboot the system
-
Ensure mounting of jffs2 filesystems is disabled (Automated)
If this type of file system is not needed, disable it.
# modprobe -n -v jffs2 | grep -E '(jffs2|install)' install /bin/true # lsmod | grep jffs2 <No output> vi /etc/modprobe.d/jffs2.conf install jffs2 /bin/true
-
Ensure mounting of hfs filesystems is disabled (Automated)
# modprobe -n -v hfs | grep -E '(hfs|install)' install /bin/true # lsmod | grep hfs <No output> vi /etc/modprobe.d/hfs.conf install hfs /bin/true
-
Ensure mounting of hfsplus filesystems is disabled (Automated)
# modprobe -n -v hfsplus | grep -E '(hfsplus|install)' install /bin/true # lsmod | grep hfsplus <No output> vi /etc/modprobe.d/hfsplus.conf install hfsplus /bin/true
-
Ensure mounting of udf filesystems is disabled (Automated)
# modprobe -n -v udf | grep -E '(udf|install)' install /bin/true # lsmod | grep udf <No output> vi /etc/modprobe.d/udf.conf install udf /bin/true
-
Ensure mounting of FAT filesystems is limited (Not Scored)
# modprobe -n -v vfat | grep -E '(vfat|install)' install /bin/true # lsmod | grep vfat <No output> vi /etc/modprobe.d/vfat.conf install vfat /bin/true
-
Ensure mounting of squashfs filesystems is disabled
The squashfs filesystem type is a compressed read-only Linux filesystem embedded in small footprint systems (similar to cramfs ). A squashfs image can be used without having to first decompress the image.
# modprobe -n -v squashfs install /bin/true # lsmod | grep squashfs <No output> vim /etc/modprobe.d/squashfs.conf install squashfs /bin/true
-
Ensure mounting of cramfs filesystems is disabled
The cramfs filesystem type is a compressed read-only Linux filesystem embedded in small footprint systems. A cramfs image can be used without having to first decompress the image.
vi /etc/modprobe.d/cramfs.conf install cramfs /bin/false blacklist cramfs #save the file #then run the following command modprobe -r cramfs
-
Ensure /tmp is configured
#check findmnt -n /tmp /tmp tmpfs tmpfs rw,nosuid,nodev,noexec #repair cp -v /usr/share/systemd/tmp.mount /etc/systemd/system/ vi /etc/systemd/system/tmp.mount [Mount] What=tmpfs Where=/tmp Type=tmpfs Options=mode=1777,strictatime,nosuid,nodev,noexec #save the file and run the following systemctl daemon-reload systemctl --now enable tmp.mount
-
Ensure nodev option set on /tmp partition
#check - verify that nothing is returned findmnt -n /tmp | grep nodev #repair vi /etc/systemd/system/tmp.mount [Mount] Options=mode=1777,strictatime,noexec,nodev,nosuid #save and run the following systemctl daemon-reload systemctl restart tmp.mount
-
Ensure nosuid option set on /tmp partition
#check - verify that nothing is returned findmnt -n /tmp | grep nosuid #repair vi /etc/systemd/system/tmp.mount [Mount] Options=mode=1777,strictatime,noexec,nodev,nosuid #save and run the following mount -o remount,nosuid /tmp
-
Ensure noexec option set on /tmp partition
#verify that nothing is returned findmnt -n /tmp | grep noexec #repair vi /etc/systemd/system/tmp.mount [Mount] Options=mode=1777,strictatime,noexec,nodev,nosuid #save and run the following mount -o remount,noexec /tmp
-
Ensure /dev/shm is configured, nodev, nosuid and noexec option set on /dev/shm partion
#verify that nothing is returned findmnt -n /dev/shm /dev/shm tmpfs tmpfs rw,nosuid,nodev,noexec vi /etc/fstab tmpfs /dev/shm tmpfs defaults,noexec,nodev,nosuid,seclabel 0 0 #save and run the following mount -o remount,noexec,nodev,nosuid /dev/shm
-
Ensure permissions on bootloader config are not overridden
chown root:root /boot/grub/grub.cfg chmod og-rwx /boot/grub/grub.cfg #check stat /boot/grub/grub.cfg #output should be chmod 400 Access: (0400/-r--------) Uid: ( 0/ root) Gid: ( 0/ root) sed -ri 's/chmod\s+[0-7][0-7][0-7]\s+\$\{grub_cfg\}\.new/chmod 400 ${grub_cfg}.new/' /usr/sbin/grub-mkconfig sed -ri 's/ && ! grep "\^password" \$\{grub_cfg\}.new >\/dev\/null//' /usr/sbin/grub-mkconfig
-
Ensure filesystem integrity is regularly checked
There are 2 ways to do this a) with cronjob b) with aide.check.service
a) If cron will be used to schedule and run aide check: Run the following command and add the following line to the crontab
# crontab -u root -e 0 5 * * * /usr/bin/aide.wrapper --config /etc/aide/aide.conf --check
if aidecheck.service and aidecheck.timer will be used to schedule and run aide check: Create or edit the file /etc/systemd/system/aidecheck.service and add the following lines:
vi /etc/systemd/system/aidecheck.service [Unit] Description=Aide Check [Service] Type=simple ExecStart=/usr/bin/aide.wrapper --config /etc/aide/aide.conf --check [Install] WantedBy=multi-user.target
Create or edit the file /etc/systemd/system/aidecheck.timer and add the following lines:
vi /etc/systemd/system/aidecheck.timer [Unit] Description=Aide check every day at 5AM [Timer] OnCalendar=*-*-* 05:00:00 Unit=aidecheck.service [Install] WantedBy=multi-user.target
finally run the following commands:
chown root:root /etc/systemd/system/aidecheck.* chmod 0644 /etc/systemd/system/aidecheck.* systemctl daemon-reload systemctl enable aidecheck.service systemctl --now enable aidecheck.timer
-
Ensure bootloader password is set.
Check the output of the following commands. If they show superusers and an encrypted password, then bootloader password is already set, if no output is displayed, follow the remedy.
grep "^set superusers" /boot/grub/grub.cfg #output set superusers="root" grep "^password" /boot/grub/grub.cfg #output password_pbkdf2 root grub.pbkdf2.sha512.10000.encrypted_password
Remedy:
Create an encrypted password with grub-mkpasswd-pbkdf2:
grub-mkpasswd-pbkdf2 Enter password: <password> Reenter password: <password> PBKDF2 hash of your password is <encrypted-password>
Add the following into a 40_custom /etc/grub.d configuration file.
vi /etc/grub.d/40_custom set superusers="root" password_pbkdf2 root <encrypted-password>
The superuser/user information and password should not be contained in the /etc/grub.d/00_header file as this file could be overwritten in a package update. If there is a requirement to be able to boot/reboot without entering the password, edit /etc/grub.d/10_linux and add --unrestricted to the line CLASS=
vi /etc/grub.d/10_linux CLASS="--class gnu-linux --class gnu --class os --unrestricted"
Run the following command to update the grub2 configuration.
update-grub
-
Ensure core dumps are restricted
Setting a hard limit on core dumps prevents users from overriding the soft variable. If core dumps are required, consider setting limits for user groups (see limits.conf(5) ). In addition, setting the fs.suid_dumpable variable to 0 will prevent setuid programs from dumping core.
grep -Es '^(\*|\s).*hard.*core.*(\s+#.*)?$' /etc/security/limits.conf /etc/security/limits.d/* #output shoud be * hard core 0 sysctl fs.suid_dumpable # output should be fs.suid_dumpable = 0 grep "fs.suid_dumpable" /etc/sysctl.conf /etc/sysctl.d/* #output should be fs.suid_dumpable = 0
Run the following command to check if systemd-coredump is installed
systemctl is-enabled coredump.service
Remedy
Add the following line to /etc/security/limits.conf or a /etc/security/limits.d/* file and set the following parameter in /etc/sysctl.conf or a /etc/sysctl.d/* file:
vi /etc/security/limits.conf * hard core 0 vi /etc/sysctl.conf fs.suid_dumpable = 0
Run the following command to set the active kernel parameter:
sysctl -w fs.suid_dumpable=0
IF systemd-coredump is installed: edit /etc/systemd/coredump.conf and add/modify the following lines:
vi /etc/systemd/coredump.conf Storage=none ProcessSizeMax=0 #save and run the following command systemctl daemon-reload
reboot the system. If you find that the setting is not persistant, the reason could be that on your Server apport might be enabled. Try disabling it by changin enable=0.
vi /etc/default/apport enabled=0 reboot sysctl fs.suid_dumpable
-
Ensure AppArmor is installed and AppArmor is enabled in the bootloader configuration.
Install apparmor using apt. Edit /etc/default/grub and add the apparmor=1 and security=apparmor parameters to the GRUB_CMDLINE_LINUX= line GRUB_CMDLINE_LINUX="apparmor=1 security=apparmor"
apt install apparmor vi /etc/default/grub GRUB_CMDLINE_LINUX="apparmor=1 security=apparmor" #Run the following command to update the grub2 configuration: update-grub
-
Ensure audit_backlog_limit is sufficient
vi /etc/default/grub GRUB_CMDLINE_LINUX='audit_backlog_limit=8192' grub-mkconfig -o /boot/grub/grub.cfg
-
Ensure actions as another user are always logged
cd /etc/audit/rules.d/ printf ' -a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation -a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation ' >> /etc/audit/rules.d/50-user_emulation.rules augenrules --load # Check if reboot is required. if [[ $(auditctl -s | grep 'enabled') =~ '2' ]]; then printf 'Reboot required to load rules '; fi
-
Ensure events that modify date and time information are collected
cd /etc/audit/rules.d/ printf ' -a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k timechange -a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k timechange -w /etc/localtime -p wa -k time-change ' >> /etc/audit/rules.d/50-time-change.rules augenrules --load reboot
-
Ensure events that modify user/group information are collected - /etc/group
vi /etc/audit/rules.d/identity.rules -w /etc/group -p wa -k identity -w /etc/passwd -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity augenrules --load reboot
-
Ensure events that modify the system's network environment are collected - auditctl /etc/hosts
cd /etc/audit/rules.d/ printf ' -a always,exit -F arch=b64 -S sethostname,setdomainname -k system-locale -a always,exit -F arch=b32 -S sethostname,setdomainname -k system-locale -w /etc/issue -p wa -k system-locale -w /etc/issue.net -p wa -k system-locale -w /etc/hosts -p wa -k system-locale -w /etc/sysconfig/network -p wa -k system-locale -w /etc/sysconfig/network-scripts/ -p wa -k system-locale ' >> /etc/audit/rules.d/50-system_local.rules augenrules --load reboot