unProxy / Документация

От исходников
до первого запроса.

unProxy — самостоятельный HTTP, HTTP/3 и SOCKS5 прокси на Go. Начните с локального запуска, затем подключите нужный следующий узел. unPreSock понадобится только для прозрачной маршрутизации на Linux-шлюзе.

01 / Начало работы

Сборка и запуск

Нужны исходники проекта и Go 1.26 или новее. Команды ниже рассчитаны на Linux и Bash. Первый блок выполняйте из корня репозитория; после него вы окажетесь в каталоге unProxy/.

Linux · Bash · из корня репозитория
cd unProxy
go build -o unproxy .
UNPROXY_LISTENTO=127.0.0.1:8585 \
SOCKS5_LISTENTO=127.0.0.1:1080 \
./unproxy

Оставьте процесс работающим. HTTP прокси доступен на 127.0.0.1:8585, SOCKS5 — на 127.0.0.1:1080. Оба адреса принимают подключения только с этого компьютера. Для остановки нажмите Ctrl + C.

В другом терминале отправьте запрос через один из протоколов. Для этих примеров нужен curl и доступ к example.com.

Проверка · другой терминал
curl --proxy http://127.0.0.1:8585 https://example.com
curl --proxy socks5h://127.0.0.1:1080 https://example.com

В браузере укажите HTTP прокси 127.0.0.1:8585 или SOCKS5 127.0.0.1:1080. При SOCKS5 включите разрешение DNS-имён через прокси, если клиент предлагает такую настройку.

Windows / PowerShell

Из корня репозитория, в новом окне PowerShell с установленным Go:

Windows · PowerShell
cd unProxy
go build -o unproxy.exe .
$env:UNPROXY_LISTENTO = '127.0.0.1:8585'
$env:SOCKS5_LISTENTO = '127.0.0.1:1080'
.\unproxy.exe

Для проверки из другого окна PowerShell используйте curl.exe --proxy http://127.0.0.1:8585 https://example.com. В Windows переменные из примера сохраняются до закрытия окна PowerShell.

О платформах. unProxy рассчитан на Linux и Windows. unPreSock предназначен только для Linux.

02 / Основной вход

HTTP и HTTPS через CONNECT

Для HTTP unProxy пересылает запросы к серверу назначения. Для HTTPS клиент открывает CONNECT-туннель, после чего unProxy передаёт байты между клиентом и сервером. Отдельный сертификат на клиенте для такого подключения не нужен.

HTTP listener включён по умолчанию. Если UNPROXY_LISTENTO не задан, используется 127.0.0.1:8585. Изменения переменных окружения применяются при следующем запуске процесса.

Основные настройки HTTP прокси
ПеременнаяНазначениеПо умолчанию
UNPROXY_LISTENTOАдрес и порт HTTP listener127.0.0.1:8585
UNPROXY_SECRETПроверка заголовка X-Proxy-Secret у прокси-запросовНе задан
UNPROXY_PERIODIC_STATSИнтервал вывода статистики в секундахБез периодического вывода
HTTP_MAX_IDLE_CONNSМаксимум простаивающих HTTP-соединений100
HTTP_MAX_IDLE_CONNS_PER_HOSTПростаивающие соединения на один хост10
HTTP_IDLE_TIMEOUTТаймаут простаивающего соединения, секунды90
HTTP_RESPONSE_HEADER_TIMEOUTОжидание заголовков ответа, секунды60
SHUTDOWN_TIMEOUT_SECONDSВремя завершения активных HTTP-запросов при остановке30

UNPROXY_SECRET использует собственный заголовок, а не стандартное поле пароля HTTP прокси в браузере. Клиент должен уметь отправлять X-Proxy-Secret. Не считайте этот заголовок шифрованием соединения.

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

Статистика
curl http://127.0.0.1:8585/statusline

03 / Отдельный порт

SOCKS5 для приложений

SOCKS5 работает рядом с HTTP прокси и включается переменной SOCKS5_LISTENTO. Поддерживаются TCP CONNECT и UDP ASSOCIATE, адреса IPv4, IPv6 и доменные имена. Команда BIND не поддерживается.

Настройки SOCKS5
ПеременнаяНазначениеПо умолчанию
SOCKS5_LISTENTOАдрес и порт SOCKS5 listenerSOCKS5 выключен
SOCKS5_AUTHИмя и пароль в формате user:passwordНе задан
SOCKS5_ALLOW_FROMРазрешённые IP-адреса или CIDR через запятуюБез списка ограничений
SOCKS5_MAX_CONNSОграничение одновременных подключенийБез ограничения
SOCKS5_AUTH_FAIL_LIMITЧисло ошибок авторизации до блокировки IP5; 0 отключает блокировку
SOCKS5_AUTH_BAN_SECONDSПродолжительность блокировки, секунды300

Если SOCKS5_AUTH пуст, но задан UNPROXY_SECRET, этот секрет используется как SOCKS5 пароль; имя пользователя может быть любым. Без обоих параметров локальный SOCKS5 работает без авторизации. По умолчанию запуск SOCKS5 без авторизации на адресе вне loopback отклоняется.

Для UDP нужен доступ к relay-порту. Каждая UDP ASSOCIATE сессия получает динамический UDP порт и живёт, пока открыто управляющее TCP-соединение. Поддерживаются пакеты с FRAG=0, до 64 получателей на сессию; таймаут бездействия — 120 секунд. Доступность UDP зависит также от клиента, NAT и межсетевого экрана.

04 / Вход через QUIC

HTTP/3 и CONNECT-UDP

unProxy принимает HTTP/3 на отдельном UDP-порту с TLS. Совместимый клиент может отправлять HTTP-запросы и открывать TCP CONNECT-туннели. Для передачи UDP через HTTP/3 отдельно включается расширение CONNECT-UDP (MASQUE).

Обычные HTTP и SOCKS5 входы сохраняют свои адреса. Наличие HTTP/3 listener не переключает браузер автоматически: клиент должен поддерживать HTTP/3-прокси и явно использовать этот вход. Для прозрачного доступа устройств к HTTP/3-сайтам см. QUIC relay на шлюзе.

Настройки HTTP/3 · всё выключено, пока не задан listener
ПеременнаяНазначение
UNPROXY_HTTP3_LISTENTOUDP адрес и порт, например 127.0.0.1:8443.
UNPROXY_HTTP3_CERTПуть к PEM-сертификату с цепочкой. Обязателен.
UNPROXY_HTTP3_KEYПуть к соответствующему PEM-ключу. Обязателен.
UNPROXY_SECRETСекрет в заголовке X-Proxy-Secret. Для адреса вне loopback обязателен.
UNPROXY_HTTP3_CONNECT_UDP_URI_TEMPLATEHTTPS URI template с переменными target_host и target_port. Без него CONNECT-UDP выключен.

Сначала локальный listener

Остановите предыдущий unProxy. В каталоге unProxy/ выполните пример, заменив пути на свой сертификат и ключ. Для локального клиента сертификат должен соответствовать имени или IP, по которому он обращается к прокси, и быть доверенным этому клиенту.

HTTP/3 · локальный запуск
UNPROXY_LISTENTO=127.0.0.1:8585 \
UNPROXY_HTTP3_LISTENTO=127.0.0.1:8443 \
UNPROXY_HTTP3_CERT=/path/to/proxy-fullchain.pem \
UNPROXY_HTTP3_KEY=/path/to/proxy-key.pem \
./unproxy

Для подключения с других машин задайте подходящий внешний адрес, откройте выбранный UDP-порт и установите UNPROXY_SECRET. Используйте сертификат для DNS-имени прокси от доверенного клиенту центра сертификации. Клиент должен уметь передавать X-Proxy-Secret; стандартное поле пароля HTTP-прокси не заменяет этот заголовок.

UDP через MASQUE

Добавьте к конфигурации URI template своего HTTP/3-прокси, например:

Дополнительная переменная окружения
export UNPROXY_HTTP3_CONNECT_UDP_URI_TEMPLATE='https://proxy.example.com:8443/.well-known/masque/udp/{target_host}/{target_port}/'

