Security Hardening Guide
Security Hardening Guide
Comprehensive guide for hardening systems, applications, and infrastructure components against security threats.
Hardening Overview
Security hardening reduces the attack surface by eliminating unnecessary services, applying security configurations, and implementing defense mechanisms.
Hardening Objectives
- Minimize Attack Surface: Remove unnecessary components
- Apply Security Defaults: Secure configurations out of the box
- Enable Security Features: Activate built-in protections
- Continuous Compliance: Maintain security posture over time
Operating System Hardening
Linux Hardening
Initial System Setup:
#!/bin/bash
# Linux hardening script
# Update system
apt update && apt upgrade -y
# Install essential security tools
apt install -y fail2ban ufw aide auditd rsyslog apparmor-utils
# Configure automatic updates
cat > /etc/apt/apt.conf.d/50unattended-upgrades << EOF
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
EOF
# Enable unattended upgrades
echo 'APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";' > /etc/apt/apt.conf.d/20auto-upgrades
User Account Hardening:
# Password policies (/etc/pam.d/common-password)
password requisite pam_pwquality.so retry=3 minlen=14 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1
# Account lockout (/etc/pam.d/common-auth)
auth required pam_tally2.so onerr=fail audit silent deny=5 unlock_time=900
# Secure shell limits (/etc/security/limits.conf)
* hard core 0
* hard maxlogins 3
* hard maxsyslogins 3
# Disable unused accounts
usermod -L -e 1 unused_account
# Set password aging
chage -M 90 -m 7 -W 14 username
Windows Hardening
PowerShell Hardening Script:
# Windows Server hardening
# Run as Administrator
# Enable Windows Defender
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -DisableBehaviorMonitoring $false
Set-MpPreference -DisableIOAVProtection $false
Set-MpPreference -DisablePrivacyMode $false
# Configure Windows Firewall
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
Set-NetFirewallProfile -DefaultInboundAction Block -DefaultOutboundAction Allow
# Disable unnecessary services
$services = @('Spooler', 'RemoteRegistry', 'Fax', 'CscService')
foreach ($service in $services) {
Stop-Service -Name $service -Force -ErrorAction SilentlyContinue
Set-Service -Name $service -StartupType Disabled
}
# Enable audit policies
auditpol /set /category:"Account Logon" /success:enable /failure:enable
auditpol /set /category:"Account Management" /success:enable /failure:enable
auditpol /set /category:"Logon/Logoff" /success:enable /failure:enable
Network Service Hardening
SSH Hardening
# /etc/ssh/sshd_config
Port 2222
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# Authentication
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
# Security restrictions
MaxAuthTries 3
MaxSessions 2
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
X11Forwarding no
AllowUsers [email protected]/8
# Crypto settings
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected]
KexAlgorithms curve25519-sha256,[email protected]
Web Server Hardening
Nginx Hardening:
# nginx.conf security settings
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Hide version
server_tokens off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
# Limits
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
# Timeouts
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
# Limit connections
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10;
}
Database Hardening
PostgreSQL Hardening
# postgresql.conf
# Connection settings
listen_addresses = 'localhost,10.0.0.5'
port = 5432
max_connections = 100
# Authentication
password_encryption = scram-sha-256
# SSL
ssl = on
ssl_cert_file = '/etc/postgresql/server.crt'
ssl_key_file = '/etc/postgresql/server.key'
ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
ssl_prefer_server_ciphers = on
ssl_min_protocol_version = 'TLSv1.2'
# Logging
log_connections = on
log_disconnections = on
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_statement = 'ddl'
log_min_duration_statement = 1000
# pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
local all all scram-sha-256
hostssl all all 10.0.0.0/24 scram-sha-256
host all all 127.0.0.1/32 reject
MySQL Hardening
# Run mysql_secure_installation first, then:
# my.cnf
[mysqld]
# Network
bind-address = 127.0.0.1
skip-networking = 0
port = 3306
# Security
local_infile = 0
skip-symbolic-links = 1
sql_mode = TRADITIONAL
secure_file_priv = /var/lib/mysql-files/
# SSL/TLS
require_secure_transport = ON
ssl-ca = /etc/mysql/ca.pem
ssl-cert = /etc/mysql/server-cert.pem
ssl-key = /etc/mysql/server-key.pem
# Logging
general_log = 0
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# Remove anonymous users and test database
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.db WHERE Db='test' OR Db='test_%';
FLUSH PRIVILEGES;
Container Hardening
Docker Security
# Docker daemon configuration (/etc/docker/daemon.json)
{
"icc": false,
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://127.0.0.1:514"
},
"userland-proxy": false,
"no-new-privileges": true,
"selinux-enabled": true,
"userns-remap": "default",
"live-restore": true,
"seccomp-profile": "/etc/docker/seccomp/default.json"
}
# Dockerfile best practices
FROM alpine:3.15
RUN apk add --no-cache python3 py3-pip
RUN adduser -D -s /bin/ash appuser
USER appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
RUN pip3 install --user -r requirements.txt
EXPOSE 8080
ENTRYPOINT ["python3", "app.py"]
Kubernetes Hardening
# Pod Security Policy
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
rule: 'MustRunAsNonRoot'
seLinux:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'
readOnlyRootFilesystem: true
Application Hardening
Runtime Application Self-Protection (RASP)
- Input validation at runtime
- SQL injection prevention
- XSS protection
- Behavior monitoring
Secure Coding Configuration
# Example security.yml for Spring Boot
security:
headers:
frame-options: DENY
xss-protection: "1; mode=block"
content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
content-security-policy: "default-src 'self'"
csrf:
enabled: true
sessions:
timeout: 900
concurrent-sessions: 1
password:
encoder: bcrypt
strength: 12
Compliance Scanning
CIS Benchmark Implementation
# Install and run CIS-CAT
wget https://cisecurity.org/cis-cat-lite
chmod +x cis-cat-lite
./cis-cat-lite -b benchmarks/CIS_Ubuntu_20.04_Benchmark_v1.0.0.xml
# OpenSCAP for continuous compliance
apt install openscap-scanner
oscap xccdf eval --profile xccdf_org.ssgproject.content_profile_cis \
--results results.xml \
--report report.html \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2004-ds.xml
Automated Hardening Tools
Tool | Platform | Purpose |
---|---|---|
Lynis | Linux/Unix | Security auditing and hardening |
Bastille | Linux | Automated hardening |
HardeningKitty | Windows | Windows hardening automation |
DevSec Hardening | Multi-platform | Ansible/Chef/Puppet roles |
Monitoring Hardened Systems
Security Monitoring
- File integrity monitoring (FIM)
- Configuration drift detection
- Compliance status dashboards
- Security event correlation
Audit Configuration
# auditd rules (/etc/audit/rules.d/hardening.rules)
# Monitor authentication
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes
-w /etc/sudoers -p wa -k sudoers_changes
# Monitor system calls
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -k perm_mod
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -k owner_mod
# Monitor network connections
-a always,exit -F arch=b64 -S socket,connect,accept,bind -k network_conn
Hardening Verification
Verification Checklist
- □ All default passwords changed
- □ Unnecessary services disabled
- □ Security patches applied
- □ Firewall rules configured
- □ Audit logging enabled
- □ File permissions restricted
- □ Network services minimized
- □ Security tools installed
Penetration Testing
- Run vulnerability scans
- Attempt privilege escalation
- Test network segmentation
- Verify security controls
Best Practices
- Automate: Use configuration management for consistency
- Document: Keep hardening procedures updated
- Test: Verify hardening doesn't break functionality
- Monitor: Continuous compliance monitoring
- Update: Regular reviews and updates
Related Resources
Note: This documentation is provided for reference purposes only. It reflects general best practices and industry-aligned guidelines, and any examples, claims, or recommendations are intended as illustrative—not definitive or binding.