Skip to content

Linux: OS Hardening

sudo Configuration

sudo = Super User Do

sudo allows regular users to execute commands with elevated root privileges.

visudo

visudo is the tool used to edit the sudo configuration. The main configuration is at /etc/sudoers. Additional configuration files are stored in /etc/sudoers.d. It is highly recommended to use visudo because it prevents saving invalid configuration.

  • -c checks syntax of sudoers file without editing

  • -f <CONFIG FILE PATH> specifies a different file to edit with visudo

  • -s runs the editor in strict mode

  • -x exports the sudoers file in JSON format for automation or auditing

wheel group

The wheel group is a special group commonly used in Linux systems to grant its members permission to run administrative command with sudo. ex sudo usermod -aG wheel john

/etc/sudoers

/etc/sudoers is the main config file accessed by visudo.

  • admin ALL=(ALL) ALL give users in the admin group full access to the system

  • john ALL=(ALL) /usr/bin/systemctl restart nginx gives user john permission to run only systemctl restart nginx

/etc/sudoers.d

/etc/sudoers.d allows admins to break up sudo configurations into multiple smaller files. That is helpful in enterprise environments with different levels of access needs, supporting automation tools like Ansible or Puppet.

sudoers Directives

  • NOPASSWD allows users to run sudo commands without being prompted for their password. It should be used with care in production environment to prevent accidental misuse.
# to not prompt tom for a sudo password
tom ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart nginx
  • NOEXEC prevents the approved user sudo commands from launching additional programs or subshells from within a sudo-allowed command. NOEXEC restricts behavior by disabling the ability of the command to spawn other processes.
# to not prompt tom for a sudo password
kyle ALL=(ALL) NOEXEC:/usr/bin/less /var/log/syslog

sudo User Groups

  • sudo group: used in Debian-based systems like Ubuntu

  • wheel group: used in RHEL-based systems

sudo Group

# to add a user to the sudo group
sudo usermod -aG sudo amy

wheel Group

It serves the same purpose has the sudo group in RHEL-based systems.

# to add a user to the wheel group
sudo usermod -aG wheel amy

sudo -i

sudo -i opens a full root shell for users with sudo privileges from the sudo or wheel group. If the sudo config contains %sudo ALL=(ALL:ALL) ALL or %wheel ALL=(ALL:ALL) ALL any user in those group can elevate their permission to full root user with sudo -i.

Root Shell

sudo su - switch to the root user role entirely. su stands for substitute user

File Attributes

File attributes provide an extra layer of control that goes beyond the standard file permissions.

lsattr

lsattr allows viewing a file's current attributes.

# to view a file attributes
lsattr my-important-file.txt

Useful options:

  • -R list attributes recursively in subdirectories

  • -a includes hidden files

  • -d shows directory attributes instead of their contents

  • -v shows the version number of the file if supported

# to view attributes of all files in a directory including hidden files
lsattr -a -d -R /etc/config

Output may look like:

----i--------e-- /etc/config/setting.conf
-----a--------e-- /etc/config/logs.log

The i indicate that the file is immutable.

The a indicate that the file is append only.

chattr

chattr allows changing a file's attributes.

Common options include:

  • -R to apply changes recursively to directories and contents

  • -v to work with file's versioning

  • +i to set a file as immutable

  • -i to remove a file from immutable mode

# to protect a script from being modified or deleted
chattr +i /usr/local/bin/m_script.sh

# to remove immutable protection
chattr -i /usr/local/bin/m_script.sh

# to protect a directory from being modified or deleted
chattr -R +i /usr/local/bin/scripts/

File Permissions

chown

chown is used to change the ownership of a file and can also change its associated group at the same time. The general syntax is chown [OPTIONS] <NEW OWNER>[:NEW GROUP] file. -R option applies the change recursively to all files and subdirectories.

# to change the owner and group of a folder
chown -R tyler:accounting /data/reports

chgrp

chgrp focusses specifically on changing the group ownership of a file without affecting the user ownership. The general syntax is chgrp [OPTIONS] <NEW GROUP> file.

# to change the group ownership of a directory
chgrp -R admins /scripts

File Modifications

chmod (change mode)

chmod allows changing file permissions by specifying user class and permission ot add, remove, or set. The general is chmod [who][operator][permission] file.

who can be:

  • u: user/owner
  • g: group
  • o: others
  • a: all

operator can be:

  • +: to add
  • -: to remove
  • =: to set

permission can be:

  • r: read
  • w: write
  • x: execute
# to give execute permission to a file
chmod u+x script.sh

chmod using Octal Notation

  • Read: 4
  • Write: 2
  • Execute: 1

The general syntax is chmod [mode] <FILE>.

# to give rwx permission to user, rx to group, and r to others
chmod 754 config.conf

File Special Permissions

Special permissions temporarily grant users additional access on certain conditions. There are mainly 3 special permissions: setuid, setgid, and the sticky bit.

setuid (Set User ID)

setuid allows a program to run with the privilege of the file's owner. The general syntax is chmod u+s <FILE>.

chmod u+s /scripts/run.sh

setgid

setgid is similar to setuid but focuses on group ownership. Files and subdirectories created inherit the group ownership of the directory. The general syntax is chmod g+s <FILE OR DIRECTORY>.

# to set the setgid of a folder
chmod g+s /data/

# to set of files and directories in a direct to belong to the same group
chgrp admins /shared/scripts && chmod g+s /shared/scripts

sticky bit

The sticky bit is a special permission used on shared directories to prevent deletion or renaming of files not owned. The general syntax of the sticky bit is chmod +t <DIRECTORY>.

# to make users be able to delete their own files only
chmod +t /shared

Default File Creation Mask

umask (User File Creation Mask)

The umask defines which permission bits should be masked out or removed from the system's default permissions when a new file or directory is created.

New files begin with a default permissions or 666 for user, group, and others. New directories start with the default permissions of 777.

umask 022 removes the write bit (value 2) from the group and others permission sets:

666 - 022 = 644 => rw-r-r for new files

777 - 022 = 755 => rwxr-xr-x for new directories

# to see the umask value
umask

# to remove all access for others and write access for the group
# 640 for new files and 750 for directories
umask 027

To make the change permanent, the command can be added to user's shell config in .bashrc or .profile.

Access Control Lists - ACLs

ACLs give more flexibility that file permission controls. It provides detailed file permission management by specifying unique access rights for individual users and groups beyond owner, group, and others. Two main commands are used to manage ACLs:

  • getfacl: to display current ACLs
  • setfacl: to modify or add new ACL entries

getfacl

getfacl is used to view ACL entries on files or directories. The general syntax is getfacl [OPTIONS] <FILE OR DIRECTORY>. -R allows displaying ACLs recursively.

ex:

# to view ACLs of directory and its content
getfacl -R data/

setfacl

setfacl is used to create or modify ACL entries, allowing admins to fine-tune file access. The general syntax is setfacl [OPTIONS] <PERMISSION> [FILE OR DIRECTORY].

Common options:

  • -m to modify or add an entry
  • -x to remove an entry
  • -R to apply changes recursively

ex:

# to give a user permission to rw a file via ACL
setfacl -m u:tom:rw config.conf

# to remove the ACL entry
setfacl -x u:tom config.conf

# to reset a file to use standard permissions
setfacl -b config.conf

# to set default ACL on a directory for new files to inherit
setfacl -d -m u:tyler:rw /data/reports

SELinux States

SELinux = Security-Enhanced Linux.

SELinux can be in one of the three states:

  • Disabled: No policy enforcement or logging
  • Permissive: No enforcement, but logs policy violations
  • Enforcing: Enforces policies and blocks unauthorized actions

SELinux - Disabled State

This mode is typically used for troubleshooting in extreme cases or when SELinux is not needed in a particular environment. SELinux configuration is located at /etc/selinux/config. Set SELINUX=disabled to disable SELinux. A reboot to required for the change to take effect.

# to view SELinux state
getenforce

SELinux - Permissive State

In this state, SELinux will log action violations that would have been blocked.

# to temporarily set SELinux to permissive without reboot
setenforce 0

The change can be made persistent after reboot by editing /etc/selinux/config with the value SELINUX=permissive.

SELinux - Enforcing State

This is the default and most secured state. It is ideal for production environments.

# to temporarily set SELinux to enforcing without reboot
setenforce 1

Update /etc/selinux/config and set SELINUX=enforcing to make the change persistent after reboot.

SELinux File Security Contexts

To work with SELinux File Security Contexts, Linux provides 3 commands:

ls -Z

ls -Z is used to display the current SELinux context for files and directories with and added column showing context label including SELinux user, role, type, and level. The User part represent the SELinux user identity, such as system_u for system processes or unconfined_u for users not strictly controlled by SELinux. The Role part defines permissions available to process or user in a context such as object_r for files and directories. The Type part is the most important part of the context describing object purpose and used by SELinux policies to grant or deny access.

restorecon

restorecon is used to restore the default context of a file or directory based on SELinux policy. The general context is restorecon [OPTIONS] <PATH>.

# to recursively restore files context
restorecon -Rv /var/www/html

chcon

chcon is used to allow manual changes to a file context when necessary. The general syntax is chcon [OPTIONS] <FILE>.

Common options include:

  • -u to set the user
  • -r to set the role
  • -t to set the type
# to manually label a file for webserver access
chcon -u system_u -r object_r -t httpd_sys_context_t index.html

# then check with 
ls -Z index.html

SELinux System-wide Configuration

getsebool

getsebool check the current status of SELinux booleans, which are special on/off switches that control how strict or flexible SELinux is in certain situations.

# to list all booleans
getsebool -a

# to view a selected boolean
getsebool antivirus_can_scan_system

# to see whether webserver is allowed to access user home directories
getsebool httpd_enable_homedirs

# to view whether FTP services are allowed to access users's home directories
getsebool ftp_home_dir

# to view whether Apache webserver can initiate outbound network connections
getsebool httpd_can_network_connect

# to see whether the Samba file sharing service can share users's home directories over the network
getsebool samba_enable_home_dirs

setsebool

setsebool is used to turn a specific boolean on or off, and optionally make that change permanent across reboot. The general syntax is setsebool [-P] <BOOLEAN NAME> on|off. -P makes the change persist across reboots.

# to allow webserver to serve content from user directories
setsebool -P httpd_enable_homedirs on

# to allow Apache to connect to network services
setsebool -P httpd_can_network_connect on

semanage

semanage is used for managing SELinux settings persistently, including booleans, port contexts, and file labels. The general syntax for working with booleans is semanage boolean -m --on|--off <BOOLEAN NAME>.

semanage boolean -m --on httpd_enable_homedirs

Port Contexts are used to allow a service such as web or mail server to operate on a non-default port.

File Labels are used to define how SELinux should treat specific files or directories on the system.

SELinux Logging and Troubleshooting

sealert

sealert reads SELinux audit logs and provides clear, human-readable summaries of what denied and why. The logs are usually stored in /var/log/audit/audit.log. The general syntax is sealert -a <LOG PATH>.

# to read review SELinux relater logs
sealert -a /var/log/audit/audit.log

audit2allow

audit2allow is a tool that helps generate new policy rules based on denials to resolve issues by safely expanding SELinux policy when appropriate. The basic syntax is audit2allow -a that analyzes all current logs in the system's audit log. Alternatively audit2allow -i <LOG PATH>.

SSHD Secure Authentication and Access Control

SSHD: Secure Shell Daemon

Key vs Password Authentication

Password authentication requires users to type their password every time they login.

Key based authentication uses a private/public key pair for secure login. Key-based can be enforced by setting PasswordAuthentication no in /etc/ssh/sshd_config, then restart the service for the change to take effect.

PermitRootLogin

This controls whether the root user can login via SSH. It is common to disable this feature to reduce potential attack vectors. To disable this feature, set PermitRootLogin no in sshd_config.

AllowUsers

AllowUsers restricts SSH login to specific users.

# to edit the config
nano /etc/ssh/sshd_config

# allow user to login via ssh and block everybody else
AllowUsers tom tyler jessica@ws1

AllowGroups

AllowGroups allows SSH login for members of a specific group.

# allow ssh login to members of selected groups only
AllowGroups sshusers

SSHD Secure Configuration and Usage

Disabling X11 Forwarding

X11 allows graphical applications to be run on a remote system but displayed on the local machine. To disable it set X11Forwarding no in /etc/ssh/sshd_config, then restart sshd service to apply the changes

SSH Tunneling

Routes traffic through an encrypted SSH connection for securely accessing internal web applications or databases not exposed to the internet.

Secure Remote Access

SSH Agent

The SSH agent is a daemon that stores decrypted private keys in memory to avoid retyping the passphrase for each server connection.

# to load keys into daemon
ssh-add ~/.ssh/id_rsa

SFTP with chroot

A key aspect of secure remote access focused on controlling user interaction with the system during file transfers. SFTP with chroot restricts filesystem access during encrypted file transfer using SFTP.

# to limit sftp users to their designated directories
Match Group sftpusers
  ChrootDirectory /home/sftp/%u
  ForceCommand internal-sftp
  X11Forwarding no
  AllowTcpForwarding no

fail2ban

fail2ban is a security tool used on Linux systems that automatically blocks IP addresses which show signs of suspicious activity.

Configuration

The main config is located in /etc/fail2ban/jail.conf. It is advised to no change that file but to make a copy then change the copy like /etc/fail2ban/jail.local.

Each section in the configuration is called a jail. Each jail correspond a specific service such as ssh.

ex:

# to monitor ssh fail login attempt and block if necessary
[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime  = 10800

Restart the service to apply the changes with systemctl restart fail2ban.

Monitoring

The main log is located in /var/log/fail2ban.log

Triggering

Simulate triggering by simulating fail login attempts.

# to detect which IP address have been banned
fail2ban-client status sshd

Unblocking

fail2ban-client set [JAIL] unbanip [IP ADDRESS]

# to unblock an ip address
fail2ban-client set sshd unbanip 203.204.205.206

Avoid Unsecure Services

Telnet

Telnet sends everything in plain text without encryption. it has been replaced by SSH.

# to disable telnet
systemctl disable --now telnet.socket

# remove telnet package
dnf remove telnet

FTP

FTP transmit credentials and files in plain text. SFTP (Secure FTP using SSH) and FTPS (FTP over TLS) are secure alternatives.

# to disable ftp 
systemctl disable --now vsftpd

# remove the package
dnf remove vsftpd

TFTP

TFTP has no authentication and no encryption. SCP and SFTP are secure alternatives.

# to disable tftp
systemctl disable --now tftpd

# remove the package
apt remove tftp-hpa
dnf remove tftp-server

Disable Unused File Systems

Linux often comes with rarely used filesystems.

Disabling filesystem by disabling kernel modules

  • cramfs
  • hfs
  • udf

To disable them, edit or create a config file in /etc/modprobe.d/ and add line install cramfs /bin/false.

# /etc/modprobe.d/cramfs.conf
install cramfs /bin/false
# /etc/modprobe.d/hfs.conf
install hfs /bin/false
# /etc/modprobe.d/udf.conf
install udf /bin/false

Disabling filesystem by editing fstab

fstab tells Linux which file systems to automatically mount at boot time. Outdated entries in fstab file can create security risks. Disable unnecessary lines placing a # at the beginning.

Unnecessary SUID Permissions

SUID bit

SUID (Set User ID) bit is a special file permission that can be applied to executable files. Setting the SUID bit in the wrong executable can be a security risk.

# to look for SUID bit file: -rwsr-xr-x. The 's' indicates that SUID bit is set
ls -l 

SUID binaries

SUID binaries are the programs or executables that have the SUID bit set.

# to search entire root file system for all files with SUID bit set
find / -perm -4000 -type f 2>/dev/null

# remove the SUID bit
chmod u-s /usr/bin/rcp

Secure Boot

Secure Boot is a feature designed to prevent unauthorized or malicious code from running during the system's startup process.

UEFI

UEFI = Unified Extensible Firmware Interface. It is the modern replacement for the older BIOS system that was used for decades to initialize hardware and start the operating system.

Secure boot can be configured via the UEFI menu with F2, Del, or Esc.