Happ-gateway

Материал из wiki.ramba-art.ru
Перейти к навигации Перейти к поиску

HAPP Gateway — централизованный прокси-шлюз RAMBA ART

HAPP Gateway — отдельный сетевой шлюз в инфраструктуре RAMBA ART, предназначенный для централизованного доступа внутренних сервисов к внешним ресурсам через VLESS/HAPP.

Шлюз используется, в частности, для работы Telegram-ботов и сервисов, которым требуется стабильный SOCKS5/HTTP-прокси.

Основная идея заключается в том, что настройки HAPP и VLESS не требуется устанавливать отдельно на каждый сервер или контейнер. В инфраструктуре работает один выделенный LXC-контейнер, предоставляющий прокси остальным узлам локальной сети.

Общая архитектура

                         Интернет
                            │
                            │ VLESS
                            ▼
                    ┌─────────────────┐
                    │   HAPP Server   │
                    │  лучший сервер │
                    └────────┬────────┘
                             │
                             │
                    ┌────────▼────────┐
                    │  happ-gateway   │
                    │  LXC CT 502     │
                    │ 192.168.1.52    │
                    │                 │
                    │ HAPP CLI / Xray │
                    └────────┬────────┘
                             │
               ┌─────────────┴─────────────┐
               │                           │
               ▼                           ▼
       SOCKS5 proxy                  HTTP proxy
    192.168.1.52:11080           192.168.1.52:11081
               │                           │
               └─────────────┬─────────────┘
                             │
                  локальная сеть RAMBA ART
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
         Telegram Bot    OpenAI API     другие сервисы

Параметры шлюза

Параметр Значение
Контейнер CT 502
Hostname happ-gateway
IP 192.168.1.52
ОС Debian
SOCKS5 для LAN 192.168.1.52:11080
HTTP Proxy для LAN 192.168.1.52:11081
Внутренний SOCKS5 127.0.0.1:10808
Внутренний HTTP Proxy 127.0.0.1:10809
HAPP subscription ramba
Часовой пояс Europe/Moscow

HAPP CLI

Для управления подпиской используется консольный клиент HAPP.

Конфигурация хранится в:

/root/.config/happ-cli

Просмотр доступных серверов:

happ --home /root/.config/happ-cli list

Обновление подписки:

happ --home /root/.config/happ-cli sub update ramba

Запуск конкретного сервера в режиме локального proxy:

happ --home /root/.config/happ-cli \
  connect "Швеция" \
  --mode proxy \
  --socks 10808 \
  --http 10809

Важно: сервер выбирается по текстовому тегу страны, а не по его номеру.

Это было сделано после обнаружения особенности HAPP: после обновления подписки порядковые номера серверов могут изменяться.

Например:

до обновления:

#32 → Нидерланды

после обновления:

#32 → Финляндия
#33 → Нидерланды

Поэтому конфигурация вида:

connect 32

небезопасна.

Используется:

connect "Швеция"

Таким образом изменение порядка серверов в подписке не приводит к подключению к другой стране.

Основной systemd-сервис

HAPP запускается автоматически через systemd.

Файл:

/etc/systemd/system/happ-gateway.service

Конфигурация:

[Unit]
Description=HAPP VLESS Proxy Gateway
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Environment=HOME=/root
ExecStart=/usr/local/bin/happ --home /root/.config/happ-cli connect "Швеция" --mode proxy --socks 10808 --http 10809
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Управление:

systemctl status happ-gateway.service
systemctl restart happ-gateway.service
systemctl stop happ-gateway.service

Просмотр журнала:

journalctl -u happ-gateway.service

Публикация proxy в локальную сеть

Сам HAPP создаёт локальные proxy:

SOCKS5: 127.0.0.1:10808
HTTP:   127.0.0.1:10809

Для использования другими машинами инфраструктуры proxy публикуются в LAN.

В рабочей конфигурации используются:

SOCKS5:
192.168.1.52:11080

HTTP:
192.168.1.52:11081

Это позволяет другим контейнерам использовать HAPP Gateway без установки HAPP/Xray на каждом из них.

Например:

curl --proxy socks5h://192.168.1.52:11080 \
  https://api.ipify.org

Параметр socks5h важен: DNS-разрешение выполняется через proxy, а не локальной машиной.

Проверка внешнего IP

Непосредственно на HAPP Gateway:

curl -sS --max-time 15 \
  --proxy socks5h://127.0.0.1:10808 \
  https://api.ipify.org
echo

Во время настройки при использовании сервера Швеции был получен внешний IP:

87.251.85.130

Внешний IP не является постоянным и может измениться при переключении HAPP-сервера.

Автоматический выбор лучшего сервера

Для повышения стабильности был реализован собственный механизм автоматического тестирования HAPP-серверов.

Скрипт:

/usr/local/sbin/happ-autoselect.sh

Он периодически проверяет доступные серверы и выбирает наиболее быстрый рабочий сервер.

Почему не используется обычный ping

ICMP ping не всегда отражает реальное качество proxy-соединения.

Для Telegram-ботов значительно важнее фактическое время выполнения HTTPS-запроса через:

клиент
  ↓
HAPP
  ↓
VLESS
  ↓
удалённый сервер
  ↓
Telegram API

Поэтому каждый сервер тестируется реальным HTTPS-запросом через временный SOCKS5 proxy.

Тестовая цель:

https://api.telegram.org

Алгоритм проверки

Для каждой страны выполняются три запроса.

HAPP candidate
      │
      ▼
127.0.0.1:12080
      │
      │ SOCKS5
      ▼
api.telegram.org

Из трёх результатов рассчитывается медиана времени ответа.

Использование медианы позволяет уменьшить влияние единичного скачка задержки.

Например:

0.19 s
0.21 s
0.85 s

median = 0.21 s

Сервер считается рабочим, если успешно выполнено не менее двух из трёх запросов.

Серверы с ошибками

Если сервер не обеспечивает стабильное соединение:

test 1: TIMEOUT/ERROR
test 2: TIMEOUT/ERROR
test 3: TIMEOUT/ERROR

REJECTED

он исключается из текущего выбора.

При тестировании, например, некоторые серверы Польши, Эстонии, Франции и Сингапура не обеспечивали соединение с Telegram API и автоматически отбрасывались.

Это не означает, что сервер навсегда исключён: при следующей проверке он тестируется снова.

Защита от постоянного переключения серверов

Выбирать сервер только по минимальной задержке недостаточно.

Например:

текущий сервер: 220 ms
другой сервер:  215 ms

Переключение ради 5 ms не имеет практического смысла и приводит к ненужным перезапускам HAPP.

Поэтому используется порог:

15 %

Новый сервер выбирается только если он быстрее текущего как минимум на 15%.

Логика:

лучший сервер
      │
      ▼
быстрее текущего ≥ 15% ?
      │
   ┌──┴──┐
   │     │
  НЕТ    ДА
   │     │
   ▼     ▼
ничего  изменить
не      сервер
делать     │
           ▼
      restart HAPP

Результаты тестирования

Во время настройки были получены, например, следующие значения:

Сервер Медиана Результат
Швеция ~0.20–0.22 s Лучший
Финляндия ~0.24–0.25 s Работает
Нидерланды ~0.25–0.28 s Работает
Литва ~0.27–0.29 s Работает
Казахстан ~0.64–0.71 s Работает
Канада ~0.83–0.84 s Работает
Дубай ~0.95–0.96 s Работает
Бразилия ~1.50 s Работает
Япония ~1.65 s Работает
Германия ~1.5–2.1 s Работает нестабильно
США ~2.4 s Высокая задержка
Польша TIMEOUT Отклонён
Эстония TIMEOUT Отклонён
Франция TIMEOUT Отклонён
Сингапур TIMEOUT Отклонён

На момент настройки наиболее быстрым маршрутом оказался сервер:

🇸🇪 Швеция
swsq2.aquafinas.org:443

systemd timer автоматической проверки

Для автоматического запуска используется:

/etc/systemd/system/happ-autoselect.service
[Unit]
Description=HAPP automatic best server selector
After=network-online.target happ-gateway.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/happ-autoselect.sh

Таймер:

/etc/systemd/system/happ-autoselect.timer
[Unit]
Description=Benchmark HAPP servers every hour

[Timer]
OnBootSec=5min
OnUnitActiveSec=1h
RandomizedDelaySec=2min
Persistent=true

[Install]
WantedBy=timers.target

Активация:

systemctl daemon-reload
systemctl enable --now happ-autoselect.timer

Проверка:

systemctl status happ-autoselect.timer --no-pager
systemctl list-timers --all | grep happ

Таким образом benchmark выполняется приблизительно один раз в час.

RandomizedDelaySec=2min добавляет небольшой случайный сдвиг времени запуска.

Важное решение: не обновлять подписку каждый час

Изначально happ-autoselect.sh перед каждым benchmark выполнял:

happ --home /root/.config/happ-cli sub update ramba

Во время тестирования обновление подписки один раз завершилось ошибкой.

В результате список серверов временно не был доступен для скрипта:

