Entrada

Nginx: Configuración y Optimización para Producción

Nginx: Configuración y Optimización para Producción

Nginx se ha consolidado como uno de los servidores web más populares del mundo, especialmente conocido por su alta performance y bajo consumo de recursos. En esta guía aprenderás desde la instalación básica hasta configuraciones avanzadas para entornos de producción.

🎯 Objetivo: Dominar Nginx desde configuraciones básicas hasta técnicas avanzadas de optimización para manejar miles de conexiones concurrentes.

🏗️ Arquitectura de Nginx: ¿Por qué es tan eficiente?

Modelo de procesos: Master + Workers

Nginx utiliza una arquitectura multiproceso que lo hace extremadamente eficiente:

1
2
3
4
5
Master Process (root)
├── Worker Process 1
├── Worker Process 2
├── Worker Process N
└── Cache Manager Process

Master Process:

  • Gestiona workers
  • Lee configuración
  • Maneja señales del sistema
  • No procesa conexiones de clientes

Worker Processes:

  • Procesan conexiones de clientes
  • Un worker por núcleo de CPU (recomendado)
  • Event-driven architecture
  • Non-blocking I/O

Event-driven vs Thread-based

Apache (tradicional):

1
2
1 Thread = 1 Conexión
1000 conexiones = 1000 threads

Nginx:

1
2
1 Worker = N conexiones (miles)
Event loop maneja todas las conexiones

Ventajas del modelo Nginx:

  • Menor uso de memoria: No threads por conexión
  • Mejor escalabilidad: C10K problem solved
  • CPU efficiency: No context switching masivo

📦 Instalación y configuración inicial

Instalación en diferentes distribuciones

Ubuntu/Debian:

1
2
3
4
5
# Repositorio oficial de Nginx
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
echo "deb https://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx

CentOS/RHEL:

1
2
3
4
5
6
7
8
9
10
11
12
# Añadir repositorio oficial
sudo cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx]
name=nginx repo
baseurl=https://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF

sudo yum update
sudo yum install nginx

Compilación desde fuente (máximo control):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Dependencias
sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev

# Descargar y compilar
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# Configurar con módulos específicos
./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --conf-path=/etc/nginx/nginx.conf \
    --with-http_ssl_module \
    --with-http_v2_module \
    --with-http_gzip_static_module \
    --with-http_realip_module

make && sudo make install

Estructura de directorios

1
2
3
4
5
6
7
/etc/nginx/
├── nginx.conf              # Configuración principal
├── conf.d/                 # Configuraciones adicionales
├── sites-available/        # Sitios disponibles
├── sites-enabled/          # Sitios activos (symlinks)
├── snippets/              # Fragmentos reutilizables
└── ssl/                   # Certificados SSL

⚙️ Configuración básica optimizada

nginx.conf base para producción

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# /etc/nginx/nginx.conf

# Usuario que ejecuta nginx
user nginx;

# Un worker por núcleo de CPU
worker_processes auto;

# Máximo número de file descriptors
worker_rlimit_nofile 65535;

# PID del proceso master
pid /var/run/nginx.pid;

# Configuración de eventos
events {
    # Método de manejo de eventos (Linux)
    use epoll;
    
    # Conexiones simultáneas por worker
    worker_connections 1024;
    
    # Aceptar múltiples conexiones
    multi_accept on;
}

http {
    # Tipos MIME
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    
    # Optimizaciones de red
    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;
    
    # Timeouts
    keepalive_timeout  65;
    client_header_timeout 10;
    client_body_timeout 10;
    send_timeout 10;
    
    # Buffer sizes
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k;
    client_max_body_size 20M;
    
    # Compresión Gzip
    gzip on;
    gzip_vary on;
    gzip_min_length 1000;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/javascript
        application/xml+rss
        application/json;
    
    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
    
    # Logs
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    error_log /var/log/nginx/error.log warn;
    
    # Incluir configuraciones de sitios
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Virtual Host optimizado

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# /etc/nginx/sites-available/ejemplo.com
server {
    listen 80;
    listen [::]:80;
    server_name ejemplo.com www.ejemplo.com;
    
    # Redirección HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name ejemplo.com www.ejemplo.com;
    
    # Directorio raíz
    root /var/www/ejemplo.com;
    index index.html index.htm index.php;
    
    # SSL Configuration
    ssl_certificate /etc/nginx/ssl/ejemplo.com.crt;
    ssl_certificate_key /etc/nginx/ssl/ejemplo.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # 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 Strict-Transport-Security "max-age=63072000" always;
    
    # Rate limiting
    limit_req zone=api burst=20 nodelay;
    limit_conn conn_limit_per_ip 10;
    
    # Cache estatico
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # PHP processing
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        
        # Cache FastCGI
        fastcgi_cache_valid 200 60m;
        fastcgi_cache_bypass $skip_cache;
        fastcgi_no_cache $skip_cache;
    }
    
    # Denegar archivos sensibles
    location ~ /\. {
        deny all;
    }
    
    # Logs específicos del sitio
    access_log /var/log/nginx/ejemplo.com.access.log;
    error_log /var/log/nginx/ejemplo.com.error.log;
}

🚀 Optimización para alta carga

Worker processes y connections

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Cálculo óptimo de workers
worker_processes auto;  # Detecta núcleos automáticamente

# O manual:
# worker_processes 4;  # Para 4 núcleos

# Conexiones por worker
events {
    worker_connections 1024;  # Para servidores normales
    # worker_connections 4096;  # Para alta carga
}

# Límite total teórico = workers × connections
# 4 workers × 1024 = 4096 conexiones simultáneas

Configuración de buffers

1
2
3
4
5
6
7
8
9
10
# Buffers del cliente
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
client_max_body_size 20M;

# Buffers de proxy
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;

FastCGI Cache para PHP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# En el bloque http
fastcgi_cache_path /var/cache/nginx/fastcgi levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

# En el server block
set $skip_cache 0;

# No cachear POST requests
if ($request_method = POST) {
    set $skip_cache 1;
}

# No cachear URLs con query
if ($query_string != "") {
    set $skip_cache 1;
}

# No cachear admin/login
if ($request_uri ~* "/wp-admin/|/wp-login/") {
    set $skip_cache 1;
}

location ~ \.php$ {
    fastcgi_cache WORDPRESS;
    fastcgi_cache_valid 200 60m;
    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;
    add_header X-Cache $upstream_cache_status;
    
    # ... resto de configuración PHP
}

⚖️ Load Balancing y Reverse Proxy

