rubric/modules/devopsmodules/devops_nginx.go

323 lines
9.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()
}