Skip to content

Proxi #40

Description

@abzalimovrrr

Proxi — Прокси-серверы: вопросы, практические задания и ответы с кодом

100 вопросов по прокси-серверам (Nginx, HAProxy, Envoy, Kong, Traefik) от основ до продвинутых тем — с практическими заданиями, примерами кода и комментариями на русском языке.


Темы

РазделОписание
1–10Основы проксиForward/reverse proxy, Nginx, location, load balancing, SSL, gzip, rate limit, cache, HAProxy
11–20HAProxy и EnvoyACL, health check, stickiness, stats, Envoy config, clusters, filters, API Gateway, Kong, Traefik
21–30Продвинутый Nginxproxy_pass, WebSocket, TCP/UDP stream, DNS cache, real IP, CONNECT, Squid, SOCKS5, Round Robin, Least Connections
31–40Балансировка и Service MeshIP Hash, weighted, active-passive, health checks, Istio, mTLS, NGINX Plus, OpenResty, Varnish, Proxy Protocol
41–50Специфические проксиCaddy, Let's Encrypt, микросервисный gateway, WebSocket, gRPC, API cache, CDN, reverse vs LB, SSE, large files
51–60Nginx продвинутыйGeo/IP blocking, map, split_clients, secure_link, referer, sub_filter, SSI, fastcgi cache, stream SSL
61–70HAProxy продвинутыйFrontend/backend SSL, stick-tables, peer sync, http-request, http-response, tcp-request, stats, ACLs, Lua
71–80Envoy продвинутыйRate limit, ext_authz, WASM, access log, retry, timeout, circuit breaker, outlier detection, LB, locality
81–90API GatewayKong plugins, Traefik middleware, Ocelot, AWS API GW, Zuul, Nginx+Lua, GraphQL federation
91–100Мониторинг и безопасностьProxy logging, OpenTelemetry, mTLS, ModSecurity, DDoS, GSLB, GeoDNS, Anycast, benchmarking

Вопросы и ответы

ВопросКод с комментариями
1Что такое прокси-сервер?
# Forward proxy — для клиентов (доступ в интернет)
export HTTP_PROXY=http://proxy:8080
export HTTPS_PROXY=http://proxy:8080
curl --proxy http://proxy:8080 https://example.com
2Что такое reverse proxy?
server {
  listen 80;
  server_name example.com;

location / {
proxy_pass http://localhost:3000;
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;
}
}

3Что такое Nginx?
# Ubuntu:
sudo apt install nginx
sudo systemctl start nginx
sudo systemctl enable nginx

Docker:

docker run -d -p 80:80 nginx:alpine

Проверка:

curl http://localhost:80

4Что такое location в Nginx?
location / {  # prefix match
  proxy_pass http://app;
}

location = /exact { # exact match
return 200 "Exact";
}

location ~ .php$ { # regex match
fastcgi_pass php:9000;
}

location ^~ /static/ { # prefix + priority
root /var/www;
}

5Что такое load balancing в Nginx?
upstream backend {
  least_conn;  # или ip_hash, random
  server app1:3000 weight=3;
  server app2:3000 weight=2;
  server app3:3000 backup;  # только если упали основные
}

server {
listen 80;
location / {
proxy_pass http://backend;
}
}

6Что такое SSL termination в Nginx?
server {
  listen 443 ssl http2;
  server_name example.com;

ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

location / {
proxy_pass http://app;
}
}

Redirect HTTP -> HTTPS

server {
listen 80;
return 301 https://$host$request_uri;
}

7Что такое gzip в Nginx?
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
gzip_min_length 1000;
gzip_comp_level 6;
gzip_vary on;
gzip_proxied any;
8Что такое rate limiting в Nginx?
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
}

9Что такое кэширование в Nginx?
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:10m max_size=1g;

