🦎 Hysteria 2 — ACL и маршрутизация трафика

О чём заметка

Как настроить на сервере Hysteria 2 правила ACL: блокировать адреса, разводить трафик по разным «выходам» (outbounds) и перехватывать соединения. Это серверная возможность — задаётся в серверном конфиге. Обзор протокола — тут.

TL;DR

  • ACL (Access Control List) — список правил на сервере, которые решают, что делать с каждым соединением клиента: пропустить, заблокировать или отправить через определённый outbound.
  • Outbound — это «выход»/«шлюз», через который соединение уходит в интернет: direct (напрямую), socks5 или http (через ещё один прокси). ACL связывает адреса с нужным outbound.
  • Правила матчатся сверху вниз, срабатывает первое подходящее; если ни одно не подошло — используется первый (default) outbound.
  • ACL полностью работает без своих outbound’ов — встроенные direct, reject, default доступны всегда. Самое частое применение — просто заблокировать список адресов через reject(...).
  • ACL — только на стороне сервера. В Hysteria 2 клиентского ACL пока нет (см. обзор).

Что такое ACL и outbounds простыми словами

Представьте, что сервер Hysteria — это диспетчер, через которого проходят все запросы клиента. Outbound — это «дверь на выход»: через какую дверь выпустить соединение наружу. По умолчанию дверь одна — direct (сервер идёт в интернет напрямую от своего имени). Но дверей может быть несколько: например, ещё одна ведёт через сторонний SOCKS5-прокси.

ACL — это список правил вида «такой-то адрес → в такую-то дверь» (или «такой-то адрес → заблокировать»). Диспетчер смотрит правила по порядку сверху вниз и применяет первое, которое подошло под адрес запроса.

Зачем это нужно на практике:

  • Блокировать нежелательные адреса/протоколы (реклама, локальные сети, спам-порты).
  • Разводить трафик: например, весь трафик — напрямую, а Netflix — через отдельный резидентный прокси, который Netflix не банит.
  • Перехватывать соединения на другой адрес (например, подменять DNS-сервер).

Синтаксис правил

Правило ACL — это одна из форм:

outbound(address)
outbound(address, proto/port)
outbound(address, proto/port, hijack_address)
# строка-комментарий начинается с #

Где outbound — имя выхода (свой из списка outbounds или встроенный), address — на какой адрес соединение, proto/port — необязательный фильтр по протоколу/порту, hijack_address — необязательный адрес перехвата.

Типы адресов

  • Один IP: 1.1.1.1 или 2606:4700:4700::1111.
  • CIDR-подсеть: 73.0.0.0/8 или 2001:db8::/32.
  • Домен (без поддоменов): example.com.
  • Домен с wildcard: *.example.com или *.google.*.
  • Суффикс домена (с поддоменами): suffix:example.com — матчит и сам домен, и все поддомены.
  • GeoIP — по стране: geoip:cn, geoip:us.
  • GeoSite — по категории сайтов: geosite:netflix, geosite:google (с атрибутами — geosite:google@ads).
  • all — все адреса. Обычно ставится последним как правило «для всего остального».

Что такое GeoIP/GeoSite

GeoIP — база «IP → страна», позволяет писать правила про целые страны, не перечисляя подсети. GeoSite — база «домен → категория» (netflix, google, facebook…), удобна для правил про сервисы целиком. Hysteria при первом использовании таких правил сама скачивает свежие базы (из проекта Loyalsoldier/v2ray-rules-dat) в рабочую директорию.

Протокол и порт

  • tcp / tcp/* — все TCP-порты, udp / udp/* — все UDP.
  • tcp/80 — TCP порт 80; udp/53 — UDP порт 53; udp/20000-30000 — диапазон.
  • */443 — TCP и UDP на 443; * или опущено — любой протокол и порт.

Адрес перехвата (hijack)

Если указан третий аргумент, соединение под это правило перенаправляется на заданный адрес (только IP, не домен). Пример — насильно завернуть публичный DNS 8.8.8.8 на 1.1.1.1.

Встроенные outbounds

Даже с пустым списком outbounds всегда доступны три встроенных:

  • direct — прямое соединение (конфигурация auto, без привязки к интерфейсу).
  • reject — отклонить соединение (это и есть «блокировка»).
  • default — первый outbound из списка; если список пуст — эквивалент direct.

Подключение ACL в конфиге сервера

ACL задаётся в серверном config.yaml. Можно писать правила прямо в конфиге (inline) или вынести в отдельный файл (file) — но не то и другое одновременно.

Inline-вариант (правила прямо в конфиге):

acl:
  inline:
    - reject(suffix:v2ex.com)
    - reject(all, udp/443)
    - reject(geoip:cn)
    - reject(geosite:netflix)

Вариант с файлом:

acl:
  file: some.txt

Примеры

Самое частое — просто заблокировать нежелательное (тут даже свои outbound’ы не нужны, хватает встроенного reject):

# Заблокировать китайские IP и Facebook
reject(geoip:cn)
reject(geosite:facebook)
# Заблокировать локальные сети
reject(10.0.0.0/8)
reject(172.16.0.0/12)
reject(192.168.0.0/16)
reject(fc00::/7)

Блокировка QUIC/HTTP/3 через ACL

Правило reject(all, udp/443) блокирует QUIC (HTTP/3) для всего проксируемого трафика. Это полезный приём: HTTP/3 через прокси Hysteria не ускоряется (см. Скорость и Brutal), и принудительный откат сайтов на TCP-based HTTP/2 часто даёт более стабильную скорость.

Разведение трафика по разным выходам. Пусть заданы outbound’ы v4_only, v6_only (оба direct с фиксированным IP-режимом) и some_proxy (SOCKS5):

# Google — через IPv6-выход
v6_only(suffix:google.com)
# Twitter — через IPv4-выход
v4_only(suffix:twitter.com)
# ipinfo.io — через сторонний SOCKS5
some_proxy(ipinfo.io)
# Перехватить 8.8.8.8 на 1.1.1.1, только UDP 53 (DNS)
default(8.8.4.4, udp/53, 1.1.1.1)
# Всё остальное — напрямую
direct(all)

Порядок правил важен

Правила матчатся строго сверху вниз, применяется первое подходящее. Если ни одно не сработало — берётся первый outbound из списка (default). Поэтому общее правило all всегда ставят последним, иначе оно «съест» все соединения раньше, чем до них дойдут более специфичные правила. Важно и то, что IP-правило действует на все соединения, ведущие к этому IP, — даже если клиент запросил домен: Hysteria сперва резолвит домен и матчит и по домену, и по получившемуся IP.

📚 См. также


🤖 Эти статьи открыты — можно обучать на них ИИ

При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны в Forgejo: исходник этой заметки · весь репозиторий.