Configuración básica de upstream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Definir pool de servidores
upstream backend {
    least_conn;  # Algoritmo de balanceo
    
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=2;
    server 192.168.1.12:8080 weight=1 backup;
    
    # Health checks
    server 192.168.1.13:8080 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name api.ejemplo.com;
    
    location / {
        proxy_pass http://backend;
        
        # Headers para el backend
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Timeouts
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

Algoritmos de balanceo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Round Robin (default)
upstream backend {
    server server1.com;
    server server2.com;
}

# Least Connections
upstream backend {
    least_conn;
    server server1.com;
    server server2.com;
}

# IP Hash (sticky sessions)
upstream backend {
    ip_hash;
    server server1.com;
    server server2.com;
}

# Weighted
upstream backend {
    server server1.com weight=3;
    server server2.com weight=1;
}

🔒 Seguridad avanzada

Rate limiting granular

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Diferentes zonas de rate limiting
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=general:10m rate=1r/s;

# Aplicar en locations específicos
location /login {
    limit_req zone=login burst=2 nodelay;
}

location /api/ {
    limit_req zone=api burst=20 nodelay;
}

location / {
    limit_req zone=general burst=10 nodelay;
}

Bloqueo de IPs maliciosas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Crear mapa de IPs bloqueadas
map $remote_addr $blocked_ip {
    default 0;
    ~^192\.168\.1\.100$ 1;
    ~^10\.0\.0\.50$ 1;
    include /etc/nginx/blocked_ips.conf;
}

server {
    # Bloquear IPs maliciosas
    if ($blocked_ip) {
        return 403;
    }
}

Headers de seguridad

1
2
3
4
5
6
7
8
9
10
# Snippet reutilizable: /etc/nginx/snippets/security-headers.conf
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;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# Incluir en server blocks
include /etc/nginx/snippets/security-headers.conf;

📊 Monitoreo y logs

Configuración de logs avanzada

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Formato de log personalizado
log_format detailed '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" '
                   '$request_time $upstream_response_time '
                   '$pipe $connection_requests';

# Logs condicionales
map $status $loggable {
    ~^[23]  0;  # No loggear 2xx, 3xx
    default 1;  # Loggear errores
}

access_log /var/log/nginx/access.log detailed if=$loggable;

Status page para monitoreo

1
2
3
4
5
6
7
8
# Compilar con --with-http_stub_status_module
location /nginx_status {
    stub_status on;
    access_log off;
    allow 127.0.0.1;
    allow 192.168.1.0/24;
    deny all;
}

Métricas importantes

Comandos de monitoreo:

1
2
3
4
5
6
7
8
9
10
11
# Conexiones activas
curl -s http://localhost/nginx_status

# Logs en tiempo real
tail -f /var/log/nginx/access.log

# Análisis de performance
awk '{print $NF}' /var/log/nginx/access.log | sort -n | tail -10

# Top IPs
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

🛠️ Troubleshooting común

Problemas de performance

1. Too many open files:

1
2
3
4
5
6
7
8
9
10
11
# Verificar límites
ulimit -n

# Aumentar en nginx.conf
worker_rlimit_nofile 65535;

# Aumentar systemd limit
sudo systemctl edit nginx
# Añadir:
[Service]
LimitNOFILE=65535

2. Alta carga de CPU:

1
2
3
4
5
6
# Verificar número de workers
ps aux | grep nginx

# Ajustar en nginx.conf
worker_processes auto;
worker_cpu_affinity auto;

Debugging de configuración

1
2
3
4
5
6
7
8
# Test de configuración
sudo nginx -t

# Reload sin downtime
sudo nginx -s reload

# Debug mode
sudo nginx -e /var/log/nginx/debug.log -g 'daemon off;'

Análisis de logs de error

1
2
3
4
5
6
7
8
# Errores más comunes
grep "error" /var/log/nginx/error.log | tail -20

# Conexiones rechazadas
grep "connection refused" /var/log/nginx/error.log

# Timeouts
grep "timeout" /var/log/nginx/error.log

🎯 Casos de uso prácticos

WordPress multisite con Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
map $http_host $blogid {
    default 0;
    ~^site1\.ejemplo\.com$ 1;
    ~^site2\.ejemplo\.com$ 2;
}

server {
    listen 80;
    server_name *.ejemplo.com ejemplo.com;
    root /var/www/wordpress;
    
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

API Gateway con rate limiting

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
upstream api_v1 {
    server api1.interno.com:8080;
    server api2.interno.com:8080;
}

upstream api_v2 {
    server apiv2.interno.com:8080;
}

server {
    listen 443 ssl http2;
    server_name api.ejemplo.com;
    
    # Rate limiting por endpoint
    location /v1/auth {
        limit_req zone=login burst=5 nodelay;
        proxy_pass http://api_v1;
    }
    
    location /v1/ {
        limit_req zone=api burst=50 nodelay;
        proxy_pass http://api_v1;
    }
    
    location /v2/ {
        limit_req zone=api burst=100 nodelay;
        proxy_pass http://api_v2;
    }
}

📈 Benchmarking y testing

Tools de testing

1
2
3
4
5
6
7
8
# Apache Bench
ab -n 1000 -c 10 http://ejemplo.com/

# wrk (más avanzado)
wrk -t4 -c100 -d30s http://ejemplo.com/

# siege
siege -c 50 -t 60s http://ejemplo.com/

Métricas a monitorear

  1. Requests per second (RPS)
  2. Response time (percentiles 50, 95, 99)
  3. Error rate (4xx, 5xx)
  4. Connection handling (activas, idle)
  5. Memory usage por worker
  6. CPU utilization

🧠 Teoría Avanzada: Fundamentos de Servidores Web

Arquitectura de Redes: El Stack TCP/IP en Nginx

Comprendiendo el flujo completo de una request:

1
Cliente → DNS → TCP Handshake → TLS Handshake → HTTP Request → Nginx → Backend

Cada paso explicado:

1. DNS Resolution:

  • Latencia típica: 20-100ms para cold cache
  • Optimización: DNS prefetching, CDN con múltiples PoPs
  • Nginx role: Server name resolution para upstreams

2. TCP Three-Way Handshake:

1
2
3
Client → SYN → Server
Client ← SYN+ACK ← Server  
Client → ACK → Server
  • Latencia: 1 RTT (Round Trip Time)
  • Optimización Nginx: tcp_nodelay on, tcp_nopush on

3. TLS Handshake (HTTPS):

1
2
3
4
Client → ClientHello → Server
Client ← ServerHello + Certificate ← Server
Client → ClientKeyExchange → Server
Client ← Finished ← Server
  • Latencia: 2 RTTs para TLS 1.2, 1 RTT para TLS 1.3
  • Optimización: Session resumption, OCSP stapling

Event-Driven Architecture: epoll vs select/poll

Evolución de I/O multiplexing:

select() - Generación 1:

1
2
3
4
5
// Limitaciones: FD_SETSIZE (típicamente 1024)
fd_set readfds, writefds;
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
select(sockfd + 1, &readfds, &writefds, NULL, &timeout);
  • Complejidad: O(n) donde n = número de file descriptors
  • Limitación: Máximo 1024 conexiones simultáneas

poll() - Generación 2:

1
2
3
// Mejora: No límite de FDs, pero sigue siendo O(n)
struct pollfd fds[nfds];
poll(fds, nfds, timeout);
  • Ventaja: Sin límite artificial de conexiones
  • Desventaja: Sigue siendo O(n) para escanear FDs

epoll() - Generación 3 (Linux):

1
2
3
4
// Event-driven: O(1) para operaciones
int epfd = epoll_create1(0);
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);
epoll_wait(epfd, events, MAX_EVENTS, timeout);
  • Complejidad: O(1) para operaciones
  • Escalabilidad: Maneja millones de conexiones

Implementación en Nginx:

1
2
3
4
5
6
events {
    use epoll;           # Linux
    # use kqueue;        # FreeBSD/macOS  
    # use /dev/poll;     # Solaris
    worker_connections 4096;
}

Memory Management y CPU Cache Optimization

Worker Process Memory Layout:

1
2
3
4
5
6
7
8
9
┌─────────────────┐
│ Code Segment    │ ← Shared between workers
├─────────────────┤
│ Data Segment    │ ← Configuration, shared memory
├─────────────────┤  
│ Heap            │ ← Connection pools, buffers
├─────────────────┤
│ Stack           │ ← Function calls, local variables
└─────────────────┘

CPU Cache Optimization:

1
2
3
4
5
6
# Bind workers to specific CPU cores
worker_processes auto;
worker_cpu_affinity auto;

# En sistemas con 8 cores:
# worker_cpu_affinity 01 02 04 08 10 20 40 80;

Ventajas del CPU affinity:

  • Cache locality: Worker mantiene datos en L1/L2 cache del core
  • Menos context switching: Reduce overhead del kernel
  • NUMA awareness: En sistemas multi-socket

HTTP Protocol Deep Dive

HTTP/1.1 vs HTTP/2 vs HTTP/3:

HTTP/1.1:

1
2
3
4
5
Características:
- Una request por conexión TCP
- Head-of-line blocking
- Headers en texto plano
- Requiere múltiples conexiones para paralelismo

HTTP/2:

1
2
3
4
5
Mejoras:
- Multiplexing: Múltiples streams por conexión
- Header compression (HPACK)
- Server push
- Stream prioritization

HTTP/3 (QUIC):

1
2
3
4
5
Innovaciones:
- Basado en UDP en lugar de TCP
- Elimina head-of-line blocking a nivel de transporte
- 0-RTT connection establishment
- Built-in encryption

Configuración Nginx para HTTP/2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
    listen 443 ssl http2;
    
    # HTTP/2 optimizations
    http2_max_field_size 16k;
    http2_max_header_size 32k;
    http2_max_requests 1000;
    
    # Server push (experimental)
    location / {
        http2_push /css/styles.css;
        http2_push /js/app.js;
    }
}

Load Balancing Algorithms: Teoría y Práctica

Round Robin:

1
2
3
4
5
6
7
8
9
10
11
Algoritmo: request_n % server_count
Complejidad: O(1)
Uso de memoria: O(1)

Ventajas:
- Simple y predecible
- Distribución uniforme en cargas similares

Desventajas:
- No considera carga actual del servidor
- Problemas con sesiones sticky

Least Connections:

1
2
3
4
5
6
7
8
9
10
11
Algoritmo: min(active_connections_per_server)
Complejidad: O(n) donde n = número de servidores
Uso de memoria: O(n)

Ventajas:
- Considera carga actual
- Mejor para requests de duración variable

Desventajas:
- Más overhead computacional
- Estado compartido entre workers

IP Hash:

1
2
3
4
5
6
7
8
9
10
11
Algoritmo: hash(client_ip) % server_count
Complejidad: O(1)
Uso de memoria: O(1)

Ventajas:
- Sticky sessions automáticas
- Cacheable per-user

Desventajas:
- Distribución desigual con NAT
- Problemas con failover

Weighted Round Robin:

1
2
3
4
5
6
7
upstream backend {
    server backend1.example.com weight=3;
    server backend2.example.com weight=2;  
    server backend3.example.com weight=1;
}

# Secuencia: backend1, backend1, backend2, backend1, backend2, backend3

SSL/TLS Performance Optimization

Cipher Suite Selection:

1
2
3
4
5
6
7
8
# Orden de preferencia de ciphers
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;

# Explicación:
# ECDHE: Perfect Forward Secrecy
# ECDSA vs RSA: ECDSA más eficiente
# AES256-GCM: Authenticated encryption
# CHACHA20: Alternativa para móviles

Session Resumption:

1
2
3
4
5
6
7
# Session tickets (stateless)
ssl_session_tickets on;
ssl_session_ticket_key /etc/nginx/ssl/ticket.key;

# Session cache (stateful)
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

OCSP Stapling:

1
2
3
4
5
# Reduce TLS handshake latency
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/ca-chain.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;

Cache Theory y Implementación

Cache Hierarchy:

1
Browser Cache → CDN Cache → Nginx Cache → Application Cache → Database

Cache Headers Strategy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    # Static assets - long cache
    expires 1y;
    add_header Cache-Control "public, immutable";
    add_header Vary "Accept-Encoding";
}

