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 theadmin
group full access to the system -
john ALL=(ALL) /usr/bin/systemctl restart nginx
gives user john permission to run onlysystemctl 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/ownerg
: groupo
: othersa
: all
operator
can be:
+
: to add-
: to remove=
: to set
permission
can be:
r
: readw
: writex
: 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 ACLssetfacl
: 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 loggingPermissive
: No enforcement, but logs policy violationsEnforcing
: 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
.