Skip to main content

Инструмент доступа к открытому интернету под российскими операторскими белыми списками (мобильные сети).

Project description

fresta

Свет проходит даже сквозь щель.

CI License: MIT Python 3.8+ stdlib-only

⚠️ Badges: CI-бейдж заработает после первого push в main (workflow .github/workflows/tests.yml).

Инструмент доступа к открытому интернету в условиях операторских белых списков (РФ, мобильные сети). Идея: найти и переиспользовать «щель» — инфраструктуру, чьи IP оператор обязан пропускать, и пустить через неё свой трафик.

Название — fresta (порт. «щель в ставнях, через которую пробивается свет»).

Как работает белый список (против чего мы)

Двухуровневая фильтрация, по умолчанию drop-all:

  • L3 — CIDR-фильтр по IP. Пакет не к разрешённой подсети дропается ещё до DPI.
  • L7 — DPI смотрит SNI в TLS ClientHello; домен в чёрном списке → RST.

Маскировка протокола (Reality, обфускация) против L3 бесполезна: блокировка идёт по адресу назначения, до того как протокол себя проявит. Работает только транспорт, физически идущий на whitelisted-IP. В РФ это прежде всего Yandex Cloud (≈каждый пятый IP в списке), а также VK, Selectel, Timeweb, Ростелеком.

Структура

Код в scripts/ разложен по тематическим подпапкам (recon / harvest / deploy / relay / tests). Подробная карта — scripts/README.md. Кратко:

fresta/
├── README.md                   ← этот файл (ты здесь)
├── pyproject.toml              ← метаданные Python-пакета + entry points
├── Makefile                    ← make test / lint / deploy / harvest-all / …
├── LICENSE                     ← MIT
├── CHANGELOG.md                ← история версий (Keep a Changelog)
├── CONTRIBUTING.md             ← гайд для контрибьюторов
├── schemas/                    ← JSON Schema для server.json / client.json
│   ├── server.schema.json      Xray inbound
│   └── client.schema.json      sing-box outbound
├── fresta/                     ← Python-пакет (после `pip install fresta`)
│   ├── __init__.py             `__version__`, `__summary__`
│   └── py.typed                маркер PEP 561
├── scripts/                    ← код (см. scripts/README.md)
│   ├── recon/                  Фаза 0: разведка (GO/NO-GO по whitelist-доменам)
│   ├── harvest/                harvest'ы: zieng2/wl (SNI) + openlibrecommunity/twl (IP)
│   ├── deploy/                 Метод 1: VLESS+Reality — генер + деплой + check_health / bench / rotate
│   ├── relay/                  Метод 2: Yandex Cloud relay (handler + клиент)
│   ├── check/                  sanity-чек зависимостей (ssh, openssl, xray, …)
│   ├── tests/                  smoke-тесты (60+ кейсов) + run_tests.{sh,ps1} + probe_reality.py
│   └── README.md               ← карта scripts/
├── docs/                       ← документация
│   ├── README.md               ← карта docs/
│   ├── knowledge.md            ← прочитать первым (контекст-хэндофф)
│   ├── specification.md        идея, threat model, архитектура
│   ├── ROADMAP.md              чек-лист: что гонять где
│   ├── PUBLISH.md              гайд для maintainer'а: релиз на PyPI (OIDC, tag → push → auto-publish)
│   └── manuals/                пошаговые гайды по методу (карта — manuals/README.md)
│       ├── vless-vps/         Метод 1: VLESS+Reality на VPS
│       │   ├── deploy.md      quickstart + troubleshooting
│       │   └── reality-params.md
│       ├── ycloud-function/   Метод 2: YC Functions relay
│       │   └── deploy.md
│       └── recon/             Phase 0: разведка
│           └── twl-harvest.md
├── .github/                    ← CI / Issue templates
│   ├── workflows/
│   │   ├── tests.yml           smoke-тесты на push/PR
│   │   └── publish.yml         авто-публикация wheel+sdist на PyPI по тегу v*.*.*
│   ├── dependabot.yml          авто-PR для dev-зависимостей и Actions
│   └── ISSUE_TEMPLATE/         bug_report / feature_request
├── .vibe/                      ← конфиг VibeIDE (rules, skills, prompts, workflows) — см. .vibe/README.md
└── …                          (`.editorconfig`, `.gitattributes`, `.gitignore`, `.pre-commit-config.yaml`)