server {
location / {
proxy_cache mycache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}

10Что такое HAProxy?
# haproxy.cfg
global
  daemon
  maxconn 256

defaults
mode http
timeout connect 5s
timeout client 10s
timeout server 10s

frontend web
bind *:80
default_backend app

backend app
balance roundrobin
server app1 10.0.0.1:3000 check
server app2 10.0.0.2:3000 check

11Что такое ACL в HAProxy?
frontend web
  bind *:80
  bind *:443 ssl crt /etc/ssl/certs.pem

acl is_api path_beg /api
acl is_static path_end .css .js .png
acl is_admin path_beg /admin

use_backend api if is_api
use_backend static if is_static
use_backend admin if is_admin
default_backend web

12Что такое health check в HAProxy?
backend app
  option httpchk GET /health
  http-check expect status 200
  default-server inter 5s fall 3 rise 2

server app1 10.0.0.1:3000 check
server app2 10.0.0.2:3000 check
server app3 10.0.0.3:3000 check backup

13Что такое stickiness (липкость) в HAProxy?
backend app
  balance roundrobin
  cookie SERVERID insert indirect nocache
  server app1 10.0.0.1:3000 check cookie app1
  server app2 10.0.0.2:3000 check cookie app2

Или по IP:

stick-table type ip size 100k

stick on src

14Что такое stats в HAProxy?
backend stats
  stats enable
  stats uri /haproxy-stats
  stats refresh 5s
  stats auth admin:password
  stats hide-version

frontend web
bind *:80
use_backend stats if { path /haproxy-stats }

15Что такое Envoy Proxy?
# envoy.yaml
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address: { address: 0.0.0.0, port_value: 10000 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/" }
                          route: { cluster: service_1 }
                http_filters:
                  - name: envoy.filters.http.router
  clusters:
    - name: service_1
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: service_1
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address: { address: app, port_value: 3000 }
16Что такое Envoy clusters?
clusters:
  - name: my_service
    type: STRICT_DNS  # DNS resolving on each request
    lb_policy: LEAST_REQUEST  # ROUND_ROBIN, RING_HASH, RANDOM
    connect_timeout: 0.25s
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 100
          max_pending_requests: 10
          max_requests: 50
    health_checks:
      - timeout: 1s
        interval: 10s
        unhealthy_threshold: 3
        healthy_threshold: 2
        http_health_check:
          path: "/health"
17Что такое Envoy filters?
# HTTP фильтры:
http_filters:
  - name: envoy.filters.http.router
  - name: envoy.filters.http.cors
  - name: envoy.filters.http.ext_authz
  - name: envoy.filters.http.ratelimit
  - name: envoy.filters.http.lua
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
      inline_code: |
        function envoy_on_request(request_handle)
          request_handle:headers():add("x-custom", "hello")
        end
18Что такое API Gateway?
# API Gateway — единая точка входа для микросервисов
# Функции:
# — Маршрутизация
# — Аутентификация
# — Rate limiting
# — Кэширование
# — Трансформация ответов
# — Агрегация
# — Мониторинг

Пример на Express Gateway:

http:
port: 8080
admin:
port: 9876
apiEndpoints:
api:
host: "*"
serviceEndpoints:
users: { url: "http://users:3000" }
orders: { url: "http://orders:3001" }
policies:

  • proxy:
    • action:
      serviceEndpoint: users
      changeOrigin: true
19Что такое Kong Gateway?
# Установка через Docker:
docker run -d --name kong-db -p 5432:5432 -e POSTGRES_DB=kong postgres:13
docker run -d --name kong -p 8000:8000 -p 8443:8443 --link kong-db kong

Добавить сервис:

curl -X POST http://localhost:8001/services
-d "name=users"
-d "url=http://users-api:3000"

Добавить роут:

curl -X POST http://localhost:8001/services/users/routes
-d "paths[]=/users"

Включить плагин:

curl -X POST http://localhost:8001/services/users/plugins
-d "name=rate-limiting"
-d "config.minute=100"

20Что такое Traefik?
# docker-compose.yml
version: "3"
services:
  traefik:
    image: traefik:v3.0
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
    ports:
      - "80:80"
      - "443:443"

app:
image: myapp
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(app.example.com)"

21Что такое proxy_pass в Nginx?
server {
  listen 80;

location /api/ {
proxy_pass http://backend:3000/;
# /api/users -> /users (с / на конце срезает prefix)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

location / {
proxy_pass http://frontend:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; # для WebSocket
}
}

22Что такое WebSocket прокси?
server {
  listen 80;
  location /ws {
    proxy_pass http://ws-backend:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 86400;
  }
}
23Что такое TCP/UDP прокси (stream)?
stream {
  upstream db {
    server db1:5432;
    server db2:5432 backup;
  }

server {
listen 5432;
proxy_pass db;
proxy_timeout 30s;
proxy_connect_timeout 5s;
}
}

Для UDP:

server {
listen 53 udp;
proxy_pass dns-server:53;
}

24Что такое кэширование DNS в прокси?
server {
  set $backend "app.example.com";
  resolver 8.8.8.8 1.1.1.1 valid=30s;
  proxy_pass http://$backend;

location / {
proxy_pass http://$backend;
proxy_set_header Host $backend;
}
}

Или upstream с resolve:

upstream backend {
zone backend 64k;
server app.example.com resolve;
}

25Что такое real IP (X-Forwarded-For)?
server {
  # set_real_ip_from — доверенные прокси
  set_real_ip_from 10.0.0.0/8;
  set_real_ip_from 172.16.0.0/12;
  set_real_ip_from 192.168.0.0/16;
  real_ip_header X-Forwarded-For;
  real_ip_recursive on;

location / {
proxy_pass http://backend;
}
}

26Что такое forward proxy (HTTP CONNECT)?
# Используется для HTTPS через прокси
# Клиент -> CONNECT example.com:443 HTTP/1.1
# Прокси -> устанавливает TCP туннель

server {
listen 3128;

Разрешить CONNECT только на 443

if ($method = CONNECT) {
set $allow_connect 1;
}

proxy_connect_allow 443 563;
proxy_connect_timeout 10s;
proxy_connect_read_timeout 30s;
proxy_connect_send_timeout 30s;
}

27Что такое Squid proxy?
# squid.conf
http_port 3128
acl allowed_networks src 10.0.0.0/8 192.168.0.0/16
http_access allow allowed_networks
http_access deny all

Кэш:

cache_dir ufs /var/spool/squid 10000 16 256
cache_mem 256 MB
maximum_object_size 4 MB

Логи:

access_log /var/log/squid/access.log

28Что такое SOCKS5 прокси?
# SOCKS5 — прокси на уровне TCP/UDP
# Плюсы:
# — Любой протокол (HTTP, FTP, SSH)
# — UDP support
# — Аутентификация

Клиент:

ssh -D 1080 user@server # SSH tunnel как SOCKS5
curl --socks5 localhost:1080 https://example.com

Dante SOCKS сервер:

danted.conf

internal: eth0 port = 1080
external: eth0
method: username none
user.privileged: root
user.unprivileged: nobody
client pass { from: 10.0.0.0/8 to: 0.0.0.0/0 }
socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 }

29Что такое балансировка Round Robin?
upstream backend {
  server app1:3000;
  server app2:3000;
  server app3:3000;
}
# Запросы распределяются по очереди: 1->app1, 2->app2, 3->app3, 4->app1...
# Плюсы: простота
# Минусы: не учитывает нагрузку
30Что такое балансировка Least Connections?
upstream backend {
  least_conn;
  server app1:3000;
  server app2:3000;
  server app3:3000;
}
# Запрос направляется к серверу с наименьшим числом активных соединений
# Учитывает текущую нагрузку
# Лучше для долгих запросов
31Что такое балансировка IP Hash?
upstream backend {
  ip_hash;
  server app1:3000;
  server app2:3000;
}
# Один и тот же клиент -> один и тот же сервер
# Решает проблему сессий без sticky sessions
# Полезно для кэширования на сервере
32Что такое балансировка с весами?
upstream backend {
  server app1:3000 weight=5;  # 50% трафика
  server app2:3000 weight=3;  # 30%
  server app3:3000 weight=2;  # 20%
}
# Для серверов с разной производительностью
33Что такое active-passive балансировка?
upstream backend {
  server app1:3000;
  server app2:3000 backup;  # passive — только при падении app1
  server app3:3000 backup;
}
# Один активный, остальные ждут
# Просто, предсказуемо
# Ресурсы простаивают
34Что такое health checks active vs passive?
# Active — прокси сам проверяет
# Nginx:
upstream backend {
  server app1:3000 max_fails=3 fail_timeout=30s;
  # 3 ошибки за 30s -> помечается как недоступный
}

Passive — по ответам сервера

HAProxy:

backend app
option httpchk GET /health
server app1 10.0.0.1:3000 check inter 5s fall 3 rise 2

35Что такое Service Mesh (прокси-сетка)?
# Istio — service mesh на основе Envoy
# Каждый pod получает sidecar proxy (Envoy)

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: myapp
spec:
hosts:
- myapp
http:
- route:
- destination:
host: myapp
subset: v1
weight: 90
- destination:
host: myapp
subset: v2
weight: 10
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: myapp
subset: v2

36Что такое mTLS в service mesh?
# Istio mTLS — шифрование между сервисами
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: STRICT  # только mTLS
  portLevelMtls:
    "8080":
      mode: DISABLE  # исключение для порта

Без Istio — nginx mTLS:

upstream backend {
server app1:3000;
}
server {
listen 443 ssl;
ssl_client_certificate /etc/ssl/ca.crt;
ssl_verify_client on;
proxy_pass http://backend;
}

37Что такое NGINX Plus?
# NGINX Plus — коммерческая версия
# Дополнительно:
# — Active health checks
# — Session persistence
# — Status dashboard
# — DNS service discovery
# — JWT validation
# — MQTT/HTTP3
# — API gateway
# — Service mesh

Active health check:

upstream backend {
zone backend 64k;
server app1:3000;
server app2:3000;
}
server {
location / {
health_check interval=5s fails=3 passes=2 uri=/health;
proxy_pass http://backend;
}
}

38Что такое OpenResty (Nginx + Lua)?
# OpenResty — Nginx + LuaJIT
# Для сложной логики на уровне прокси

worker_processes 1;
events { worker_connections 1024; }
http {
server {
listen 80;
location / {
content_by_lua_block {
local method = ngx.var.request_method
if method == "POST" then
ngx.say("Processing POST...")
else
ngx.say("Hello from OpenResty!")
end
}
}

# Lua для авторизации:
location /api {
  access_by_lua_block {
    local token = ngx.var.http_authorization
    if not token then
      ngx.exit(401)
    end
  }
  proxy_pass http://backend;
}

}
}

39Что такое caching proxy (Varnish)?
# Varnish — HTTP кэширующий прокси
# default.vcl
vcl 4.0;

backend default {
.host = "backend";
.port = "3000";
}

sub vcl_recv {

Кэшировать GET

if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}

Удалить cookie для статики

if (req.url ~ ".(css|js|png)$") {
unset req.http.cookie;
}
}

sub vcl_backend_response {

Кэш на 1 час

if (bereq.url ~ ".(css|js|png)$") {
set beresp.ttl = 1h;
}
}

sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}

