Проксі та реверс-проксі¶
Проксі-сервер — посередник між клієнтом та сервером. Залежно від того, з якого боку він стоїть, це може бути forward proxy (прямий) або reverse proxy (зворотний).
Forward Proxy (прямий проксі)¶
Forward proxy стоїть перед клієнтами і допомагає їм звертатись до інтернету.
┌─────────────────────────────────────────────────────────────────┐
│ FORWARD PROXY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Офіс / Корпоративна мережа Інтернет │
│ │
│ ┌────────┐ ┌────────────┐ │
│ │Client 1│──┐ ┌────▶│ google.com │ │
│ └────────┘ │ ┌──────────────┐ │ └────────────┘ │
│ │ │ │ │ │
│ ┌────────┐ ├────▶│Forward Proxy │──────┼────▶┌────────────┐ │
│ │Client 2│──┤ │ │ │ │ github.com │ │
│ └────────┘ │ └──────────────┘ │ └────────────┘ │
│ │ │ │ │
│ ┌────────┐ │ │ └────▶┌────────────┐ │
│ │Client 3│──┘ │ │blocked.com │ │
│ └────────┘ │ │ ✗ │ │
│ │ └────────────┘ │
│ │ │
│ [Кешування] │
│ [Фільтрація] │
│ [Анонімізація] │
│ │
└─────────────────────────────────────────────────────────────────┘
Навіщо forward proxy?¶
1. Контроль доступу
Компанія блокує соцмережі в робочий час:
- facebook.com → заблоковано
- youtube.com → заблоковано
- github.com → дозволено
2. Кешування
Client 1 запитує ubuntu.iso (2 GB)
→ Proxy завантажує з інтернету
→ Зберігає в кеш
Client 2 запитує ubuntu.iso
→ Proxy віддає з кешу (миттєво!)
3. Анонімність
Сервер бачить IP проксі, а не клієнта:
Client (192.168.1.100) → Proxy (203.0.113.50) → Server
↑
Сервер бачить цей IP
4. Обхід геообмежень
Клієнт в Україні → Proxy в США → Netflix US
(американський IP)
Приклади forward proxy¶
- Squid — класичний корпоративний проксі
- Privoxy — проксі з фільтрацією реклами
- SOCKS proxy — проксі на рівні TCP (не тільки HTTP)
- VPN — по суті, теж forward proxy на рівні мережі
Reverse Proxy (реверс-проксі)¶
Reverse proxy стоїть перед серверами і приймає запити від клієнтів.
┌─────────────────────────────────────────────────────────────────┐
│ REVERSE PROXY │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Інтернет Дата-центр │
│ │
│ ┌────────┐ ┌────────────┐ │
│ │Client 1│──┐ ┌────▶│ Backend 1 │ │
│ └────────┘ │ ┌──────────────┐ │ │ (app:8000) │ │
│ │ │ │ │ └────────────┘ │
│ ┌────────┐ ├────▶│Reverse Proxy │──────┤ │
│ │Client 2│──┤ │ (Caddy) │ │ ┌────────────┐ │
│ └────────┘ │ │ :443 │ ├────▶│ Backend 2 │ │
│ │ └──────────────┘ │ │ (app:8000) │ │
│ ┌────────┐ │ │ │ └────────────┘ │
│ │Client 3│──┘ │ │ │
│ └────────┘ │ │ ┌────────────┐ │
│ │ └────▶│ Backend 3 │ │
│ [SSL/TLS] │ (app:8000) │ │
│ [Load Balancing] └────────────┘ │
│ [Caching] │
│ [Security] │
│ │
└─────────────────────────────────────────────────────────────────┘
Навіщо reverse proxy?¶
1. SSL Termination
Клієнт ←── HTTPS (шифрований) ──→ Reverse Proxy
│
│ HTTP (нешифрований)
▼
Backend
Бекенд не морочиться з сертифікатами — це робить проксі.
2. Балансування навантаження (Load Balancing)
┌────────────────┐
│ Reverse Proxy │
└───────┬────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Server 1 │ │ Server 2 │ │ Server 3 │
│ 33% │ │ 33% │ │ 33% │
└──────────┘ └──────────┘ └──────────┘
Навантаження розподіляється між серверами.
3. Захист бекенду
Інтернет бачить:
- IP reverse proxy
- Порт 443
Інтернет НЕ бачить:
- IP бекенд серверів
- Внутрішні порти
- Структуру інфраструктури
Атакувати напряму бекенд неможливо.
4. Кілька сервісів на одному IP
example.com → Frontend (port 3000)
api.example.com → Backend (port 8000)
wiki.example.com → Wiki (port 5000)
matrix.example.com → Matrix (port 8008)
Все на одному сервері, один IP, один порт 443!
5. Кешування
GET /static/logo.png
Перший запит:
Proxy → Backend → Response → Cache → Client
Наступні запити:
Proxy → Cache → Client (backend не чіпаємо)
Приклади reverse proxy¶
- Caddy — сучасний, автоматичний HTTPS
- Nginx — найпопулярніший, гнучкий
- HAProxy — найшвидший для load balancing
- Traefik — заточений під Docker/Kubernetes
- Apache httpd — класика, але застарілий
Порівняння¶
┌────────────────────────────────────────────────────────────────┐
│ FORWARD vs REVERSE PROXY │
├────────────────────────────────────────────────────────────────┤
│ │
│ FORWARD PROXY: │
│ │
│ [Clients] ──→ [PROXY] ──→ [Internet] ──→ [Servers] │
│ ↑ │
│ Знає про проксі │
│ Налаштовує браузер │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ REVERSE PROXY: │
│ │
│ [Clients] ──→ [Internet] ──→ [PROXY] ──→ [Backends] │
│ ↑ │
│ Клієнт НЕ знає │
│ що є проксі │
│ │
└────────────────────────────────────────────────────────────────┘
| Аспект | Forward Proxy | Reverse Proxy |
|---|---|---|
| Захищає | Клієнтів | Сервери |
| Клієнт знає? | Так | Ні |
| Приховує | IP клієнта | IP серверів |
| Типове використання | Корпоративні мережі | Веб-сервіси |
| Приклади | Squid, VPN | Caddy, Nginx |
Практичний приклад: Caddy як reverse proxy¶
Маємо:
- Frontend на порту 3000
- Backend API на порту 8000
- Домен wiki.example.com
Caddyfile¶
wiki.example.com {
# API запити
handle /api/* {
reverse_proxy localhost:8000
}
# Все інше — frontend
handle {
reverse_proxy localhost:3000
}
}
Що відбувається?¶
┌─────────────────────────────────────────────────────────────────┐
│ │
│ Browser: https://wiki.example.com/api/users │
│ │ │
│ │ HTTPS (port 443) │
│ ▼ │
│ ┌───────────────────────────────────┐ │
│ │ Caddy │ │
│ │ ┌─────────────────────────────┐ │ │
│ │ │ /api/* → localhost:8000 │ │ ← Маршрутизація │
│ │ │ /* → localhost:3000 │ │ │
│ │ └─────────────────────────────┘ │ │
│ │ │ │
│ │ [Auto HTTPS: Let's Encrypt] │ │
│ └───────────────────────────────────┘ │
│ │ │
│ │ HTTP (port 8000) │
│ ▼ │
│ ┌───────────────────────────────────┐ │
│ │ Backend (FastAPI) │ │
│ │ localhost:8000 │ │
│ └───────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Docker Compose приклад¶
services:
caddy:
image: caddy:2-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
networks:
- web
frontend:
image: frontend:latest
networks:
- web
# НЕ публікуємо порти назовні!
backend:
image: backend:latest
networks:
- web
# НЕ публікуємо порти назовні!
networks:
web:
volumes:
caddy_data:
# Caddyfile для Docker
wiki.example.com {
handle /api/* {
reverse_proxy backend:8000 # Ім'я Docker сервісу
}
handle {
reverse_proxy frontend:3000
}
}
Типові помилки¶
1. Неправильні заголовки¶
# Проблема: backend бачить IP проксі, а не клієнта
# Рішення для Caddy:
wiki.example.com {
reverse_proxy backend:8000 {
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
2. WebSocket не працює¶
# Проблема: WebSocket з'єднання обриваються
# Рішення: Caddy підтримує автоматично
# Для Nginx:
location /ws {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
3. Великі файли не завантажуються¶
# Nginx: збільшити ліміт
client_max_body_size 100M;
# Caddy: немає ліміту за замовчуванням
# Але backend може мати свій ліміт
4. Таймаути¶
# Довгі запити обриваються
# Nginx:
proxy_connect_timeout 60s;
proxy_read_timeout 300s;
proxy_send_timeout 60s;
# Caddy:
reverse_proxy backend:8000 {
transport http {
dial_timeout 10s
response_header_timeout 60s
}
}
Див. також¶
- Caddy — налаштування Caddy
- VPS та хмари — де хостити
- Docker Compose — контейнеризація сервісів
Шлях: services/web/proxy-reverse-proxy.md