- sub-filter
Умный фильтр подписок на прокси-серверы (VLESS, VMess, Trojan, Shadowsocks, Hysteria2).
Программа проверяет каждую ссылку внутри подписки на:
- безопасность (например, блокирует
security=noneв VLESS), - корректность (например, требует
pbkприsecurity=reality), - наличие «запрещённых слов» в названии или адресе сервера на основании гибких правил (вырезать или удалить),
- фильтрация описания серверов по странам, их флагам и национальным названиям.
Результат — чистая, рабочая подписка, готовая к использованию в Clash, Sing-Box, роутерах и других клиентах.
⚠️ Программа не проверяет живучесть прокси. Для этого используйте xray-checker.
✅ Валидация по гибким правилам из rules.yaml и настройкам из badwords.yaml
✅ Фильтрация по одной или нескольким странам (до 20) и плохим словам
✅ Дедупликация ссылок с выбором наиболее полной версии среди одинаковых серверов
✅ Кеширование (по умолчанию 30 минут)
✅ Поддержка CLI-режима с выводом в терминал
Требуется Go 1.21+.
go build -o sub-filter .Проект использует модульную архитектуру с dependency injection:
pkg/config: Загрузка и валидация конфигурации из YAML/JSON/TOML файловpkg/service: Основная бизнес-логика, HTTP handlers, кэширование regexpkg/errors: Типизированные ошибки с кодами и severitypkg/logger: Структурированное логирование на основе slogpkg/cache: Кэширование скомпилированных regex для производительности
Протоколы (VLESS, VMess, etc.) реализованы в отдельных пакетах с общим интерфейсом ProxyLink.
Программа поддерживает два режима работы: HTTP-сервер и CLI (консольный).
Пример конфигурационных файлов
Основной файл config/config.yaml:
# Пути к файлам
sources_file: "./config/sub.txt" # Список URL подписок
rules_file: "./config/rules.yaml" # Правила валидации
bad_words_file: "./config/badwords.yaml" # Запрещенные слова
uagent_file: "./config/uagent.txt" # User-Agent для запросов
# Кэширование
cache_dir: "/tmp/sub-filter-cache" # Директория кэша
cache_ttl: 1800s # Время жизни кэша
# Лимиты
max_country_codes: 20 # Макс кодов стран
max_merge_ids: 10 # Макс подписок для merge
merge_buckets: 256 # Шарды для mergeЗапускается с указанием порта. Подписки фильтруются «на лету» при каждом запросе.
./sub-filter <порт> [cache_ttl] [sources_file] [bad_words_file] [uagent_file] [rules_file]# Минимальный запуск (использует файлы из ./config/)
./sub-filter 8000
# Полный запуск
./sub-filter 8000 1800 ./config/sub.txt ./config/bad.txt ./config/uagent.txt ./config/rules.yaml| Эндпоинт | Описание |
|---|---|
/filter |
Фильтрация одной подписки |
/merge |
Объединение и фильтрация нескольких подписок |
Параметры:
id— номер строки изsources_file(для/filter)ids— номера строк через запятую (для/merge, максимум 20)c— коды стран по ISO 3166-1 alpha-2 через запятую (максимум 20)lim— максимальное количество ссылок в результате (для/filterи/merge)
Примеры:
/filter?id=1— фильтрация первой подписки/filter?id=1&c=DE— фильтрация по Германии/merge?ids=1,2,3&c=US,CA— объединение трёх подписок с фильтрацией по США и Канаде
Обрабатывает все подписки один раз и сохраняет результаты в кеш.
./sub-filter --cli [--stdout] [--config файл.yaml] [--country AD,DE]| Флаг | Описание |
|---|---|
--cli |
Запуск в CLI-режиме |
--stdout |
Вывод результата в терминал |
--config |
Использовать внешний файл конфигурации |
--country |
Фильтрация по странам (например, --country=AR,AE) |
# Обработать все подписки и сохранить в кеш
./sub-filter --cli
# Вывести результат в терминал
./sub-filter --cli --stdout
# Обработать с фильтрацией по странам
./sub-filter --cli --country=NL,RU
# Использовать внешний конфиг
./sub-filter --cli --config ./my-config.yamlИнформация о странах хранится в ./config/countries.yaml в плоском формате:
RU:
cca3: RUS
flag: '🇷🇺'
name: Russia
native: 'Россия|Российская Федерация'Программа ищет внутри фрагмента ссылки (#...) следующие строки:
- Код страны (CCA2):
RU - Код (CCA3):
RUS - Флаг:
🇷🇺 - Общее название:
Russia - Национальные названия:
Россия,Российская Федерация
Сравнение — регистронезависимое и поддерживает URL-декодирование.
| Параметр | Описание |
|---|---|
<порт> |
Порт HTTP-сервера (обязателен в серверном режиме) |
cache_ttl |
Время кеширования в секундах (по умолчанию 1800) |
sources_file |
Список URL-подписок (по одному на строку) sub.txt |
bad_words_file |
Список правил обработки запрещённых слов (удалить/вырезать) badwords.yaml |
uagent_file |
Список разрешённых User-Agent (например, Clash) uagent.txt |
rules_file |
Файл правил валидации rules.yaml |
| Флаг | Описание |
|---|---|
--cli |
Запуск в CLI-режиме |
--stdout |
Вывод результата в stdout |
--config |
Путь к файлу конфигурации |
--country |
Фильтрация по странам (только в CLI) |
curl -H "User-Agent: Clash" "http://localhost:8000/filter?id=1&c=AD"./sub-filter --cli --country=US --stdoutРезультаты сохраняются в /tmp/sub-filter-cache (или в указанную директорию).
Добавьте подписку вида:
http://ваш-сервер:8000/filter?id=1&c=NL,RU
🔒 Рекомендуется использовать за reverse proxy с HTTPS.
docker run -d \
-p 8080:8080 \
-v $(pwd)/config:/config:ro \
-v $(pwd)/cache:/tmp/sub-filter-cache \
ghcr.io/viktor45/sub-filter:latest \
8080 1800# Обработка подписок
docker run --rm \
-v $(pwd)/config:/config:ro \
-v $(pwd)/cache:/tmp/sub-filter-cache \
ghcr.io/viktor45/sub-filter:latest \
--cli --country=DE
# Вывод в терминал
docker run --rm \
-v $(pwd)/config:/config:ro \
-v $(pwd)/cache:/tmp/sub-filter-cache \
ghcr.io/viktor45/sub-filter:latest \
--cli --stdout
💡 Убедитесь, что папки
./configи./cacheсуществуют перед запуском.