Docker:

docker run -d -p 80:80 -v default.vcl:/etc/varnish/default.vcl varnish

40Что такое proxy protocol?
# Proxy Protocol — передача реального IP через прокси

HAProxy (отправляет):

backend app
server app1 10.0.0.1:3000 send-proxy-v2

Nginx (принимает):

server {
listen 80 proxy_protocol;
set_real_ip_from 10.0.0.0/8;
real_ip_header proxy_protocol;
}

41Что такое Caddy?
# Caddy — автоматический HTTPS, простой конфиг
# Caddyfile

api.example.com {
reverse_proxy app:3000
}

static.example.com {
root * /var/www
file_server
}

Сжатие:

api.example.com {
encode gzip zstd
reverse_proxy app:3000
}

Установка:

docker run -d -p 80:80 -p 443:443 -v Caddyfile:/etc/caddy/Caddyfile caddy

42Что такое авто-обновление сертификатов?
server {
  listen 80;
  server_name example.com;

location /.well-known/acme-challenge/ {
root /var/www/certbot;
}

location / {
return 301 https://$host$request_uri;
}
}

Certbot:

sudo certbot --nginx -d example.com -d www.example.com

Авто-обновление:

sudo certbot renew --dry-run

Или:

0 3 * * * /usr/bin/certbot renew --quiet

