Skip to content

This chapter is geared towards advanced users. Solid tech skills are required.

Advanced server hardening

Disclaimer

No system is safe. While this chapter presents measures to protect a server from most immediate threats, any skilled hacker or organisation with sufficient resources will probably find a way into the system.

Sudo privileges

Privileged access should be limited to users of a specific group, as detailed below.

Show me the step-by-step guide

Create a group called sudousers, and add both users gofossroot and gofossadmin (adjust user names according to your own setup):

sudo groupadd sudousers
sudo usermod -a -G sudousers gofossroot
sudo usermod -a -G sudousers gofossadmin

Backup the sudoers configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/sudoers

Add the following line, if it's not already there:

%sudousers   ALL=(ALL:ALL) ALL

Save and close the file (:wq!). Finally, limit access to elevated privileges to the sudousers group:

sudo dpkg-statoverride --update --add root sudousers 4750 /bin/su

Check permissions with the following command, the terminal should display sudousers:

ls -lh /bin/su
Show me a summary video


Protected processes

Protected processes

The /proc directory contains potentially sensitive information about processes. By default, all users can access this directory. Follow the instructions below to continue hardening your server and keep sensitive data hidden from unauthorised users or programs.

Show me the step-by-step guide

Back up the fstab configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --preserve /etc/fstab /etc/fstab-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/fstab

Hide process information by adding the following line at the end of the file:

proc    /proc   proc    defaults,hidepid=2  0   0

Save and close the file (:wq!). Finally, remount the /proc directory:

sudo mount -o remount,hidepid=2 /proc
Show me a summary video


Password security

Password security

By default, users are free to choose any password. Read on below for more details on how to enforce strong passwords and define quality requirements such as:

  • the maximum number of days a password can be used
  • the minimum number of days before a password can be changed
  • the minimum password length
  • the number of upper and lower case characters as well as digits to be used
Show me the step-by-step guide

Configure account parameters

Back up the configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --preserve /etc/login.defs /etc/login.defs-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/login.defs

Modify or add the following parameters:

PASS_MAX_DAYS   365
PASS_MIN_DAYS   1
PASS_WARN_AGE   30
SHA_CRYPT_MIN_ROUNDS 1000000
SHA_CRYPT_MAX_ROUNDS 1000000

Save and close the file (:wq!).

Let's apply the same settings to administrator users gofossroot and gofossadmin, which were created before password rules were hardened (adjust usernames according to your own setup):

sudo chage -m 1 -M 365 -W 30 gofossroot
sudo chage -m 1 -M 365 -W 30 gofossadmin

Make sure all changes were correctly applied:

sudo chage -l gofossroot
sudo chage -l gofossadmin

Some additional information on those modules:

Setting Description
PASS_MAX_DAYS Maximum number of days a password may be used.
PASS_MIN_DAYS Minimum number of days allowed between password changes.
PASS_WARN_AGE Number of days a warning is given before a password expires.
SHA_CRYPT_MIN_ROUNDS & SHA_CRYPT_MAX_ROUNDS By default, Linux stores the administrator password using a single, salted SHA-512 hash. To strengthen the password, use multiple rounds of a hash.

Configure PAM

Linux Pluggable Authentication Modules (PAM) is a powerful suite to manage user authentication. Install the following PAM module, which allows to strength-check passwords:

sudo apt install libpam-cracklib

Back up the pam.d configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --archive /etc/pam.d/common-password /etc/pam.d/common-password-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/pam.d/common-password

Modify or add the following parameters:

password requisite pam_cracklib.so retry=3 minlen=12 ucredit=-1 lcredit=-1 dcredit=-1 difok=3 gecoschec

In the same file, add the shadow option as well as an increased number of rounds in the following line:

password        [success=1 default=ignore]      pam_unix.so obscure use_authtok try_first_pass sha512 shadow rounds=1000000

Save and close the file (:wq!).

Some additional information on those settings:

