Skip to main content

Configuration Templates

Production-ready configuration files with security best practices and detailed comments. Copy, customize, and deploy.

SSH Hardening

Secure SSH configuration with key-based auth, fail2ban-friendly settings, and modern ciphers.

sshd_config
# /etc/ssh/sshd_config - Hardened SSH Configuration

# Network
Port 22
AddressFamily inet
ListenAddress 0.0.0.0

# Authentication
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes

# Limit users/groups
AllowGroups ssh-users admin

# Security
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no
MaxAuthTries 3
MaxSessions 5
ClientAliveInterval 300
ClientAliveCountMax 2

# Logging
SyslogFacility AUTH
LogLevel VERBOSE

# Modern ciphers only
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
sshsecurityhardening

Nginx Reverse Proxy

Production-ready Nginx configuration with SSL, security headers, and upstream proxy.

nginx.conf
# /etc/nginx/nginx.conf - Production Configuration

user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # Performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Security
    server_tokens off;
    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 "strict-origin-when-cross-origin" always;

    # SSL Settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Gzip
    gzip on;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript;

    # Rate Limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

    include /etc/nginx/conf.d/*.conf;
}
nginxwebserversslsecurity

fstab - NAS Mounts

CIFS/SMB mount configuration with credentials, proper options, and boot resilience.

fstab
# /etc/fstab - NAS Mount Configuration
# <device>  <mount>  <type>  <options>  <dump>  <pass>

# Root filesystem
UUID=abc123-def456  /  ext4  defaults  0  1

# CIFS/SMB Mounts - Using credentials file for security
# Create credentials file: /etc/cifs-credentials
# Contents:
#   username=your_user
#   password=your_pass
#   domain=WORKGROUP

# Media share - optimized for streaming
//10.42.0.10/media  /mnt/nas/media  cifs  credentials=/etc/cifs-credentials,uid=1000,gid=1000,iocharset=utf8,vers=3.0,_netdev,nofail,x-systemd.automount  0  0

# Backups - mounted on demand
//10.42.0.10/backups  /mnt/nas/backups  cifs  credentials=/etc/cifs-credentials,uid=1000,gid=1000,vers=3.0,_netdev,nofail,noauto,x-systemd.automount  0  0

# Downloads - high performance options
//10.42.0.10/downloads  /mnt/nas/downloads  cifs  credentials=/etc/cifs-credentials,uid=1000,gid=1000,vers=3.0,cache=loose,_netdev,nofail  0  0

# NFS Mount example
# 10.42.0.10:/volume1/data  /mnt/nfs/data  nfs4  rw,hard,intr,rsize=65536,wsize=65536,_netdev,nofail  0  0
fstabcifsnfsstoragenas

Traefik Static Config

Traefik static configuration with entrypoints, providers, and certificate resolvers.

traefik.yml
# /etc/traefik/traefik.yml - Static Configuration

global:
  checkNewVersion: false
  sendAnonymousUsage: false

log:
  level: INFO
  format: json

api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt
        domains:
          - main: "example.com"
            sans:
              - "*.example.com"

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 10s
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-public
  file:
    directory: /etc/traefik/dynamic
    watch: true
traefikreverse-proxysslnetworking

Prometheus Scrape Config

Prometheus configuration with job definitions for common homelab services.

prometheus.yml
# /etc/prometheus/prometheus.yml

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    cluster: homelab
    env: production

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093

rule_files:
  - /etc/prometheus/rules/*.yml

scrape_configs:
  # Prometheus self-monitoring
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Node Exporter - system metrics
  - job_name: 'node'
    static_configs:
      - targets:
        - 'node-exporter:9100'
        - '10.42.0.10:9100'
        - '10.42.0.11:9100'

  # Docker containers via cAdvisor
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

  # Traefik metrics
  - job_name: 'traefik'
    static_configs:
      - targets: ['traefik:8080']

  # Kubernetes API server (if using K3s/K8s)
  - job_name: 'kubernetes-apiservers'
    kubernetes_sd_configs:
      - role: endpoints
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    relabel_configs:
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name]
        action: keep
        regex: default;kubernetes
prometheusmonitoringmetrics

Fail2ban Jail Config

Fail2ban configuration for SSH, Nginx, and custom service protection.

jail.local
# /etc/fail2ban/jail.local

[DEFAULT]
# Ban settings
bantime = 1h
findtime = 10m
maxretry = 5

# Actions
banaction = iptables-multiport
action = %(action_mwl)s

# Email notifications
destemail = admin@example.com
sender = fail2ban@example.com
mta = sendmail

# Ignore local network
ignoreip = 127.0.0.1/8 ::1 10.42.0.0/24

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log

[nginx-botsearch]
enabled = true
filter = nginx-botsearch
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 2

[nginx-limit-req]
enabled = true
filter = nginx-limit-req
port = http,https
logpath = /var/log/nginx/error.log

# Traefik protection
[traefik-auth]
enabled = true
filter = traefik-auth
port = http,https
logpath = /var/log/traefik/access.log
maxretry = 5
fail2bansecurityfirewall