43Что такое прокси для микросервисов?
server {
  listen 80;
  server_name api.example.com;

location /users/ {
proxy_pass http://users-service:3000/;
}
location /orders/ {
proxy_pass http://orders-service:3001/;
}
location /payments/ {
proxy_pass http://payments-service:3002/;
}

Rate limiting для всех

limit_req zone=api burst=50 nodelay;

CORS

add_header Access-Control-Allow-Origin "*";
}

44Что такое прокси для WebSocket?
map $http_upgrade $connection_upgrade {
  default upgrade;
  "" close;
}

upstream ws {
hash $binary_remote_addr consistent;
server ws1:3000;
server ws2:3000;
}

server {
listen 80;

location /ws {
proxy_pass http://ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}

45Что такое прокси для gRPC?
upstream grpc_backend {
  server app1:50051;
  server app2:50051;
}

server {
listen 443 ssl http2;
server_name grpc.example.com;

location / {
grpc_pass grpc://grpc_backend;
grpc_set_header Host $host;
grpc_read_timeout 1h;
grpc_send_timeout 1h;
}
}

46Что такое кэширование API ответов?
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api:10m inactive=1h;

server {
location /api/ {
proxy_cache api;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error updating;

# Не кэшировать с cookie
proxy_no_cache $http_cookie;
proxy_cache_bypass $http_cookie;

add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;

}
}

47Что такое CDN (Content Delivery Network)?
# CDN — распределённая сеть прокси-серверов
# Cloudflare, CloudFront, Akamai

Origin pull — CDN забирает контент с вашего сервера

Пушим контент на CDN (для больших файлов)

Nginx конфиг для CDN origin:

server {
listen 80;
server_name origin.example.com;

Только CDN может обращаться к origin

allow 103.21.244.0/22; # Cloudflare IPs
allow 103.22.200.0/22;
deny all;

location / {
root /var/www;
expires 30d;
add_header Cache-Control "public, immutable";
}
}

48Что такое reverse proxy vs load balancer?
# Reverse proxy:
# — Скрывает backend
# — SSL termination
# — Кэширование
# — Сжатие
# — Security (WAF)
# — Пример: Nginx, Envoy

Load Balancer:

— Распределение трафика

— Health checks

— Session persistence

— Пример: HAProxy, AWS ALB

Часто совмещены в одном инструменте

49Что такое прокси для Server-Sent Events (SSE)?
server {
  location /events {
    proxy_pass http://sse-backend:3000;
    proxy_buffering off;  # выключить буферизацию!
    proxy_cache off;
    chunked_transfer_encoding on;
    proxy_set_header Connection "";
    proxy_http_version 1.1;
    proxy_read_timeout 86400s;
  }
}
50Что такое прокси для больших файлов?
server {
  client_max_body_size 100M;  # максимум тела запроса
  client_body_buffer_size 128k;
  proxy_request_buffering off;  # стриминг тела
  proxy_buffering off;  # не буферизовать ответ
  proxy_buffer_size 4k;

location /upload {
proxy_pass http://backend;
proxy_http_version 1.1;
}

location /download {
proxy_pass http://backend;
# Для больших файлов
proxy_max_temp_file_size 0;
proxy_set_header Range $http_range;
}
}

51Что такое geo/IP blocking в Nginx?
geo $blocked_country {
  default 0;
  # ISO коды стран
  RU 1;
  CN 1;
  KP 1;
  IR 1;
}

server {
listen 80;
if ($blocked_country) {
return 403;
}

location / {
proxy_pass http://backend;
}
}

Или через map + geoip:

ngx_http_geoip_module (MaxMind GeoIP)

На debian: apt install libnginx-mod-http-geoip

Блокировка по IP:

geo $blocked_ip {
default 0;
10.0.0.0/8 1;
192.168.0.0/16 1;
203.0.113.0/24 1;
}

server {
if ($blocked_ip) {
return 403;
}
proxy_pass http://backend;
}

52Что такое map module в Nginx?
# map — создание переменных на основе значений

map $http_host $backend {
default backend;
app1.example.com app1;
app2.example.com app2;
api.example.com api;
}

map $request_method $is_read {
GET 1;
HEAD 1;
default 0;
}

map $http_upgrade $connection_upgrade {
default upgrade;
"" close;
}

map $remote_addr $rate_limit_key {
default $binary_remote_addr;
10.0.0.0/8 ""; # не лимитировать внутренние
}

map $uri $cache_key {
~^/api/ "api:$request_uri";
~^/static/ "static:$uri";
default "other:$request_uri";
}

server {
listen 80;
location / {
proxy_pass http://$backend;
}
}

53Что такое split_clients в Nginx?
# split_clients — распределение трафика в процентах

split_clients "${remote_addr}${http_user_agent}" $variant {
10% version_a;
20% version_b;

  •  version_default;
    

}

split_clients "$request_uri" $upstream {
5% backend_canary;

  •  backend_stable;
    

}

server {
listen 80;
location / {
# Canary: 5% трафика на новый backend
proxy_pass http://$upstream;

# A/B тест UI
add_header X-Variant $variant;

}
}

Использование с map:

map $variant $color {
version_a #ff0000;
version_b #00ff00;
default #0000ff;
}

54Что такое secure_link в Nginx?
# secure_link — защита от hotlinking

location /files/ {
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr secret_key";

if ($secure_link = "") {
return 403;
}
if ($secure_link = "0") {
return 410;
}
}

Генерация защищённой ссылки (на стороне приложения):

import hashlib, time

secret = "secret_key"

path = "/files/document.pdf"

expires = int(time.time()) + 3600

md5 = hashlib.md5(f"{expires}{path}127.0.0.1 {secret}".encode()).hexdigest()

url = f"https://example.com{path}?md5={md5}&expires={expires}"

Только для определённых агентов:

secure_link_md5 "$secure_link_expires$uri$http_user_agent secret";

55Что такое referer module в Nginx?
# valid_referers — блокировка hotlinking по рефереру

location /images/ {
valid_referers none blocked server_names
*.example.com
~.google.
~.yandex.
~.bing.;

if ($invalid_referer) {
return 403;
}

Или редирект на заглушку:

rewrite ^ /blocked.png redirect;

}

location /downloads/ {
valid_referers
server_names
~.mydomain.com$;

if ($invalid_referer) {
return 444; # закрыть соединение без ответа
}

proxy_pass http://cdn;
}

Отключить проверку для API:

location /api/ {
valid_referers none;
proxy_pass http://backend;
}

56Что такое sub_filter в Nginx?
# sub_filter — замена текста в ответе на лету

server {
listen 80;
location / {
sub_filter '<head>' '<head><base href="https://example.com">';
sub_filter 'http://' 'https://';
sub_filter_once off; # заменить все вхождения
sub_filter_types text/html text/xml;

proxy_pass http://backend;

}
}

Замена переменных:

sub_filter '$hostname' '$hostname ($server_name)';
sub_filter '$remote_addr' '[IP: $remote_addr]';

Удаление куков:

sub_filter 'Set-Cookie: ' 'Set-Cookie: SameSite=Strict; ';
sub_filter_types *;

Множественные замены:

sub_filter 'old-domain.com' 'new-domain.com';
sub_filter 'http:' 'https:';
sub_filter_once off;

57Что такое SSI (Server Side Includes) в Nginx?
# SSI — вставка содержимого в HTML на стороне сервера

server {
listen 80;
location / {
ssi on;
ssi_types text/html;
ssi_silent_errors off;
proxy_pass http://backend;
}
}

В HTML используем:

<!--# include virtual="/header.html" -->

<!--# include virtual="/footer.html" -->

<!--# echo var="DATE_LOCAL" -->

<!--# echo var="REMOTE_ADDR" -->

<!--# set var="name" value="Alice" -->

<!--# if expr="$name = /Alice/" -->

<p>Welcome Alice!</p>

<!--# endif -->

<!--# include file="sidebar.html" stub="true" -->

With variables:

<!--# set var="page" value="$query_string" -->

<!--# if expr="$page = /admin/" -->

<!--# include virtual="/admin-panel" -->

<!--# endif -->

58Что такое fastcgi_cache в Nginx?
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=phpcache:100m inactive=60m;

server {
listen 80;
root /var/www/html;
index index.php;

location ~ .php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;

# Кэширование
fastcgi_cache phpcache;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 302 30m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid any 1m;
fastcgi_cache_min_uses 2;
fastcgi_cache_use_stale error timeout updating invalid_header;

# Не кэшировать для админов
fastcgi_no_cache $cookie_admin_session;
fastcgi_cache_bypass $cookie_admin_session;

add_header X-Cache $upstream_cache_status;

}
}

Purge cache:

location ~ /purge(/.*) {

fastcgi_cache_purge phpcache "$scheme$request_method$host$1";

}

59Что такое uwsgi прокси?
# Nginx как прокси для uWSGI (Python/Django)

upstream uwsgi_backend {
server app1:8000;
server app2:8000;
}

server {
listen 80;
server_name myapp.com;

location / {
include uwsgi_params;
uwsgi_pass uwsgi_backend;
uwsgi_param Host $host;
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $scheme;

# Buffers
uwsgi_buffering on;
uwsgi_buffer_size 32k;
uwsgi_buffers 8 32k;
uwsgi_busy_buffers_size 64k;

# Timeouts
uwsgi_read_timeout 60s;
uwsgi_send_timeout 60s;
uwsgi_connect_timeout 10s;

}

location /static/ {
alias /var/www/static/;
expires 30d;
}
}

Django uwsgi.ini:

[uwsgi]

socket = :8000

module = myapp.wsgi:application

processes = 4

threads = 2

60Что такое stream SSL в Nginx?
stream {
  # TCP прокси с SSL termination
  server {
    listen 443 ssl;
    proxy_pass db-backend:5432;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

proxy_ssl on;
proxy_ssl_certificate /etc/ssl/certs/client.crt;
proxy_ssl_certificate_key /etc/ssl/private/client.key;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;

proxy_timeout 30s;
proxy_connect_timeout 5s;

}

SSL для Redis

server {
listen 6380 ssl;
proxy_pass redis:6379;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
}

MQTT over SSL

server {
listen 8883 ssl;
proxy_pass mqtt-broker:1883;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
}
}

61Что такое frontend/backend SSL в HAProxy?
frontend web
  bind *:443 ssl crt /etc/ssl/certs/mydomain.pem
  bind *:80

http-request redirect scheme https unless { ssl_fc }
default_backend app

backend app

Backend SSL (если backend требует HTTPS)

server app1 10.0.0.1:443 ssl verify required ca-file /etc/ssl/certs/ca.crt
server app2 10.0.0.2:443 ssl verify none

Client certificate для backend

server app3 10.0.0.3:443 ssl verify required ca-file /etc/ssl/certs/ca.crt crt /etc/ssl/certs/client.pem

SSL options

option ssl-hello-chk
default-server ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3

frontend api
bind *:8443 ssl crt /etc/ssl/certs/api.pem alpn h2,http/1.1
bind *:8080
default_backend api_servers

62Что такое stick-tables в HAProxy?
# Stick-tables — хранение данных о клиентах

frontend web
bind *:80

Таблица для rate limiting по IP

stick-table type ip size 100k expire 30s store http_req_rate(10s)
http-request track-sc1 src
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }

default_backend app

backend app

Таблица для липкости сессий

stick-table type string len 32 size 50k expire 1h store server_id
stick on cookie(SESSION)

Таблица для подсчёта ошибок

stick-table type integer size 10k expire 1h store gpc0
http-request set-gpc0(1) 1 if { status 500 }
http-request deny if { sc_get_gpc0(1) gt 10 }

server app1 10.0.0.1:3000 check
server app2 10.0.0.2:3000 check

63Что такое peer sync в HAProxy?
# Peer sync — синхронизация stick-tables между HAProxy

global
daemon
maxconn 256

peers mypeers
peer haproxy1 10.0.0.1:10001
peer haproxy2 10.0.0.2:10001
peer haproxy3 10.0.0.3:10001

table mytable type ip size 1m expire 30s store http_req_rate(10s)

frontend web
bind *:80
stick-table type ip size 1m expire 30s store http_req_rate(10s)
http-request track-sc1 src table mypeers/mytable
http-request deny deny_status 429 if { sc_http_req_rate(0) gt 1000 }
default_backend app

backend app
server app1 10.0.0.1:3000 check
server app2 10.0.0.2:3000 check

Параметры peer:

peer <name> <ip>:<port> [resolvers <name>]

^ Настройка DNS resolution для пиров

64Что такое http-request rules в HAProxy?
frontend web
  bind *:80

