323 lines
9.6 KiB
Go
323 lines
9.6 KiB
Go
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()
|
||
}
|