Practical security checklist for production Linux environments
Linux is everywhere.
It powers:
- cloud infrastructure,
- web servers,
- Kubernetes nodes,
- databases,
- network appliances,
- security platforms.
Many administrators believe that Linux is secure by default.
The reality is different.
Linux provides powerful security mechanisms, but they must be correctly configured.
A fresh installation is only the beginning.
A production server should go through a hardening process:
Fresh Linux Installation
↓
System Updates
↓
Kernel Security
↓
User Management
↓
Network Protection
↓
Service Hardening
↓
Monitoring
↓
Continuous Auditing
What is Linux Hardening?
Linux hardening is the process of reducing the attack surface of a Linux system.
The goal is simple:
Allow only required functionality and block everything unnecessary.
A hardened server should follow:
Principle of Least Privilege
Every user, process and service receives only the permissions it needs.
Example:
Bad:
Web Application
↓
root privileges
↓
Entire system access
Better:
Web Application
↓
Dedicated user
↓
Limited permissions
1. Keep the System Updated
The first security layer is patch management.
Check available updates:
Debian/Ubuntu:
apt update
apt upgrade
RHEL/Fedora:
dnf update
For production environments:
Do not update randomly.
Use:
Testing
↓
Staging
↓
Production
A security update should improve protection without breaking applications.
2. Remove Unnecessary Services
Every running service is a potential entry point.
Check running services:
systemctl list-units --type=service
Example:
A server hosting a website probably does not need:
Bluetooth
Printing service
Avahi discovery
Unused databases
Disable unnecessary services:
systemctl disable service_name
systemctl stop service_name
Security rule:
If a service is not required, remove it.
3. Secure SSH Access
SSH is one of the most attacked services on Linux servers.
Basic hardening:
Edit:
/etc/ssh/sshd_config
Disable root login:
PermitRootLogin no
Disable password authentication:
PasswordAuthentication no
Use keys:
Public Key Authentication
Example:
ssh-keygen -t ed25519
Modern SSH authentication should look like:
User
↓
SSH Key
↓
Server Verification
↓
Access Granted
4. Protect SSH Against Brute Force
Install:
fail2ban
Example:
apt install fail2ban
Architecture:
Failed Login Attempts
↓
Fail2ban
↓
Firewall Rule
↓
IP Block
However, blocking attackers is only one layer.
The better approach:
- disable passwords,
- use MFA,
- restrict access by firewall.
5. Configure Firewall Rules
A server should not expose unnecessary ports.
Check listening services:
ss -tulpn
Example output:
22/tcp SSH
80/tcp HTTP
443/tcp HTTPS
Everything else should be reviewed.
Example using nftables:
nft list ruleset
Security model:
Internet
↓
Firewall
↓
Allowed Services Only
↓
Application
6. Use Mandatory Access Control
Traditional permissions:
User
↓
Group
↓
File permissions
are not always enough.
Linux provides:
SELinux
Common in:
- Red Hat Enterprise Linux,
- CentOS,
- Fedora.
Example:
getenforce
AppArmor
Common in:
- Ubuntu,
- Debian.
Check profiles:
aa-status
These systems answer:
What is a process allowed to do, even if it is compromised?
7. Kernel Hardening
The Linux kernel is the foundation.
Check kernel version:
uname -r
Important mechanisms:
Kernel parameters
Example:
/etc/sysctl.conf
Disable IP forwarding:
net.ipv4.ip_forward=0
Protect against SYN attacks:
net.ipv4.tcp_syncookies=1
Apply:
sysctl -p
8. Secure User Accounts
Review users:
cat /etc/passwd
Find accounts with shells:
cat /etc/passwd | grep bash
Remove unused accounts:
userdel username
Check sudo privileges:
cat /etc/sudoers
Avoid:
ALL=(ALL) ALL
for unnecessary users.
9. Filesystem Security
Important directories:
/etc
/bin
/usr
/var
/home
Check permissions:
ls -la
Sensitive files:
/etc/shadow
should be:
-rw-r-----
not:
-rw-rw-rw-
10. Use Secure Mount Options
Example:
Temporary filesystem:
/tmp
can use:
nodev
nosuid
noexec
Meaning:
nodev
No device files.
nosuid
Ignore SUID bits.
noexec
Prevent execution.
Example:
/dev/sdb1 /tmp ext4 defaults,nodev,nosuid,noexec
11. Audit System Activity
Security without visibility is impossible.
Linux provides:
auditd
Install:
apt install auditd
Check status:
systemctl status auditd
Example events:
User login
↓
File modification
↓
Privilege change
↓
Audit record
12. Centralize Logs
System logs are critical.
Modern Linux uses:
systemd-journald
Check logs:
journalctl
Examples:
SSH logs:
journalctl -u ssh
Kernel messages:
journalctl -k
Production environments usually forward logs to:
- SIEM,
- Elasticsearch,
- Graylog,
- Splunk.
13. Container Security on Linux Hosts
Modern Linux servers often run containers.
Docker security should include:
Rootless containers
Instead of:
root
↓
Docker daemon
↓
Container
Use:
User
↓
Rootless Docker
↓
Container
Seccomp
Limit system calls:
Allowed:
read()
write()
open()
Blocked:
mount()
ptrace()
cgroups v2
Control:
- CPU,
- RAM,
- processes.
Example:
Container
↓
Memory limit
↓
Host protection
14. Backup and Recovery
Security is incomplete without recovery.
A ransomware attack changes the question:
Not:
Can we prevent every attack?
But:
How quickly can we recover?
Backup strategy:
Production
↓
Backup
↓
Offline Copy
↓
Recovery Test
15. Automated Security Auditing
Manual checks are not enough.
Useful tools:
Lynis
Linux security auditing:
lynis audit system
OpenSCAP
Compliance scanning:
- CIS Benchmarks,
- security policies.
Docker Bench Security
Container security auditing.
Linux Hardening Checklist
System
✅ Updates enabled
✅ Unused packages removed
✅ Services reviewed
✅ Time synchronization configured
Authentication
✅ SSH keys
✅ Root login disabled
✅ MFA where possible
✅ Password policies
Network
✅ Firewall enabled
✅ Minimal open ports
✅ Network monitoring
Kernel
✅ sysctl hardening
✅ Secure parameters
✅ Updated kernel
Filesystem
✅ Correct permissions
✅ Secure mounts
✅ Encryption where required
Monitoring
✅ auditd
✅ journald
✅ Central logging
✅ Alerts
Final Thoughts
Linux is not secure because it is Linux.
Linux is secure because it provides the tools required to build a secure system.
The difference between a normal Linux server and a production security-grade server is configuration.
A mature security approach combines:
Linux Hardening
+
Firewall
+
SELinux/AppArmor
+
Audit Logging
+
Container Security
+
Monitoring
+
Regular Testing
Security is not a single command.
It is a continuous process of reducing risk, monitoring changes and improving the system over time.
Tags:
#Linux
#CyberSecurity
#DevSecOps
#LinuxSecurity
#SystemAdministration
#Hardening
#InfrastructureSecurity
#CloudSecurity
Top comments (1)
Solid checklist. The one thing I'd promote from "item #11" to load-bearing: auditd and local logs are only worth anything if they're immutable and already off the box before you need them. A checklist quietly assumes the attacker isn't root yet, but auditd, local log files, and filesystem perms are exactly the controls you lean on after a compromise — and a local auditd that root can turn off with
auditctl -e 0, or whose logs they can truncate, is theater. Set the audit config immutable (-e 2, so rules can't change until reboot) and ship logs push-only to a separate trust domain, so root-on-the-host doesn't also mean root-on-the-evidence. Same reasoning is why the key-only SSH line matters more than fail2ban — one actually closes the door, the other just trims the noise from people rattling it.