Установка заголовков

http-request set-header X-Real-IP %[src]
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Request-ID %[uuid()]

Перенаправление

http-request redirect scheme https unless { ssl_fc }
http-request redirect location /maintenance if { path_beg /admin } { nbsrv(app) lt 2 }

Замена пути

http-request set-path /api%[path] if { path_beg /v1 }

Аутентификация

http-request auth realm "Restricted" unless { http_auth(userlist Users) }
http-request deny deny_status 403 if { path_beg /secret }

Отбрасывание тела

http-request disable-l7-retry

Замена метода

http-request set-method POST if { path_beg /api }

default_backend app

65Что такое http-response rules в HAProxy?
backend app
  server app1 10.0.0.1:3000 check

Добавление заголовков

http-response set-header X-Backend app1
http-response set-header X-Powered-By ""
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains"

Удаление заголовков

http-response del-header X-Powered-By
http-response del-header Server

Кэширование (если включено)

http-response cache-store mycache

Замена тела ответа

http-response replace-header Set-Cookie (.*) "; SameSite=Strict; \1"

Замена статуса

http-response set-status 200 if { status 201 }

Scrub cookies for privacy

http-response del-header Set-Cookie if { path_beg /api }

CORS

http-response set-header Access-Control-Allow-Origin "*" if { res.hdr(Origin) -m found }