Замените proxy.example.com:8443 на доступное клиенту имя и порт с подходящим сертификатом. Передайте тот же template MASQUE-клиенту с поддержкой HTTP/3 Datagrams (H3_DATAGRAM). Передача полезной нагрузки через надёжные DATAGRAM capsules не предусмотрена. CONNECT-UDP передаёт UDP-датаграммы; обычный CONNECT остаётся TCP-туннелем. HTTP-запросы к конечным серверам обслуживаются существующим HTTP-транспортом, без автоматического выбора HTTP/3 на выходе.

Размер UDP-пакета ограничен MTU пути и накладными расходами туннеля. Слишком большие датаграммы и PMTU-пробы отбрасываются без закрытия сессии; IPv4-фрагментация исходящего UDP отключена на Linux и Windows. Для QUIC внутри CONNECT-UDP клиенту может потребоваться начальный размер пакета 1200 байт и отключение внутреннего поиска MTU. Эти значения не гарантируют работоспособность любого сетевого пути.

Маршрут задаётся явно. HTTP/3 listener не запускается с NEXT_SOCKS5_ADDR, TUNNEL_MODE или slave-режимом. NEXT_UNPROXY_ADDR поддерживается для HTTP-запросов и TCP CONNECT, но отвергается при включённом CONNECT-UDP. Неподдерживаемая цепочка не заменяется прямым подключением.

SOCKS5 UDP и прозрачный QUIC relay могут работать без HTTP/3 listener. Поэтому для цепочки SOCKS5 с UDP используйте отдельный обычный экземпляр unProxy.

05 / Следующий узел

Цепочки прокси

Следующий узел может быть HTTP или SOCKS5 прокси. Таблица относится к обычным TCP-входам HTTP и SOCKS5; ограничения отдельного HTTP/3 listener описаны выше.

Как направляется трафик
НастройкаHTTP / CONNECT на TCP-входеSOCKS5 CONNECTSOCKS5 UDP
NEXT_UNPROXY_ADDRЧерез HTTP upstreamЧерез HTTP CONNECTНе поддерживается
NEXT_SOCKS5_ADDRЭта настройка не применяетсяЧерез SOCKS5 upstreamЧерез SOCKS5 upstream

Пример HTTP цепочки: upstream уже должен работать на 127.0.0.1:9585. Остановите предыдущий unProxy и выполните этот блок из каталога unProxy/.

Локальный вход → HTTP upstream
UNPROXY_LISTENTO=127.0.0.1:8585 \
NEXT_UNPROXY_ADDR=127.0.0.1:9585 \
./unproxy

Для upstream unProxy с секретом добавьте NEXT_UNPROXY_SECRET. Значение передаётся в заголовке X-Proxy-Secret.

Пример SOCKS5 цепочки: upstream должен работать на 127.0.0.1:2080. Локальный вход здесь — SOCKS5 на порту 1080; HTTP listener остаётся отдельным.

Локальный SOCKS5 → SOCKS5 upstream
UNPROXY_LISTENTO=127.0.0.1:8585 \
SOCKS5_LISTENTO=127.0.0.1:1080 \
NEXT_SOCKS5_ADDR=127.0.0.1:2080 \
./unproxy

Если upstream требует авторизацию, задайте NEXT_SOCKS5_AUTH=user:password со своими значениями. Для SOCKS5 входа NEXT_SOCKS5_ADDR имеет приоритет над NEXT_UNPROXY_ADDR. Не смешивайте настройки разных примеров без явной необходимости.

Для UDP-цепочки возвращённый upstream-сервером адрес UDP relay должен быть доступен с машины unProxy. Закрытие любого управляющего TCP-соединения завершает UDP-сессию.

06 / Вспомогательный модуль · Linux

Когда нужен unPreSock

unPreSock нужен на Linux-шлюзе, если устройства не настраивают прокси сами. Он принимает перенаправленный TCP-трафик и выбирает прямой путь или upstream по HTTP Host и TLS SNI. Сам unProxy работает без этого модуля.

Для сборки модуля достаточно Go 1.25.4 или новее. Следующий блок выполняйте из корня репозитория. Просмотр справки не настраивает межсетевой экран.

unPreSock · сборка и справка
cd unPreSock
go build -o unpresock2 .
./unpresock2 -h
Основные параметры unPreSock
ПараметрНазначение
-http-proxyHTTP upstream. Для локального unProxy укажите 127.0.0.1:8585; собственное значение по умолчанию у модуля — 127.0.0.1:8989.
-socksSOCKS5 upstream. Для выбора этого пути также задайте -http-proxy="".
-clientIP или CIDR устройств, для которых создаются правила перенаправления.
-host-redirect-listДомены и шаблоны для TCP через запятую, например example.com,*.example.com. Не применяется к QUIC.
-host-redirect-fileФайл правил TCP: одно имя, IP или шаблон в строке; # начинает комментарий, !example.com принудительно выбирает direct. Файл позволяет сохранять переключения из monitor.
-ssh-uplink-userЗапускает только дочерний SSH-процесс от указанного пользователя и использует его домашний каталог и ключи. Нужен, если QUIC оставляет сам unPreSock с правами root.
-set-fwСоздаёт правила TCP 80/443; также устанавливает выбранную QUIC-политику через iptables. Нужны права root.
-set-fw-dnsВключает перенаправление DNS и встроенный DNS proxy; -dns-upstream задаёт DNS-сервер.
-dns-listenОтдельный DNS-вход, например 192.168.2.12:53, для явно направленных к серверу запросов. Принимает источники из -client; используется вместо -set-fw-dns. Upstream задаётся через -dns-upstream.
-block-quicСовместимый с прежней конфигурацией вариант -quic-mode block; несовместим с явно выбранным relay или passthrough.

Перед включением -set-fw настройте шлюз и явно задайте -client для своей сети: этот режим изменяет системные правила маршрутизации трафика. Примеры доменов выше служат шаблонами для вашей конфигурации.

unPreSock передаёт TLS-трафик без расшифровки. Для TCP, если SNI недоступен, модуль пытается найти домен по ранее наблюдавшемуся DNS-ответу; при отсутствии соответствия выбирает безопасный путь через прокси и передаёт ему исходный IP назначения. Это не гарантирует точную фильтрацию доменов на общих CDN-адресах.

07 / HTTP/3 для устройств за шлюзом

Прозрачная передача QUIC

В режиме relay unPreSock принимает IPv4 UDP 443 через Linux TPROXY, передаёт целые датаграммы в SOCKS5 UDP ASSOCIATE и возвращает ответы с исходным IP и портом сервера. TLS остаётся между клиентом и сайтом. Для этого пути не требуется HTTP/3 listener unProxy.

Параметры QUIC в unPreSock
ПараметрНазначение
-quic-modepassthrough по умолчанию оставляет QUIC внешней маршрутизации; block отклоняет выбранный UDP 443 через ICMP, чтобы клиент мог сразу перейти на TCP; relay передаёт его через SOCKS5.
-quic-socksАдрес SOCKS5-сервера с UDP ASSOCIATE; если пуст, используется -socks. HTTP upstream для TCP задаётся отдельно.
-quic-socks-authSOCKS5 имя и пароль в формате user:password.
-quic-targetsIPv4 адреса/CIDR назначения через запятую. Пустое значение охватывает все внешние IPv4 назначения на UDP 443.
-quic-portЛокальный прозрачный UDP-порт; по умолчанию 10443.
-quic-idle-timeoutТаймаут сессии без трафика, по умолчанию 2m.
-quic-max-sessionsПредел сессий клиент/назначение, по умолчанию 1024.
-quic-cleanupУдаляет принадлежащие модулю runtime-правила QUIC и policy routing после аварийной остановки, затем завершает процесс.

Пример с локальным unProxy

На подготовленном Linux-шлюзе запустите обычный unProxy с HTTP на 127.0.0.1:8585 и SOCKS5 на 127.0.0.1:1080, как в быстром старте. Затем из каталога собранного unPreSock/ выполните:

Linux-шлюз · замените сеть клиентов своей
sudo ./unpresock2 \
  -client 192.168.50.0/24 -set-fw \
  -http-proxy 127.0.0.1:8585 \
  -quic-mode relay -quic-socks 127.0.0.1:1080

Устройства из указанной сети должны уже использовать эту машину как шлюз. Для удалённого unProxy замените адреса, настройте авторизацию SOCKS5 и доступ к управляющему TCP-порту и динамическим UDP relay-портам. При необходимости ограничьте назначения через -quic-targets. Ошибка SOCKS5 завершает сессию без прямого UDP-обхода.

Нужны root, поддержка TPROXY в ядре, ip и iptables. Правила QUIC действуют только во время работы процесса и удаляются при штатной остановке. Режимы relay/block несовместимы с -firewall-permanent и -drop-privileges-to; relay также несовместим с -direct. Без -set-fw правила захвата настраивает администратор отдельно.

Отбор по доменам относится к TCP. -host-redirect-list, -host-redirect-file и DNS/SNI fallback не применяются к QUIC. Relay выбирает трафик по IP/CIDR и не расшифровывает QUIC ClientHello или ECH. Автоматический захват IPv6 и UDP-портов, отличных от 443, не реализован.

После SIGKILL или аварии выполните sudo ./unpresock2 -quic-cleanup перед повторным запуском. Эта команда очищает только правила модуля. Старые правила DROP от прежнего -block-quic, правила firewalld и сторонние ограничения не удаляются автоматически: устраните конфликт вручную по сообщению запуска.

В управляемом режиме QUIC файл .EXIT запрашивает штатную остановку через SIGTERM с очисткой правил. Автоматическая замена из .UPDATE откладывается: остановите процесс, установите обновление и запустите его с прежними параметрами. Предупреждение выводится один раз для неизменившегося файла обновления.

Проверка реализации

Из корня исходников можно запустить локальные Go-тесты и отдельный сетевой сценарий:

Тесты · из корня репозитория
(cd unProxy && go test -race ./...)
(cd unPreSock && go test -race ./...)
bash tests/http3-netns.sh

Сетевой сценарий требует доступных Linux user/network namespaces, unshare, ip, iptables, mount и Python 3. Он создаёт изолированную сеть для проверки HTTP/3 через unPreSock и unProxy, TCP и очистки правил. Это проверка протокольного пути, а не совместимости всех браузеров или публичных видеосервисов.

08 / Наблюдение

Состояние и маршруты

У запущенного unProxy откройте 127.0.0.1:8585/monitor/, подставив свой адрес HTTP-входа при необходимости. Это рабочая страница, встроенная в бинарник; она обновляет снимок каждые 5 секунд и позволяет приостановить обновление.

В плотной таблице видны источник, назначение, известное имя хоста, протокол, маршрут и состояние подключения. Фильтры разделяют перенаправленные, прямые и ещё ожидающие решения соединения. После закрытия прямого подключения его адрес остаётся в отчёте: с числом попыток, ошибками и временем последнего обращения.

Подключить данные шлюза

Добавьте к своей существующей команде запуска unPreSock параметр -monitor-listen 127.0.0.1:8586. Затем добавьте к переменным окружения unProxy адрес монитора шлюза:

Bash · дополнение к настройкам unProxy
export UNPROXY_GATEWAY_MONITOR_URL=http://127.0.0.1:8586
./unproxy

На странице выберите unPreSock, чтобы увидеть настройки перехвата, адреса клиентов, назначения и доменные правила. Отдельная панель шлюза доступна по http://127.0.0.1:8586/monitor/. При размещении компонентов на разных машинах используйте доступный адрес и ключ доступа.

Для работы сервера как DNS включите, например, -dns-listen 192.168.2.12:53 -dns-upstream 192.168.2.1:53. DNS-клиенты появятся среди исходных хостов, а запросы и ответы — в счётчиках DNS. Одна настройка DNS на клиенте не направляет веб-трафик через прокси: для этого нужен также шлюз через unPreSock или явная настройка прокси.

Нажмите на счётчик «Исходные хосты», «Назначения proxy» или «Назначения direct», чтобы открыть соответствующий список имён и IP без портов. В нём есть поиск, страницы по 100 адресов и кнопка «Обновить список»; повторный клик по счётчику сворачивает список. Учитываются наблюдения с запуска выбранного компонента, включая завершённые подключения, максимум 16 384 уникальных хоста в каждой группе. Знак «+» сообщает о неполном учёте из-за защитного предела. Списки загружаются по запросу; после перезапуска сбор начинается заново.

Раздел фактического состояния содержит снимок iptables/ip6tables, маршрутов, firewalld и nftables, включая сторонние правила. Он читается по запросу и кэшируется на 30 секунд. Конфигурация процесса и правила ядра показаны отдельно: внешние правила, порядок цепочек или отсутствие прав могут менять результат.

Доступ и границы наблюдения

Параметры мониторинга
ПараметрНазначение
UNPROXY_MONITOR_SECRETКлюч страницы unProxy. Если не задан, используется UNPROXY_SECRET. Без обоих ключей API доступен только через loopback.
-monitor-listenВключает отдельный HTTP-вход мониторинга unPreSock; по умолчанию выключен.
-host-redirect-fileВключает сохраняемые переключатели «через прокси / direct» на отдельной странице unPreSock.
UNPRESOCK_MONITOR_SECRETКлюч шлюза; обязателен для его внешнего адреса.
UNPROXY_GATEWAY_MONITOR_URLАдрес монитора unPreSock для общей страницы, например http://127.0.0.1:8586.
UNPROXY_GATEWAY_MONITOR_SECRETКлюч шлюза, который unProxy использует при чтении его данных.

Ключ вводится на странице и хранится в sessionStorage этой вкладки: он переживает перезагрузку страницы. Кнопка «Выйти» удаляет ключ; браузер также удаляет его при закрытии вкладки. API /monitor/api/state принимает ключ в Authorization: Bearer … или X-Monitor-Secret. Для удалённого доступа используйте защищённый транспорт, например SSH-туннель или HTTPS reverse proxy.

Изменение маршрута доступно только на отдельной панели unPreSock, всегда требует ключ и атомарно записывает правило в -host-redirect-file; текущие соединения не переключаются. В режиме -quic-mode block с -set-fw в строке QUIC доступна кнопка временной разблокировки и повторной блокировки. После перезапуска действует режим из командной строки.

Если пользователи прокси не должны видеть мониторинг, задайте ключи обеих панелей: доступ к localhost через прокси тоже приходит с loopback-адреса.

Что означает «напрямую». unPreSock действительно выбрал прямое подключение вместо upstream. Все запросы к unProxy уже используют прокси, даже когда сам unProxy выходит к сайту напрямую. Компоненты показаны отдельно, их показатели не складываются.

Сохраняются последние 16 384 сочетаний источника и прямого назначения. При заполнении удаляется запись с самым давним последним обращением; после перезапуска история начинается заново. Трафик вне правил перехвата, QUIC passthrough и заблокированные пакеты в этот отчёт не попадают. SOCKS5 UDP отображается как ассоциация с возможными несколькими назначениями.

Счётчики объёма работают прежним способом, иногда обновляясь после завершения передачи. Точная скорость и объём по каждому протоколу не вычисляются; в циклах передачи новый подсчёт не добавлен. Для HTTP строка обозначает активный запрос, для CONNECT — туннель, для UDP — ассоциацию или поток шлюза.

09 / Перед расширением схемы

Границы возможностей

  • Локальный запуск — начальная конфигурация. HTTP listener не запрещает внешний адрес без авторизации автоматически. Доступ с других компьютеров требует отдельно настроить доступ к порту и подходящую авторизацию.
  • CONNECT и шифрование — разные уровни. HTTPS сохраняет TLS-соединение клиента с конечным сервером. Обычный HTTP listener и SOCKS5 username/password сами по себе не шифруют соединение с прокси.
  • UDP зависит от пути. SOCKS5 UDP работает напрямую или через SOCKS5 upstream, но не через HTTP upstream. Это не обещание совместимости с каждым приложением или каждой сетью.
  • HTTP/3 требует подходящего пути. Native listener требует сертификат и совместимый клиент; прозрачный QUIC relay ограничен IPv4 UDP 443. Туннелирование не раскрывает ECH и не делает скрытый SNI видимым.
  • Mux и TUNNEL — расширенные экспериментальные режимы. В коде есть hub/slave-схема с MODE, MODE_LABEL, LINK_ADDR и отдельная подсистема TUNNEL_*. Их покрытие протоколов отличается от обычного прокси; не предполагается, что любой трафик автоматически проходит через туннель.

Mux hub запускается только при явно заданном LINK_ADDR или -link. Параметры MUX_SECRET, MUX_TLS и MUX_AES_KEY относятся именно к mux-каналу и не меняют HTTP listener из быстрого старта.

Вернуться к быстрому старту