package devopsmodules import ( "rubric/utils" ) var NginxModule = Module{ Key: "nginx", Aliases: []string{"n", "web", "proxy", "haproxy"}, Title: "Nginx и балансировка нагрузки", Description: "Конфигурация, virtual hosts, reverse proxy, SSL/TLS, балансировка, HAProxy", Run: showNginx, } func showNginx() { utils.Header("DevOps — Nginx и балансировка нагрузки") utils.Section("Основы Nginx") utils.Code(`# Установка: apt install nginx # Debian/Ubuntu dnf install nginx # RHEL/Fedora systemctl enable --now nginx nginx -t # проверить конфигурацию nginx -s reload # перезагрузить конфиг nginx -s stop # остановить # Структура конфигурации: /etc/nginx/ ├── nginx.conf # главный файл ├── conf.d/ # дополнительные конфиги (*.conf) ├── sites-available/ # доступные виртуальные хосты ├── sites-enabled/ # включённые (симлинки) ├── snippets/ # переиспользуемые блоки └── mime.types # MIME-типы`) utils.Section("nginx.conf — основной конфиг") utils.Code(`user nginx; worker_processes auto; # = количество CPU error_log /var/log/nginx/error.log warn; pid /run/nginx.pid; events { worker_connections 1024; # соединений на воркер multi_accept on; use epoll; # Linux event model } http { include /etc/nginx/mime.types; default_type application/octet-stream; # Логи: log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct=$upstream_connect_time'; access_log /var/log/nginx/access.log main; # Производительность: sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; gzip on; gzip_types text/plain text/css application/json application/javascript; # Безопасность: server_tokens off; # скрыть версию nginx client_max_body_size 10M; client_body_timeout 12s; client_header_timeout 12s; include /etc/nginx/conf.d/*.conf; }`) utils.Section("Virtual Hosts (Server Blocks)") utils.Code(`# /etc/nginx/conf.d/example.com.conf # Статический сайт: server { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; } location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 30d; add_header Cache-Control "public, immutable"; } # Перенаправление на HTTPS: return 301 https://$host$request_uri; } # HTTPS: server { listen 443 ssl http2; server_name example.com www.example.com; root /var/www/example.com; ssl_certificate /etc/ssl/certs/example.com.crt; ssl_certificate_key /etc/ssl/private/example.com.key; # Современные настройки TLS: ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_stapling on; ssl_stapling_verify on; # HSTS: add_header Strict-Transport-Security "max-age=63072000" always; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; location / { try_files $uri $uri/ =404; } }`) utils.Section("Reverse Proxy") utils.Code(`# Проксирование к бэкенду: server { listen 443 ssl http2; server_name api.example.com; ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; location / { proxy_pass http://localhost:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; # WebSocket 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; proxy_cache_bypass $http_upgrade; proxy_connect_timeout 30s; proxy_send_timeout 30s; proxy_read_timeout 30s; } # Кэширование статики: location /static/ { proxy_pass http://localhost:8000/static/; proxy_cache_valid 200 1d; expires 1d; } }`) utils.Section("Балансировка нагрузки") utils.Code(`# upstream — группа серверов: upstream myapp { least_conn; # least connections (или round_robin, ip_hash) server backend1:8000 weight=3; # 3x больше запросов server backend2:8000 weight=1; server backend3:8000; server backend4:8000 backup; # только при недоступности остальных keepalive 32; # keepalive соединения } upstream myapp { ip_hash; # один клиент → один бэкенд (sticky sessions) server backend1:8000; server backend2:8000; } server { listen 80; location / { proxy_pass http://myapp; health_check; # nginx plus или модуль } } # Алгоритмы балансировки: # round_robin — по очереди (по умолчанию) # least_conn — к серверу с наименьшим числом соединений # ip_hash — по IP клиента (sticky sessions) # hash $var — по произвольной переменной # random — случайно`) utils.Section("Настройки производительности и безопасности") utils.Code(`# Rate limiting — ограничение запросов: http { limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn:10m; } server { location /api/ { limit_req zone=api burst=20 nodelay; limit_conn conn 10; proxy_pass http://backend; } # Защита от DDoS: location /login { limit_req zone=api rate=1r/s burst=5; proxy_pass http://backend; } } # Аутентификация Basic Auth: location /admin { auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } # htpasswd -c /etc/nginx/.htpasswd admin # Блокировка по IP: location /api { deny 192.168.1.100; allow 192.168.1.0/24; deny all; proxy_pass http://backend; } # Кэширование прокси: proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m; server { location / { proxy_cache my_cache; proxy_cache_valid 200 10m; proxy_cache_use_stale error timeout updating; add_header X-Cache-Status $upstream_cache_status; proxy_pass http://backend; } }`) utils.Section("Let's Encrypt — бесплатные сертификаты") utils.Code(`# Установка certbot: apt install certbot python3-certbot-nginx # Получить и настроить сертификат: certbot --nginx -d example.com -d www.example.com # Только получить сертификат (без правки nginx.conf): certbot certonly --nginx -d example.com # Обновление (автоматически через systemd timer или cron): certbot renew --dry-run # тест certbot renew # обновить просроченные # Принудительное обновление: certbot renew --force-renewal # Wildcard сертификат (через DNS challenge): certbot certonly --manual \ -d "*.example.com" \ --preferred-challenges dns`) utils.Section("HAProxy — продвинутая балансировка") utils.Code(`# HAProxy — специализированный балансировщик нагрузки. # Лучше nginx для TCP/L4 балансировки. # Богатые возможности health check и ACL. # /etc/haproxy/haproxy.cfg: global maxconn 50000 log /dev/log local0 stats socket /run/haproxy/admin.sock mode 660 level admin defaults log global mode http option httplog option dontlognull timeout connect 5s timeout client 30s timeout server 30s option forwardfor option http-server-close frontend http_front bind *:80 redirect scheme https unless { ssl_fc } frontend https_front bind *:443 ssl crt /etc/ssl/certs/example.pem default_backend app_back # ACL-маршрутизация: acl is_api path_beg /api/ use_backend api_back if is_api backend app_back balance roundrobin option httpchk GET /health server web1 192.168.1.10:8000 check weight 2 server web2 192.168.1.11:8000 check weight 1 server web3 192.168.1.12:8000 check backup backend api_back balance leastconn timeout server 60s server api1 192.168.1.20:8080 check server api2 192.168.1.21:8080 check # Статистика: frontend stats bind *:8404 stats enable stats uri /stats stats refresh 10s stats auth admin:secret`) utils.Footer() }