66Что такое tcp-request rules в HAProxy?
frontend tcp_front
  bind *:22
  mode tcp

Inspection delay

tcp-request inspect-delay 5s

Accept if content matches

tcp-request content accept if { req.ssl_hello_type 1 }

Reject by IP

tcp-request connection reject if { src 10.0.0.0/8 }

Rate limiting по соединениям

stick-table type ip size 100k expire 30s store conn_cur,conn_rate(10s)
tcp-request connection track-sc1 src
tcp-request connection reject if { sc_conn_cur(0) gt 100 }
tcp-request connection reject if { sc_conn_rate(0) gt 1000 }

Content switching based on SNI

tcp-request content switch-case
use-server app1 if { req_ssl_sni -i app1.example.com }
use-server app2 if { req_ssl_sni -i app2.example.com }
default-server app3

Proxy protocol

tcp-request connection expect-proxy layer4

default_backend tcp_back

backend tcp_back
server app1 10.0.0.1:3000 check
server app2 10.0.0.2:3000 check

67Что такое connection pooling в HAProxy?
backend app
  # Не закрывать соединения с backend
  option http-keep-alive
  option http-server-close
  option http-pretend-keepalive

Pool size

pool-max-conns 50
pool-purge-delay 1000
pool-conn-name "backend-pool"

Concurrency

concurrency 10
maxconn 1000

server app1 10.0.0.1:3000 check maxconn 200
server app2 10.0.0.2:3000 check maxconn 200

Connection reuse

http-reuse safe

Timeouts

timeout connect 5s
timeout client 30s
timeout server 30s
timeout http-keep-alive 60s
timeout queue 10s

frontend web
bind *:80

Client-side keep-alive

timeout client 30s
default_backend app

68Что такое stats admin в HAProxy?
frontend web
  bind *:80

Stats page

stats enable
stats uri /stats
stats refresh 5s
stats show-desc "Production HAProxy"
stats show-legends
stats show-node
stats auth admin:StrongPassword123
stats admin if LOCALHOST

Stats через UNIX socket

stats socket /var/run/haproxy.sock mode 600 level admin

default_backend app

backend app
server app1 10.0.0.1:3000 check
server app2 10.0.0.2:3000 check

REST API:

echo "show info" | socat stdio /var/run/haproxy.sock

echo "show stat" | socat stdio /var/run/haproxy.sock

echo "show pools" | socat stdio /var/run/haproxy.sock

echo "disable server app/app1" | socat stdio /var/run/haproxy.sock

echo "enable server app/app1" | socat stdio /var/run/haproxy.sock

echo "set weight app/app1 50" | socat stdio /var/run/haproxy.sock

69Что такое advanced ACLs в HAProxy?
frontend web
  bind *:80

ACL на основе заголовков

acl is_api path_beg /api
acl is_admin path_beg /admin
acl is_static path_end .css .js .png .jpg .svg

ACL на основе cookie

acl has_session cookie(SESSION) -m found
acl is_premium cookie(USER_TYPE) premium

ACL на основе IP

acl is_internal src 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
acl is_blocked src -f /etc/haproxy/blocked_ips.lst

ACL на основе метода

acl is_get method GET
acl is_post method POST
acl is_write method POST PUT DELETE PATCH

ACL на основе SSL

acl is_https ssl_fc
acl has_sni req.ssl_sni -i example.com

ACL на основе тела запроса

acl has_json req.body -m reg {"username":

Сложные условия

use_backend api if is_api !is_blocked
use_backend admin if is_admin is_internal
block if is_write !has_session
redirect location https://login.example.com if !is_https !is_api

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions