← Все заметки
Сети

VPN-CA: edge на Caddy + NaiveProxy + Hysteria2

Развёртывание внешнего edge для выборочного gateway: Caddy и NaiveProxy на TCP/443, Hysteria2 на UDP/443, TLS, firewall и контрольные проверки.

Статус: актуальноОпубликовано: 2026-09-29Обновлено: 2026-09-29

Проверено на: AlmaLinux 10.2 · Caddy 2.11.4 · Hysteria2 2.12.3

← Обзор мини-проекта

Роль edge

Внешний VPS завершает оба транспортных протокола и даёт единый egress IP:

Internet clients
      |
      | TCP/443
      v
   Caddy
forward_proxy
      |
      +--> Internet

local gateway
      |
      | UDP/443
      v
  Hysteria2
      |
      +--> Internet

В примерах используется:

edge.example.net
203.0.113.10

Реальные адреса, логины и секреты публиковать не нужно.

Базовые требования

Для VPS достаточно небольших ресурсов, если через него проходит только selected traffic:

Перед настройкой полезно убедиться, что IPv4 routing обычного VPS работает независимо от прокси.

ip -4 addr
ip route
curl -4 https://api.ipify.org

Caddy и Naive forward proxy

Используется Caddy с модулем forward_proxy. На TCP/443 он одновременно даёт нормальный HTTPS front и Naive-compatible forward proxy.

Ключевой момент — отключить HTTP/3, чтобы UDP/443 остался свободным для Hysteria2.

Упрощённый глобальный блок:

{
    order forward_proxy before file_server

    servers {
        protocols h1 h2
    }
}

Пример site block:

edge.example.net {
    forward_proxy {
        basic_auth USER PASSWORD
        hide_ip
        hide_via
        probe_resistance
    }

    root * /var/www/edge
    file_server
}

Front полезен не только как маскировка. Он позволяет обычным браузером проверить TLS, SNI и HTTP/2 независимо от proxy CONNECT.

Проверка TCP front

После запуска Caddy:

curl -sSI --http2 https://edge.example.net/

Ожидается обычный HTTP response без ошибок сертификата.

Проверяем сокет:

ss -lntp | grep ':443'

TCP/443 должен принадлежать Caddy.

Hysteria2 на UDP/443

Hysteria2 использует тот же hostname и TLS identity, но слушает UDP/443.

Упрощённая конфигурация:

listen: :443

tls:
  cert: /path/to/fullchain.pem
  key: /path/to/privkey.pem
  sniGuard: strict

obfs:
  type: salamander
  salamander:
    password: CHANGE_ME

auth:
  type: password
  password: CHANGE_ME

udpIdleTimeout: 60s

Секреты лучше держать вне статьи и вне shell history.

Если сертификаты выдаёт Caddy, Hysteria2 должен иметь только необходимые права чтения. Не нужно делать каталоги сертификатов world-readable.

systemd

Сервис Hysteria2 должен стартовать автоматически и перезапускаться при сбое.

Минимальные эксплуатационные проверки:

systemctl is-enabled hysteria-server
systemctl is-active hysteria-server
journalctl -u hysteria-server -n 50 --no-pager

Название unit может отличаться в зависимости от способа установки.

Firewall

На edge нужны оба 443:

firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=443/udp
firewall-cmd --reload

Проверка:

firewall-cmd --list-all

Важно не перепутать: service=https обычно открывает только TCP/443.

Проверяем Hysteria2 отдельно от TUN

Перед интеграцией с sing-box полезно доказать, что Hysteria2 работает сам по себе.

Для UDP лучше использовать реальный UDP payload, например DNS forwarding. Если тест подтверждает только TCP внутри Hysteria2, это ещё не доказывает рабочий UDP relay.

На edge во время теста удобно смотреть:

tcpdump -lni eth0 -nn       '((udp port 443) or (host 8.8.8.8 and udp port 53))'

Рабочая последовательность выглядит так:

client -> edge UDP/443
edge -> 8.8.8.8:53
8.8.8.8:53 -> edge
edge UDP/443 -> client

Почему один IP и один порт удобны

Снаружи проект использует один адрес и один номер порта:

TCP/443 -> Naive
UDP/443 -> Hysteria2

Это упрощает firewall, DNS и диагностику.

При этом конфликта нет, потому что TCP и UDP — разные транспортные сокеты.

Контрольный checklist edge

Дальше

Следующая часть: локальный sing-box gateway и MikroTik policy routing.

Ссылки