Компоненты

Файл Что Фаза
docs/specification.md Идея, threat model, архитектура, роадмап
docs/ROADMAP.md Чек-лист: что сделано и что погонять где
docs/knowledge.md Полный контекст-хэндофф проекта (читать первым)
docs/PUBLISH.md Гайд для maintainer'а: релиз на PyPI (OIDC trusted publishing, tag→push, FAQ)
schemas/server.schema.json JSON Schema для Xray server.json (inbounds/realitySettings)
schemas/client.schema.json JSON Schema для sing-box client.json (vless+reality+utls)
scripts/harvest/reports/harvest-report.md Снимок SNI/провайдеров из живой подписки zieng2/wl
docs/manuals/vless-vps/deploy.md vless-vps (Метод 1): quickstart + troubleshooting (сценарии A/B) 2
docs/manuals/vless-vps/reality-params.md Reality-параметры + генератор + ручной деплой 2
docs/manuals/ycloud-function/deploy.md ycloud-function (Метод 2): YC Functions relay + клиент 2
docs/manuals/recon/twl-harvest.md harvest whitelisted-IP (twl) 0
scripts/recon/fresta_recon.py Recon: за каким провайдером сидят whitelisted-домены → GO/NO-GO 0
scripts/recon/whitelist.txt Домены белого списка Минцифры (реконструкция по сервисам) 0
scripts/recon/whitelist.sample.txt Пример формата ввода 0
scripts/harvest/sni_candidates.txt Whitelisted-SNI для своего Reality-конфига (harvest) 0
scripts/harvest/harvest_subscription.py Выжимает SNI + провайдеров из VLESS-подписки 0
scripts/harvest/harvest_twl.py harvest whitelisted-IP из openlibrecommunity/twl → ips.txt / subnets.txt 0
scripts/harvest/twl-data/ Выход harvest'а: ips.txt (≈44k IP), subnets.txt (41 /24), report.md, meta.json 0
scripts/deploy/fresta_gen_vless.py Генератор Xray/sing-box/vless:// для VLESS+Reality 2
scripts/deploy/deploy_vps.sh Серверный деплой Метода 1: ставит Xray, кладёт конфиг, открывает порт, рестарт 2
scripts/deploy/quickstart.sh Локальный одноступенчатый деплой: генер → scp → deploy → scp обратно 2
scripts/deploy/check_health.py Health-check деплоя: SOCKS5 alive? exit-IP правильный? latency p50/p95 2
scripts/deploy/bench.py Мини-бенчмарк (latency × 10 + 1 МБ throughput) туннеля 2
scripts/deploy/rotate_keys.sh Ротация UUID/X25519/shortId на сервере без переустановки Xray 2
scripts/deploy/validate_config.py Stdlib-валидатор server.json / client.json по schemas/*.json 2
scripts/deploy/diff_configs.py Diff двух server/client.json (UUID/ключи маскируются); --summary-only, --json 2
scripts/deploy/configs/default/ Пример сгенерированного набора (демо) 2
scripts/deploy/configs/remote-fresta/ PoC-набор для fresta.ru (end-to-end пройден) 2
scripts/check/sanity.py Pre-flight check зависимостей: python, openssl, ssh, xray, sing-box, yc, …
scripts/relay/yc_function/handler.py Relay-функция на Yandex Cloud (fetch-on-behalf) 2
scripts/relay/fresta_client.py Локальный клиент к relay: CLI + HTTP-proxy 2
scripts/tests/test_*.py Smoke-тесты (60+ кейсов), ловят регрессии
scripts/tests/probe_reality.py TLS-probe ко всем whitelisted-SNI через sing-box SOCKS5
scripts/tests/run_tests.sh / .ps1 Прогон всех тестов разом

Статус

  • ✅ Имя, концепция, спека.
  • ✅ Фаза 0: recon-скрипт (цель — российские провайдеры, Yandex Cloud во главе) + список доменов. Оффлайн-логика протестирована.
  • ✅ Метод 2: минимальный serverless fetch-relay. Плумбинг протестирован end-to-end.
  • ✅ Фаза 2 (Метод 1): генератор VLESS+Reality конфигов + deploy-скрипты (deploy_vps.sh + quickstart.sh).
  • ✅ Фаза 2 (Метод 1): PoC end-to-end на fresta.ru — Xray v26.3.27 + sing-box 1.13.13, curl --proxy socks5h https://api.github.com/zen = 200 OK, exit-IP сменился на 89.253.255.108.
  • ⬜ Фаза 2: деплой и прогон на whitelisted-VPS под мобильным каналом с белым списком.
  • ⬜ Фаза 3: ротация фронтов (несколько VPS × несколько SNI × автоперебор).
  • ✅ Подключить реальные whitelisted-IP: scripts/harvest/harvest_twl.py (43k+ IP из openlibrecommunity/twl).
  • ✅ JSON Schema для конфигов (schemas/*.schema.json) + stdlib-валидатор (validate_config.py).
  • ✅ Pre-commit хуки (.pre-commit-config.yaml): ruff + schema-валидация server/client.json.
  • ⬜ Подключить реальные whitelisted-SNI под своего оператора (выжимка из twl по доменам — в планах).
  • ✅ Пакет на PyPI: pip install fresta → 7 entry points в $PATH (см. ниже).

Установка

Два способа — выбирай по ситуации.

Из исходного кода (для контрибьюторов)

# Клонировать репозиторий
git clone https://github.com/VibeIDEProjects/Fresta.git
cd Fresta

# Создать виртуальное окружение (опционально, но рекомендую)
python -m venv .venv
source .venv/bin/activate          # Linux / macOS / WSL / Git Bash
.venv\Scripts\activate             # Windows PowerShell / cmd

# Поставить в editable-режиме + dev-стек (ruff/mypy/pytest/build/twine)
pip install -e ".[dev]"

# Проверить, что всё на месте
make sanity
make test

Все скрипты доступны и как python3 scripts/<path>.py, и как точки входа (fresta-recon, fresta-validate и т.д. — см. ниже). Bash-скрипты (quickstart.sh, deploy_vps.sh, rotate_keys.sh) тоже лежат в репо и работают через bash <path>.

Через pip (для пользователей)

# Установка
pip install fresta

# Обновление
pip install --upgrade fresta

# Установить вспомогательные утилиты, если планируешь деплой (Xray, sing-box)
# Linux:    bash <(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)  # Xray
#           см. https://sing-box.app/installation (один пакет по дистрибутиву)
# Windows:  winget install XTLS.Xray-core
#           winget install SagerNet.sing-box

После установки в $PATH появляются 7 CLI-команд (это [project.scripts] из pyproject.toml):

Команда Эквивалент в исходниках Назначение
fresta-recon python3 scripts/recon/fresta_recon.py Phase 0: GO/NO-GO по whitelisted-доменам
fresta-harvest-sni python3 scripts/harvest/harvest_subscription.py выжимка SNI из VLESS-подписки
fresta-harvest-twl python3 scripts/harvest/harvest_twl.py harvest whitelisted-IP из openlibrecommunity/twl
fresta-gen-vless python3 scripts/deploy/fresta_gen_vless.py генератор server.json / client.json / vless://
fresta-validate python3 scripts/deploy/validate_config.py stdlib-валидатор server/client.json по schemas
fresta-sanity python3 scripts/check/sanity.py pre-flight check зависимостей (ssh/openssl/xray/…)
fresta-diff python3 scripts/deploy/diff_configs.py diff двух server/client.json

Bash-скрипты quickstart.sh / deploy_vps.sh / rotate_keys.shне входят в pip-пакет (им нужны bash + ssh + scp на машине, в Windows-экосистеме это бессмысленно). Бери их из исходников: git clone … && bash scripts/deploy/quickstart.sh ….

💡 PATH на Windows: после pip install команды могут не находиться, если папка Scripts не в PATH. Добавь вручную один раз:

# Найти путь
python -m site --user-site   # обычно %APPDATA%\Python\Python3X\Scripts
# Добавить в PATH (от администратора)
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$env:APPDATA\Python\Python3X\Scripts", "User")

На Linux / macOS: обычно ~/.local/bin уже в PATH для pip-user, но если нет:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc

Проверить, что всё работает:

fresta-validate --help    # должен вывести help без ModuleNotFoundError
fresta-sanity --version   # должна вывести "fresta-sanity (fresta 0.2.0)"

Использование

Phase 0 — разведка (GO/NO-GO)

Под мобильным каналом с белым списком (раздать интернет с телефона на ноут):

# Из исходников
python3 scripts/recon/fresta_recon.py scripts/recon/whitelist.txt --probe

# Из pip-пакета (если whitelist.txt нет под рукой — взять из клона)
git clone --depth 1 https://github.com/VibeIDEProjects/Fresta.git
fresta-recon Fresta/scripts/recon/whitelist.txt --probe

Вердикт (GO / NO-GO / частично) + таблица по доменам. Детали — в docs/specification.md §6.

Harvest whitelisted-SNI (для Reality-конфига)

# Из исходников
python3 scripts/harvest/harvest_subscription.py <подписка-vless> -o sni.txt
# SNI попадают в sni.txt — этот файл можно скормить fresta-gen-vless

# Из pip-пакета
fresta-harvest-sni <подписка-vless> -o sni.txt

Harvest whitelisted-IP (для выбора VPS-провайдера)

# Из исходников
python3 scripts/harvest/harvest_twl.py --providers yandex --min-subnet-density 0.7

# Из pip-пакета
fresta-harvest-twl --providers yandex --min-subnet-density 0.7

Подробности — docs/manuals/recon/twl-harvest.md. Выход: ips.txt (43k+ IP, 498 ASN), subnets.txt (41 /24 с плотностью ≥ 50%), report.md + meta.json.

Phase 2 — Метод 1 (VLESS+Reality на VPS)

Тут только из исходников (bash + ssh + scp):

# Деплой одной командой — генер + scp + server-side install + scp обратно
git clone --depth 1 https://github.com/VibeIDEProjects/Fresta.git
cd Fresta
bash scripts/deploy/quickstart.sh --ssh user@your-vps.example.com
# Готово: client.json / links.txt лежат в configs/<host>-<date>/

# Сгенерировать только конфиги (без деплоя — для теста/эксперимента)
fresta-gen-vless --exit-ip ВАШ.IP.ЛИТЕРАЛ --out configs/my-vps
# → server.json + client.json + links.txt в configs/my-vps/

# Health-check / бенчмарк / ротация — из исходников
python3 scripts/deploy/check_health.py configs/my-vps
python3 scripts/deploy/bench.py
bash scripts/deploy/rotate_keys.sh user@your-vps.example.com

Подробности, опции, troubleshooting — docs/manuals/vless-vps/deploy.md и docs/manuals/vless-vps/reality-params.md.

Phase 2 — Метод 2 (Yandex Cloud Functions relay)

# Из исходников
python3 scripts/relay/fresta_client.py --check       # проверить, что канал жив
python3 scripts/relay/fresta_client.py <url>         # fetch через relay

fresta_client.py не зарегистрирован как entry point (нужны токен + URL, зависит от конфига функции) — используй его напрямую из клонированного репо.

Подробности — docs/manuals/ycloud-function/deploy.md.

Pre-flight / валидация / diff

# Sanity-check зависимостей
fresta-sanity                       # все
fresta-sanity --required-only       # только обязательные (python, ssh, scp, openssl)
fresta-sanity --json                # machine-readable для CI

# Валидация server.json / client.json по schemas/*.schema.json
fresta-validate configs/my-vps/server.json
fresta-validate configs/my-vps/client.json
fresta-validate --strict configs/my-vps/   # весь каталог

# Diff двух наборов (после rotate_keys — что изменилось)
fresta-diff configs/my-vps server.json configs/my-vps-new server.json --summary-only
# UUID/ключи маскируются по умолчанию; --no-redact если нужны реальные

Быстрый старт (TL;DR)

Один-в-один сценарий "есть VPS, деплой за 30 секунд":

# Из исходников
bash scripts/deploy/quickstart.sh --ssh user@your-vps.example.com
# Подробности, опции, troubleshooting — docs/manuals/vless-vps/deploy.md

Нет whitelisted-VPS под рукой? Используй любой доступный сервер — quickstart такой же, архитектура работает, но под белым списком оператора пройдёт только когда IP-адрес будет в whitelisted-подсети. PoC на fresta.ru: 89.253.255.108 — end-to-end пройден, см. scripts/deploy/configs/remote-fresta/ и docs/ROADMAP.md.

Остальное (по компонентам) — см. секцию «Использование» выше (с разбиением «из исходников» vs «из pip-пакета»).

Импорт client.json в sing-box

# Linux/macOS/WSL
mkdir -p ~/.config/sing-box
cp configs/<host>-<date>/client.json ~/.config/sing-box/config.json
sing-box check -c ~/.config/sing-box/config.json
sing-box run -c ~/.config/sing-box/config.json &
curl --proxy socks5h://127.0.0.1:1080 https://api.github.com/zen   # 200 OK

На Windows: используй Git Bash или WSL для bash-скриптов; для sing-box есть winget install SagerNet.sing-box.

Методы обхода (от простого к сложному)

  1. VLESS + Reality на РФ-VPS — основной, стабильный. IP в whitelist + whitelisted-SNI + fp=chrome.
  2. Yandex Cloud Functions (этот репо, Метод 2) — serverless fetch-relay, бесплатно, но не туннель.
  3. API Gateway + WebSocket → VPS — настоящий туннель; вектор уже начали банить.
  4. olcRTC / xDNS — экспериментальные (видеозвонки, DNS); см. openlibrecommunity.

Подробный разбор уровней фильтрации и методов — в docs/specification.md и статье zarazaex на Хабре (habr.com/ru/articles/1027276).

Зависимости

Рантайм — stdlib-only. Никаких pip install для пользователя; только Python 3.8+ (и openssl для X25519, ssh/scp для деплоя). Это сознательное решение: минимум поверхности атаки, нулевая стоимость входа, одинаково работает на любом VPS.

Dev-стек (опционально, для контрибьюторов): ruff + mypy + pytest — поднимается одной командой:

pip install -e .[dev]
make lint test

См. также секцию «Установка» выше — там подробнее про pip install fresta и CLI-команды.

Для контрибьюторов

  • Читай CONTRIBUTING.md — там workflow, правила приёма PR, что НЕ принимаем.
  • История изменений — CHANGELOG.md.
  • Лицензия — LICENSE (MIT).
  • Релиз на PyPI (для maintainer'а) — docs/PUBLISH.md (OIDC, tag→push, FAQ).
  • Issues — шаблоны bug report и feature request.
  • IDE-конфиг для AI-агентов (VibeIDE) — .vibe/README.md (rules, skills, prompts).

Рамка

Обход операторских ограничений и проксирование через чужой serverless — серая зона и нарушение ToS провайдеров (функции/серверы сносят, идёт арм-рейс). Инструмент — для доступа к открытому интернету; оценка рисков и решение на пользователе.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fresta-0.2.1.tar.gz (73.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fresta-0.2.1-py3-none-any.whl (79.5 kB view details)

Uploaded Python 3

File details

Details for the file fresta-0.2.1.tar.gz.

File metadata

  • Download URL: fresta-0.2.1.tar.gz
  • Upload date:
  • Size: 73.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fresta-0.2.1.tar.gz
Algorithm Hash digest
SHA256 70ccb3fd3954252c48a963c482ebe1a48ed2f77d47184333b7b4f911403d3c51
MD5 62e2480b5b142e5a14346a5012fe13a7
BLAKE2b-256 9bd22b535f87d66cf219cb505a28cc9977f95ad5d86ae1653fa6c857deba1c2c

See more details on using hashes here.

File details

Details for the file fresta-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: fresta-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 79.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fresta-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 50a85283c36ac8ad54f74a3a0046802b68311de519ab94aa83a8ee3a0382d1ef
MD5 0a520cbf655c19138df881b952bfdea2
BLAKE2b-256 ef90a31d03719be68924f3e099347faf950915ac232f2d825deb9b8ca427025e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page