Setting Description
retry = 3 Prompt users 3 times before returning an error.
minlen = 10 Minimum password length.
ucredit = -1 Password must have at least one upper case letter.
lcredit = -1 Password must have at least one lower case letter.
dcredit = -1 Password must have at least one digit.
difok = 3 At least 3 characters from the new password cannot have been used in the old password.
gecoschec Do not allow passwords with the account's name in it.
shadow rounds=1000000 By default, the pam_unix module stores the administrator password using a single, salted SHA-512 hash. To strengthen the password, Linux PAM can use multiple rounds of a hash.

Show me a summary video


Network security

Network security

The system administration command sysctl allows to fine tune the kernel and can be used to improve network security. More details below.

Show me the step-by-step guide

Back up the sysctl configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --archive /etc/sysctl.conf /etc/sysctl.conf-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/sysctl.conf

Delete the content by typing :%d. Then enter or copy/paste the following content:

# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Ignore ICMP broadcast requests
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0 
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0

# Block SYN attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5

# Log Martians
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Ignore ICMP redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0 
net.ipv6.conf.default.accept_redirects = 0

# Ignore Directed pings
net.ipv4.icmp_echo_ignore_all = 1

Save and close the file (:wq!), and load the new settings:

sudo sysctl -p

Some additional information on those security settings:

Measure Description
Enable IP spoofing protection Protect against IP spoofing where attackers disguise their IP, typically during Denial of Service (DoS) attacks.
Ignore ICMP broadcast requests Avoid that the server participates in a Smurf attack.
Ignore ICMP redirects Protect against forged ICMP redirect packets used by attackers to cause a Denial of Service (DoS) attack.
Disable source packet routing Protect against source routed packets used by attackers to obscure their identity and location.
Block SYN attacks Protect against SYN attacks, a form of Denial of Service (DoS) attack.
Log martians Protect against martian packets. These are spoofed packets with a source address which is obviously wrong. They can be used during Denial of Service (DoS) attacks.
Ignore directed pings The ping command can be used to check the connection status with your server. But it can also be used to perform attacks.

Show me a summary video


Antivirus & Anti-malware

Anti malware & virus

Linux Malware Detect (LMD) and ClamAV are open source antivirus and malware scanner solutions. Follow the instructions below to install and configure them on your server.

Show me the step-by-step guide

Malware scanner (LMD)

Install LMD using the following commands:

sudo apt install wget
sudo wget http://www.rfxn.com/downloads/maldetect-current.tar.gz
sudo tar -xvf maldetect-current.tar.gz
cd maldetect-1.6.4
sudo ./install.sh

Back up the maldet configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --archive /usr/local/maldetect/conf.maldet /usr/local/maldetect/conf.maldet-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /usr/local/maldetect/conf.maldet

Modify or add the following parameters (adjust the administrator user gofossadmin according to your own setup):

# send malware inspection results to local system administrator gofossadmin (adjust accordingly) in /var/mail/gofossadmin

email_alert="1"
email_addr="gofossadmin@localhost"

# move to quarantine & alert if malware is detected
quarantine_hits="1"

# don't automatically delete clean string-based malware injections (in case of false positives, avoid deleting files)
quarantine_clean="0"

# allow suspending users hit by malware
quarantine_suspend_user="1"

#use ClamAVs scanner engine (faster scans)
scan_clamscan="1"

#scan root owned files
scan_ignore_root="0"

Save and close the file (:wq!). Update LMD to the latest version and download the most recent malware definitions:

sudo maldet --update-ver
sudo maldet --update

Antivirus (ClamAV)

Install ClamAV with the following command:

sudo apt install clamav

Check if the software was successfully installed:

clamscan --version

Update the virus signature database:

sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-freshclam

Enable ClamAV to be automatically launched after each reboot:

sudo systemctl enable clamav-freshclam

Test LMD and ClamAV

We'll use dummy malware provided by the European Expert Group for IT Security (EICAR) to test the malware scanner and antivirus. Download the files as follows:

cd /var/www/html
sudo wget http://www.eicar.org/download/eicar.com 
sudo wget http://www.eicar.org/download/eicar.com.txt 
sudo wget http://www.eicar.org/download/eicar_com.zip 
sudo wget http://www.eicar.org/download/eicarcom2.zip

Use ClamAV to recursively scan the directory /var/www/html and all its subdirectories for viruses:

sudo clamscan --recursive --infected /var/www/html

The terminal should prompt something similar to:

/var/www/html/eicar_com.zip: Win.Test.EICAR_HDB-1 FOUND
/var/www/html/eicar.com: Win.Test.EICAR_HDB-1 FOUND
/var/www/html/eicarcom2.zip: Win.Test.EICAR_HDB-1 FOUND
/var/www/html/eicar.com.txt: Win.Test.EICAR_HDB-1 FOUND

----------- SCAN SUMMARY -----------
Known viruses: 6880642
Engine version: 0.102.2
Scanned directories: 1
Scanned files: 5
Infected files: 4
Data scanned: 0.01 MB
Data read: 0.01 MB (ratio 1.00:1)
Time: 54.632 sec (0 m 54 s)

Next, use LMD to scan the same directory for malware:

sudo maldet --scan-all /var/www/html

The output should contain a scan ID, something similar to 200510-1954.2127 (adjust accordingly). Inspect the detailed report with:

sudo maldet --report 200510-1954.2127

A list of all scan reports can be accessed with:

sudo maldet -e list

Finally, remove all quarantined files:

sudo ls /usr/local/maldetect/quarantine/
sudo rm -rf /usr/local/maldetect/quarantine/*

Schedule LMD scans

The malware scanner LMD is configured to run a daily cron job (/etc/cron.daily/maldet) which updates the malware registry and scans all home directories. That should be sufficient for most use cases. To keep the server load down, disable real time monitoring to avoid scans running every 10 minutes:

sudo rm /etc/cron.d/maldet_pub
sudo maldet -k

Schedule ClamAV scans

Let's also schedule antivirus scans and updates. Create an empty log file:

sudo touch /var/log/clamav/clamscan.log

Create a cron job to update the virus database and scan for viruses every day at 6pm:

crontab -e

Add the following two lines at the end of the file (adjust the administrator username according to your own setup):

0 18 * * * /usr/bin/freshclam
00 00 * * * root clamscan / -l /var/log/clamscan.log -r | mail -s "Clamscan Report" gofossadmin@localhost sudo systemctl restart cron

Save and close the file (:wq!).

Show me a summary video


Permissions

Permissions

The so-called umask defines default permissions and is set to 022 in Ubuntu. Which means that users can read and execute files they don't own, even if they don't belong to the file's group. This being said, they can't write to nor modify those files. Read on below to find out how to change the umask setting and enforce stricter permissions.

Show me the step-by-step guide

Change default permissions

Back up the login.defs configuration file. If something goes wrong, you'll be able to recover the initial settings:

sudo cp --archive /etc/login.defs /etc/login.defs-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/login.defs

Change the umask as follows:

UMASK 027

Save and close the file (:wq!).

Restrict permissions

Restrict unauthorised access to the following files:

sudo chmod 600 /etc/at.deny
sudo chmod 600 /etc/crontab
sudo chmod 600 /etc/ssh/sshd_config
sudo chmod 700 /etc/cron.d
sudo chmod 700 /etc/cron.daily
sudo chmod 700 /etc/cron.hourly
sudo chmod 700 /etc/cron.weekly
sudo chmod 700 /etc/cron.monthly
sudo chmod 750 /home/gofossroot
sudo chmod 750 /home/gofossadmin

Restrict access to compilers

Remove read and execute permissions to restrict access to compilers:

sudo chmod o-rx /usr/bin/gcc
sudo chmod o-rx /usr/bin/cc
sudo chmod o-rx /usr/bin/as

If no compilers are installed, the terminal should output something along the lines of No such file or directory.

Show me a summary video

Tell me more about Linux permissions

umask determines which users can access newly created files or directories. There are three user classes:

User Class Description
User The file's or directory's owner.
Group Users belonging to the file's or directory's group.
Others Users who are neither owner nor member of the file's or directory's group.

And there are three access restrictions:

Access restriction Description Permission's decimal value
Read ( r ) File or directory can be read or viewed. 4
Write ( w ) File or directory can be written, edited or modified. 2
Execute ( x ) File or directory can be executed. 1

A file's or directory's permission is determined by the sum of the three decimal values:

Permissions Value Description
--- 0 = 0 + 0 + 0 Can read, write & execute.
--x 1 = 0 + 0 + 1 Can read & write, but not execute.
-w- 2 = 0 + 2 + 0 Can read & execute, but not write.
-wx 3 = 0 + 2 + 1 Can read, but not write or execute.
r-- 4 = 4 + 0 + 0 Can write & execute, but not read.
r-x 5 = 4 + 0 + 1 Can write, but not read or execute.
rw- 6 = 4 + 2 + 0 Can execute, but not read or write.
rwx 7 = 4 + 2 + 1 Can't read, write or execute.

umask summarises permissions for each user class with three values. For example, changing umask from 022 to 027 prevents "others" from reading, writing or executing files and directories:

Umask User permissions Group permissions Others permissions Description
022 --- -w- -w- • The file's or directory's owner can read, write & execute.
• Members of the file's or directory's group can read and execute, but not write.
• Users who are neither owner nor member of the file's or directory's group can read and execute, but not write.
• In other words: the file's or directory's owner has full access, the group and others can only read and execute it.
027 --- -w- rwx • The file's or directory's owner can read, write & execute.
• Members of the file's or directory's group can read and execute, but not write.
• Users who are neither owner nor member of the file's or directory's group can't read, write or execute it.
• In other words: the file's or directory's owner has full access, the group can only write it, and others don't have access.

Other permissions referred to earlier in this tutorial include:

Permission Description
640 Owner can read and write, group can read, others have no access.
644 Owner can read and write, group and others only can read.
600 Owner can read and write, group and others have no access. This adds extra security.
755 Owner has full access, group and others can read and execute, but not write.
750 Owner has full access, group can read and execute, others have no access.
700 Owner has full access, group and others have no access. This adds extra security.


Core dumps

Disable core dumps

A core dump is a file containing a program's memory when it crashes. That's useful for debugging purposes, but can leak sensitive data. It's safe to disable if you don't do troubleshooting. More details below.

Show me the step-by-step guide

Backup the configuration files:

sudo cp --archive /etc/security/limits.conf /etc/security/limits.conf-COPY-$(date +"%Y%m%d%H%M%S")

sudo cp --archive /etc/sysctl.conf /etc/sysctl.conf-COPY-$(date +"%Y%m%d%H%M%S")

Open the first configuration file:

sudo vi /etc/security/limits.conf

Add the following lines at the end:

* soft core 0
* hard core 0

Save and close the file (:wq!).

Open the second configuration file:

sudo vi /etc/sysctl.conf

Add the following lines at the end:

# Disable coredumps
fs.suid_dumpable=0

Save and close the file (:wq!). Finally, apply the changes:

sudo sysctl -p
Show me a summary video


Kernel modules

Disable unused kernel modules

The Linux kernel is the core of the operating system. It controls the hardware, the memory, tasks and processes, and so on. Kernel modules are pieces of code that extend the kernel's functionality, for example to access new hardware. Having said that, kernel modules can also be misused to load malicious software or gain unauthorised access to the server. To avoid this, disallow the loading of unused kernel modules, as shown below.

Show me the step-by-step guide

Backup the configuration file:

sudo cp --archive /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf-COPY-$(date +"%Y%m%d%H%M%S")

Open the configuration file:

sudo vi /etc/modprobe.d/blacklist.conf

Add the following lines at the end:

# Instruct modprobe to force inactive modules to always fail loading
install cramfs /bin/false
install freevxfs /bin/false
install hfs /bin/false
install hfsplus /bin/false
install jffs2 /bin/false
install udf /bin/false

Save and close the file (:wq!).

Show me a summary video


Server security