Mastering Linux Security and Hardening

Written in


A book to cover tips and tricks to securing a Linux machine. It covers both recommended configurations to make your machine more secure, as well as investigative techniques (i.e. how to read certain syslogs or setup remote logging). In this post, I’ll be focusing on mainly recommended configurations and tweaks to secure a Linux Machine.

This list is obviously not exhaustive, I’m only showing things I found to be interesting or important


It is not recommended to edit /etc/sudoers directly, but to run sudo visudo instead.

The wheel group allows the users to delegate administrative powers to users. Rather than manually configuring individual permissions, you can simply add someone to the wheel group.

Refrain from doing this %wheel ALL=(ALL) NOPASSWD: ALL, which allows users in the wheel group to run any command without entering the sudo password.

The sudo command has a timer of 5 minutes after entering the password. You can disable this timer by editing the /etc/sudoers file to set timestamp_timeout=0. You can also manually reset the timer by running sudo -k.

To prevent users escaping to a root shell, you can specify exact commands users can run with sudo. e.g. sylvester ALL=(ALL) /usr/bin/systemctl status sshd, /usr/bin/systemctl restart sshd means that sylvester can only run status or restart on sshd. Never put a wildcard, which indicates he can run whatever he wants.

Remember to check both /etc/sudoers and /etc/sudoers.d. Also, change all default root passwords.

User Accounts

Password complexity can be enforced in /etc/security/pwquality.conf

The default password lifespan and expiry is found in /etc/login.defs

Use chage binary to manage password and account expiry

Settings in /etc/pam.d/login can be configured to prevent brute force attacks by changing the values of deny, even_deny_root and unlock_time.

You can lock/unlock user accounts with usermod and passwd. Under the hoods, it adds an exclamation mark in front of their password hashes in /etc/shadow.

Locking: sudo usermod -L username / sudo passwd -l katelyn

Unlocking: sudo usermod -U username / sudo passwd -u katelyn

Security Banners

This may seem trivial, but under the law, its actually something that’s required to warn unauthorized users not to login or use the system.

You can add a security message under /etc/motd, which will be displayed when users login through SSH.

You can also add messages to /etc/issue, which will display a message after a user has logged in.


Usually we would want to Block ICMP packets, but there are 3 ICMP packets that are required for the network to function properly on the machine, which are types 3 (unreachable), 11 (Time-out) and 12 (Invalid packet).

We can add those using iptables:

sudo iptables -A INPUT -m conntrack -p icmp --icmp-type 3 --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

sudo iptables -A INPUT -m conntrack -p icmp --icmp-type 11 --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

sudo iptables -A INPUT -m conntrack -p icmp --icmp-type 12 --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

Aside from these 3 ICMP packets, we should drop the rest of them.

Aside from dropping the ICMP packets, we should also drop malformed ICMP packets.

ufw is iptables under the hood. firewalld is nftables under the hood

Hardening SSL/TLS

On the Ubuntu VM with Apache, edit the /etc/apache2/mods-enabled/ssl.conf file from: SSLProtocol all -SSLv3 to SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

Enable system-wide crypto policy to FIPS: sudo fips-mode-setup –enable

Edit /etc/httpd/conf.d/ssl.conf from:

SSLProtocol all -SSLv2 -SSLv3


SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

This removes the old DES and SHA encryption from the system.

SSH Hardening

Disable SSH protocol 1 by editing /etc/ssh/sshd_config and change Protocol 1 to Protocol 2

Disable root login by changing PermitRootLogin yes to PermitRootLogin no

If you want to allow root login, but only by using key exchange, use PermitRootLogin prohibit-password

We can disable username/password logins and only allow key exchanges by changing PasswordAuthentication yes to PasswordAuthentication no

Disable weak SSH algorithms by inserting:

Ciphers -aes128-ctr,aes192-ctr,

KexAlgorithms ecdh-sha2-nistp384


Disable X11 Forwarding, which allows a GUI to spawn, by setting X11Forwarding yes to X11Forwarding no

Disable SSH tunnels, which allow other protocols to ride on SSH by setting:

AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no

Centralize all authorized_keys of all users by placing them in /etc/ssh/authorized-keys/<username>, and give them only read access. Configure /etc/ssh/sshd_config to add this line:

AuthorizedKeysFile      /etc/ssh/authorized-keys/%u

The %u at the back finds the right authorized_keys by using the username. Now even when the user adds their own authorized_keys in their home directory, it will be ignored.


SELinux operates by adding context to files and directories. We can see this when we run ls -Z

drwxrwxr-x. donnie donnie unconfined_u:object_r:user_home_t:s0 acl_demo_dir

This shows that the context type of this directory is user_home. The SELinux policy will define how context types can access each other.

We can change SELinux context using chcon, restorecon or semanage.

Two SElinux policies are required for a web server to run: httpd_unified and httpd_can_sendmail

If your site is not running cgi scripts, set sudo setsebool httpd_enable_cgi off

We can allow process to run on ports without giving them sudo access for privilege ports, by specifying the exact port in http_port_t: sudo semanage port -a 82 -t httpd_port_t -p tcp

Kernel and Processes

We can set a grub password to prevent users from editing kernel parameters by running sudo grub2-setpassword. The resulting password hash will be stored in /etc/grub2/user.cfg

We can disable the grub submenu, which allows users to boot into emergency mode that allows a password reset by placing GRUB_DISABLE_SUBMENU=true in /etc/default/grub

We can prevent users from seeing other process that they do not own by adding this line into /etc/fstab:

proc    /proc    proc    hidepid=2   0    0
sudo mount -o remount proc

We can allow a binary to have certain capabilities using setcap without running them as root and risk granting them too much permissions. e.g if python3 needs to run a server on privileged ports, instead of running sudo python3 -m http.server, which risks a breakout to a root shell, we can grant python3 capabilities to bind to ports using sudo setcap 'CAP_NET_BIND_SERVICE+ep' /usr/bin/python3

Security Checklist

We can simplify a lot of these work by using opensource tools such as OpenSCAP


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: