Skip to content

[BUG] user_domains_text не маршрутизируется через VPN после некорректной остановки podkop #356

@asdasd-dev

Description

@asdasd-dev

📝 Описание проблемы

После перезапуска podkop без предварительного чистого stop (например, при краше процесса или OOM-kill) пользовательские домены (user_domains_text) перестают маршрутизироваться через VPN — трафик идёт напрямую. Community lists при этом работают нормально.

🔍 Root cause

Проблема в функции prepare_source_ruleset (/usr/bin/podkop, ~строка 933):

create_source_rule_set "$ruleset_filepath"
case $? in
0)
    config=$(sing_box_cm_add_local_ruleset "$config" "$ruleset_tag" "source" "$ruleset_filepath")
    config=$(sing_box_cm_patch_route_rule "$config" "$route_rule_tag" "rule_set" "$ruleset_tag")
    config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
    ;;
3) log "Source rule set $ruleset_filepath already exists, skipping." "debug" ;;
esac

Когда podkop завершается некорректно (crash, OOM, kill без stop), файл /tmp/sing-box/rulesets/main-user-domains-ruleset.json остаётся в /tmp/.

При следующем старте podkop генерирует sing-box config с нуля, но create_source_rule_set возвращает 3 (файл уже существует) → вызов sing_box_cm_add_local_ruleset и patch_route_rule пропускается → local ruleset не добавляется в конфиг.

В результате /etc/sing-box/config.json не содержит ссылки на main-user-domains-ruleset, и sing-box роутит user domains напрямую (через final: direct-out).

Важно: dscacheutil может возвращать FakeIP из кэша cache.db — это создаёт иллюзию что DNS работает, хотя routing rule отсутствует.

✅ Ожидаемое поведение

Независимо от того, существует ли файл рулсета на диске, при генерации нового sing-box config local ruleset должен быть добавлен в config. Файл создаётся один раз, но ссылка на него должна добавляться при каждой генерации конфига.

💡 Предлагаемый фикс

В prepare_source_ruleset, case 3 должен также добавлять ruleset в конфиг (не пересоздавая файл):

create_source_rule_set "$ruleset_filepath"
case $? in
0|3)
    config=$(sing_box_cm_add_local_ruleset "$config" "$ruleset_tag" "source" "$ruleset_filepath")
    config=$(sing_box_cm_patch_route_rule "$config" "$route_rule_tag" "rule_set" "$ruleset_tag")
    case "$type" in
    domains)
        config=$(sing_box_cm_patch_dns_route_rule "$config" "$SB_FAKEIP_DNS_RULE_TAG" "rule_set" "$ruleset_tag")
        ;;
    esac
    ;;
esac

Либо: очищать $TMP_RULESET_FOLDER в start_service перед запуском podkop (но это дольше при старте из-за повторного парсинга доменов).

🔧 Временный workaround

В /etc/init.d/podkop, в функцию start_service добавить строку перед procd_open_instance:

rm -f /tmp/sing-box/rulesets/*.json

🔁 Шаги для воспроизведения

  1. Настроить user_domains_text с несколькими доменами, убедиться что всё работает
  2. Убить podkop/sing-box без чистого stop: kill -9 $(pgrep -f "podkop start") или дождаться OOM
  3. Запустить /etc/init.d/podkop start
  4. Проверить /etc/sing-box/config.jsonmain-user-domains-ruleset отсутствует в rule_set
  5. Убедиться что трафик на user domains идёт напрямую

🖥️ Информация о системе

  • OpenWrt версия: RouteRich 24.10.5 (OpenWrt-форк, mediatek/filogic aarch64)
  • Podkop версия: v0.7.10
  • Sing-box версия: 1.12.22
  • Роутер модель: Routerich AX3000

🔗 Связанный issue

Схожая проблема описана в #273 (закрыт без фикса в коде).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions