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.

Ops Community
Ops Community
Ops Community
Master Linux Server Hardening: From Manual Steps to Automated Scripts

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.defs

2. SSH Security Hardening

# /etc/ssh/sshd_config key settings
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300

3. 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.v4

Service 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 /tmp

5. 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 = 2

Monitoring 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
}
EOF

One‑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 --count

Future Trend: Cloud‑Native Security

Extending hardening practices to Kubernetes clusters with PodSecurityPolicies and other native controls.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

monitoringDockerLinuxAnsibleHardening
Ops Community
Written by

Ops Community

A leading IT operations community where professionals share and grow together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.