WARNING: subscription update failed
Skipping США: not found
Skipping Литва: not found
...
ERROR: no working servers found

Основной HAPP Gateway при этом продолжил работать на текущем сервере.

После анализа было принято решение разделить две независимые операции:

  1. обновление подписки;
  2. benchmark серверов.

Часовой benchmark больше не выполняет sub update.

Он работает с уже имеющейся локальной подпиской.

Это делает автоматический выбор сервера безопаснее: временная недоступность сервера подписки не влияет на уже работающий proxy.

Отказоустойчивость

Система построена по принципу:

не удалось провести benchmark
             │
             ▼
     НЕ менять сервер
             │
             ▼
оставить работающий HAPP
на текущем сервере

То есть ошибка системы мониторинга не должна ломать рабочее соединение.

Это особенно важно для сервисов, которые постоянно используют шлюз.

Просмотр логов автоматического выбора

Последние события:

journalctl -t happ-autoselect -n 100 --no-pager

Наблюдение в реальном времени:

journalctl -t happ-autoselect -f

Типичный успешный результат:

Best server: Швеция (0.217001s)
Current Швеция: 0.217001s
Improvement: 0.0%
Already using best server: Швеция
Keeping current server: Швеция
=== HAPP benchmark finished ===

Если другой сервер значительно быстрее:

Best server: Швеция (0.202160s)
Improvement: 18.4%
Switching ...
Switch successful

Настройка часового пояса

Первоначально контейнер использовал UTC:

Local time: 07:50 UTC
Time zone: Etc/UTC

Для удобства администрирования установлен московский часовой пояс:

timedatectl set-timezone Europe/Moscow

Проверка:

timedatectl
date

После настройки:

Local time: 10:50 MSK
Universal time: 07:50 UTC
Time zone: Europe/Moscow (MSK, +0300)
System clock synchronized: yes

После изменения timezone systemd автоматически начал отображать время таймеров и журналов в MSK.

Использование HAPP Gateway приложениями

Для приложений в локальной сети рекомендуется использовать:

SOCKS5:

socks5://192.168.1.52:11080

или при использовании curl:

socks5h://192.168.1.52:11080

HTTP Proxy:

http://192.168.1.52:11081

Таким образом приложение не знает ничего о VLESS, Xray, подписках и конкретном внешнем сервере.

Для него HAPP Gateway является обычным proxy:

Приложение
     │
     │ SOCKS5
     ▼
192.168.1.52:11080
     │
     ▼
HAPP Gateway
     │
     │ VLESS
     ▼
лучший внешний сервер
     │
     ▼
Интернет

Итоговая схема

                    RAMBA ART LAN
                         │
       ┌─────────────────┼─────────────────┐
       │                 │                 │
       ▼                 ▼                 ▼
 Telegram Bot       Kuzya 2.0        другие сервисы
       │                 │                 │
       └─────────────────┼─────────────────┘
                         │
                         │ SOCKS5
                         ▼
                 192.168.1.52:11080
                         │
                ┌────────▼────────┐
                │  HAPP Gateway   │
                │     CT 502      │
                │                 │
                │ HAPP CLI + Xray │
                └────────┬────────┘
                         │
                         │ VLESS
                         ▼
                 выбранный сервер
                         │
                         ▼
                      Internet

Каждый час:

happ-autoselect.timer
          │
          ▼
happ-autoselect.sh
          │
          ▼
проверка серверов
через Telegram HTTPS
          │
          ▼
расчёт median
          │
          ▼
лучший быстрее ≥15% ?
       ┌──┴───┐
       │      │
      НЕТ     ДА
       │      │
       ▼      ▼
 оставить   изменить
 текущий    сервер
             │
             ▼
       restart HAPP

Текущее состояние

На момент завершения настройки:

  • HAPP Gateway работает в отдельном LXC-контейнере;
  • SOCKS5 и HTTP proxy доступны другим узлам LAN;
  • основной HAPP управляется через systemd;
  • сервер задаётся по стабильному текстовому тегу страны;
  • реализован автоматический benchmark серверов;
  • benchmark выполняется примерно раз в час;
  • проверяется реальная доступность Telegram API через proxy;
  • используется медиана трёх измерений;
  • неработающие серверы автоматически отбрасываются;
  • переключение выполняется только при выигрыше не менее 15%;
  • ошибка benchmark не отключает рабочий proxy;
  • обновление HAPP-подписки отделено от механизма автоматического выбора;
  • системное время контейнера отображается в MSK;
  • HAPP Gateway готов для использования Telegram-ботами и другими сервисами RAMBA ART.