location /api/ {
    # API responses - conditional cache
    add_header Cache-Control "private, max-age=300";
    add_header ETag $request_id;
}

location /dynamic/ {
    # Dynamic content - no cache
    add_header Cache-Control "no-cache, no-store, must-revalidate";
    add_header Pragma "no-cache";
    add_header Expires "0";
}

FastCGI Cache Algorithm:

1
2
3
4
5
6
7
Cache Key = MD5(scheme + request_method + host + request_uri + args)

Lookup Process:
1. Hash cache key
2. Check memory index
3. If hit: serve from memory/disk
4. If miss: request from backend + store

🎓 Conclusión

Nginx es una herramienta extremadamente poderosa que, con la configuración correcta, puede manejar cargas masivas con recursos mínimos. La comprensión profunda de su arquitectura event-driven, la teoría de redes subyacente y los algoritmos de optimización es lo que separa una configuración básica de una implementación de nivel empresarial.

Las claves del éxito son:

  1. Entender la arquitectura event-driven y sus implicaciones
  2. Optimizar para tu caso de uso específico basado en patrones de tráfico
  3. Monitorear constantemente el rendimiento y ajustar dinámicamente
  4. Aplicar seguridad desde el primer día con defense-in-depth
  5. Testing regular de configuraciones bajo carga real
  6. Comprender la teoría subyacente para troubleshooting efectivo

Próximos pasos recomendados

  • Implementar Nginx Plus para features empresariales
  • Integrar con Prometheus/Grafana para monitoreo avanzado
  • Explorar OpenResty para funcionalidad con Lua scripting
  • Configurar WAF (Web Application Firewall) con ModSecurity
  • Estudiar HTTP/3 y QUIC para prepararse para el futuro

El dominio de Nginx no es solo sobre configuración, sino sobre entender cómo funcionan los sistemas distribuidos modernos a gran escala.


Andrés Nuñez - t4ifi

Esta entrada está licenciada bajo CC BY 4.0 por el autor.