Обзор модулей

Что такое модули, где они работают, как их добавлять и включать и что нужно знать перед включением.

Модуль — файл стороннего автора, который внутри VPN-туннеля меняет запросы и ответы выбранных сайтов или блокирует домены. Модули есть только на iPhone. В Letakof нет готовых модулей и каталога: вы добавляете модуль сами, а новый модуль работает без обновления приложения.

Модули — продвинутая функция. Скрипт модуля видит заголовки, cookie и тела запросов тех хостов, которые он обрабатывает. Добавляйте только модули, код которых вы прочитали. Ссылка и SHA-256 не доказывают, кто написал модуль.

Формат собственный, не совместимый с модулями Shadowrocket, Surge и Loon.

Где

Настройки → Модули (справа показано число включённых). На экране такие группы:

Группа Что это
Установленные Ваши модули: значок, имя, статус и переключатель. Нажмите, чтобы открыть карточку. Свайп влево удаляет выключенный модуль.
Черновики Модули, сохранённые из редактора.
Добавить По ссылке, Из файла и Создать вручную.
Сертификат Сертификат модулей; см. Сертификат и MITM.
Не расшифровывать Исключённые вами хосты, с кнопкой Вернуть.

Добавление модуля

Любой способ заканчивается предпросмотром Новый модуль, и пока вы не подтвердите, ничего не выполняется.

Способ Подробности
Ссылка letakof://module/add?url=<https-адрес> Необязательный sha256=<64 hex> фиксирует содержимое. Другие или повторяющиеся параметры отвергаются.
По ссылке Адрес https:// и необязательный SHA-256. Ссылка на страницу файла GitHub заменяется прямой.
Из файла Любой файл до 256 КиБ.
Создать вручную Редактор с вкладками Манифест, по одной на каждый скрипт, и Проверка. Можно сохранить черновик, установить или экспортировать манифест.
Старый .module / .sgmodule Распознаётся по файлу, который не начинается с {. Переносятся только правила DOMAIN и DOMAIN-SUFFIX с REJECT и список хостов [MITM]. Всё остальное перечисляется как не перенесённое.

Ссылки должны быть https, без логина, без локальных и частных адресов; редиректы проверяются заново (до 5); веб-страница вместо файла отклоняется. Сам файл описан в Структуре модуля.

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

Пример: стартовый модуль

Нажмите Добавить → Создать вручную, и редактор откроется с готовым текстом. Он нейтральный: никаких реальных сервисов, только условный хост. Вот манифест на вкладке Манифест:

{
  "schemaVersion": 1,
  "id": "my.module",
  "name": "My module",
  "version": "1.0.0",
  "author": "",
  "parameters": [
    { "id": "value", "title": "Value", "type": "string", "default": "one", "enum": ["one", "two"] }
  ],
  "mitmHosts": ["api.example.org"],
  "httpRules": [
    { "id": "main", "phase": "request", "host": "api.example.org", "path": { "prefix": "/" },
      "action": { "type": "script", "script": "main" } }
  ],
  "scripts": [ { "id": "main" } ]
}

А это код на вкладке скрипта main:

// transform(event, context) → patch | null. null — оставить обмен без изменений.
function transform(event, context) {
  return null;
}
Часть Что означает
schemaVersion Версия формата. Всегда 1.
id Уникальное имя модуля и имя его хранилища. Для своего модуля измените.
name, version, author Что показывают список и карточка. author необязателен и здесь пуст.
parameters Одна настройка, value: строка, по умолчанию one, с вариантами one и two. В карточке она показана как выбор, а скрипт читает её как context.parameters.value.
mitmHosts Хосты, HTTPS-трафик которых расшифровывается. api.example.org — заглушка: укажите нужный хост. Именно эта часть требует сертификат.
httpRules Одно правило с именем main. phase: request — до отправки запроса. host должен входить в mitmHosts. path.prefix: "/" подходит для любого пути. action запускает скрипт с id main.
scripts Только называет скрипт. Его код лежит на отдельной вкладке скрипта в редакторе.
transform Вызывается для каждого обмена, который подошёл правилу. Возвращает null, поэтому стартовый модуль ничего не меняет: польза появится, когда вы вернёте патч.

Замените хост и путь, напишите патч в transform и проверьте результат на вкладке Проверка перед Установить…. Все поля и формат патча — в Структуре модуля.

Управление

  • Переключатель в списке или Включён в карточке. Модуль работает, только пока VPN подключён, в том числе в режиме «Напрямую». Изменения применяются сразу, если VPN включён.
  • Несколько модулей применяются в порядке установки; в интерфейсе их нельзя переставить. Для правил доменов решает первый модуль с совпадением. Для HTTP-правил побеждает первое подходящее правило фазы, остальные пропускаются. Движок принимает до 32 включённых модулей.
  • В карточке модуля показан статус: Выключен, Ждёт подключения VPN, Применяется, Нужен сертификат, Нужно доверие сертификату, Применён, Ошибка, TLS несовместим, Лимит ресурсов, Имя узла недоступно; а также Расшифровываемые хосты, счётчики и Диагностика хостов.
  • Удаление убирает модуль, его параметры и данные.

Лимиты

Что Лимит
Манифест, скрипт, заголовки 256 КиБ, 256 КиБ, 64 КиБ
HTTP-правила, хосты 256 правил; по 64 mitmHosts и excludedHosts
Выполнение скрипта 100 мс, куча 8 МиБ, новый runtime на каждый вызов
Хранилище скрипта 64 КиБ на модуль, 1 МиБ суммарно
Тела 1 МиБ по сети, 2 МиБ после распаковки

Любая ошибка в скрипте (исключение, время, память, неверный патч) означает, что приложение получит исходный обмен без изменений. Обрабатывается только TCP на портах 443 и 80; QUIC отклоняется локально, чтобы приложение перешло на TCP; WebSocket, видео, аудио, потоки событий и gRPC проходят без изменений.

Нашли ошибку? Создайте обращение на GitHub.