Master Linux Server Hardening: From Manual Steps to Automated Scripts
This comprehensive guide walks you through Linux server security hardening, covering real-world incident analysis, a detailed checklist of system, SSH, firewall, kernel and logging configurations, plus ready-to-use Bash scripts, Ansible playbooks, Docker hardening, monitoring tools, and actionable steps to build an enterprise‑grade defense.
Opening Horror: A Real Security Incident
At 3 am, alerts fired, CPU spiked, network traffic was abnormal, and a mining program was found due to a misconfigured SSH key.
Linux Security Hardening Checklist
System‑level Security Configuration
1. User Permission Management
# Check privileged users
awk -F: '$3 == 0 {print $1}' /etc/passwd
# Lock unnecessary system accounts
usermod -L daemon
usermod -L bin
usermod -L sys
usermod -L sync
# Set password policy
echo "PASS_MAX_DAYS 90" >> /etc/login.defs
echo "PASS_MIN_DAYS 1" >> /etc/login.defs
echo "PASS_WARN_AGE 7" >> /etc/login.defs2. SSH Security Hardening
# /etc/ssh/sshd_config key settings
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 3003. Firewall Configuration
# Basic iptables rules
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
iptables -I INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
iptables-save > /etc/iptables/rules.v4Service Security Configuration
4. Filesystem Security
# Set critical file permissions
chmod 644 /etc/passwd
chmod 600 /etc/shadow
chmod 644 /etc/group
chmod 600 /etc/gshadow
# Find SUID/SGID files
find / -type f \( -perm -4000 -o -perm -2000 \) -exec ls -l {} \;
# Secure /tmp
mount -o remount,noexec,nosuid,nodev /tmp5. Kernel Parameter Optimization
# /etc/sysctl.conf security settings
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2Monitoring and Auditing
6. Log Security Configuration
# rsyslog configuration
echo "*.* @@log-server:514" >> /etc/rsyslog.conf
# Set log file permissions
chmod 640 /var/log/messages
chmod 640 /var/log/secure
chmod 640 /var/log/maillog
# logrotate configuration
cat > /etc/logrotate.d/security <<EOF
/var/log/secure {
daily
rotate 90
compress
delaycompress
missingok
notifempty
create 640 root root
}
EOFOne‑Click Hardening Script
Core Automation Script
#!/bin/bash
# Linux Security Hardening Script
# Author: DevOps Engineer
# Version: 2.0
set -euo pipefail
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${GREEN}[${$(date +'%Y-%m-%d %H:%M:%S')} ] $1${NC}"; }
warn() { echo -e "${YELLOW}[WARNING] $1${NC}"; }
error() { echo -e "${RED}[ERROR] $1${NC}"; exit 1; }
# ... (functions: check_root, backup_configs, configure_ssh, configure_kernel, configure_firewall, harden_permissions, configure_services, install_security_tools, update_system, main)Advanced Automation with Ansible
Enterprise‑grade Playbook
---
- name: Linux Security Hardening Playbook
hosts: all
become: yes
vars:
ssh_port: 2222
backup_dir: "/root/security_backup_{{ ansible_date_time.epoch }}"
tasks:
- name: Create backup directory
file:
path: "{{ backup_dir }}"
state: directory
mode: '0700'
# ... (remaining tasks for SSH, kernel, firewall, services, tools)Security Audit Script: Automated Assessment
#!/bin/bash
# Security Audit Script
REPORT_FILE="/tmp/security_audit_$(date +%Y%m%d_%H%M%S).txt"
echo "=== Linux Security Audit Report ===" > "$REPORT_FILE"
echo "Generated: $(date)" >> "$REPORT_FILE"
# ... (user account checks, network services, file permissions, system integrity)
echo "Security audit completed. Report saved to: $REPORT_FILE"Real‑time Monitoring with Zabbix
#!/usr/bin/env python3
"""Security Monitoring Script for Zabbix"""
import subprocess, json, sys
from datetime import datetime
def check_failed_logins():
try:
result = subprocess.run(['grep','Failed password','/var/log/secure'], capture_output=True, text=True)
return len(result.stdout.splitlines())
except:
return 0
# ... (other metric functions)
def main():
metrics = {
'failed_logins': check_failed_logins(),
'root_logins': check_root_logins(),
'suspicious_processes': check_suspicious_processes(),
'disk_usage': check_disk_usage(),
'timestamp': datetime.now().isoformat()
}
print(json.dumps(metrics))
if __name__ == "__main__":
main()Docker‑based Deployment: Container Security Best Practices
# Security‑hardened base image
FROM alpine:3.18
# Create non‑root user
RUN addgroup -g 1001 appgroup && \
adduser -D -u 1001 -G appgroup appuser
# Install security tools
RUN apk add --no-cache sudo fail2ban logrotate && \
rm -rf /var/cache/apk/*
# Copy security configs
COPY security-configs/ /etc/
# Set file permissions
RUN chmod 600 /etc/ssh/sshd_config && \
chmod 644 /etc/sysctl.conf
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD pgrep -f "security_monitor" || exit 1
CMD ["/usr/local/bin/security_monitor.sh"]Kubernetes Security Extension (Cloud Native)
apiVersion: v1
kind: ConfigMap
metadata:
name: security-policies
data:
pod-security-policy.yaml: |
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
runAsUser:
rule: 'MustRunAsNonRoot'
fsGroup:
rule: 'RunAsAny'Practical Experience Sharing
Common Security Pitfalls
SSH key management : weak algorithms, wrong permissions, no rotation.
Firewall configuration : forgetting to save rules, wrong order, missing outbound control.
Log monitoring gaps : improper rotation, no real‑time alerts, overly permissive log file permissions.
Performance Optimization Tips
# Parallel file‑permission checks
find / -type f -perm -4000 -print0 | xargs -0 -P 4 ls -l
# Faster log analysis with ripgrep
apt-get install ripgrep
rg "Failed password" /var/log/secure --countFuture Trend: Cloud‑Native Security
Extending hardening practices to Kubernetes clusters with PodSecurityPolicies and other native controls.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Community
A leading IT operations community where professionals share and grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
