Обзор модулей
Что такое модули, где они работают, как их добавлять и включать и что нужно знать перед включением.
Модуль — файл стороннего автора, который внутри 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.