Правила - статичная таблица; режим script позволяет куску JavaScript решать судьбу каждого соединения динамически: по времени суток, порту, резолвнутому IP, любой комбинации. Функция Premium-ядра, в CFW работает из коробки.
Включение
Добавьте верхнеуровневую секцию script и поставьте mode: script (в переключателе режимов клиента появится Script):
mode: script
script:
code: |
function main(ctx, metadata) {
// вернуть имя выхода: группа / "DIRECT" / "REJECT"
if (metadata.host && metadata.host.endsWith("company.com")) {
return "DIRECT";
}
// ночной игровой трафик напрямую, днём через прокси
const hour = new Date().getHours();
if (metadata.dst_port === 3074 && hour >= 1 && hour <= 7) {
return "DIRECT";
}
// остальное - обратно движку правил
return ctx.resolveOutbound(metadata) ?? "Select";
}
Полезные поля metadata
| Поле | Смысл |
|---|---|
host | Домен назначения (пустой при соединении на голый IP) |
dst_ip / dst_port | IP и порт назначения |
src_ip / src_port | Адрес источника (различать устройства при allow-lan) |
network | tcp / udp |
process_name | Процесс-инициатор (под TUN) |
Контекст даёт и помощников - ctx.geoip(ip), ctx.resolveIP(host) - для логики «сначала резолвим, потом решаем», которую правилами не выразить.
Шорткаты script: лёгкий вариант
Не хочется забирать весь mode - опишите короткие выражения и ссылайтесь на них из обычных правил:
script:
shortcuts:
late-night-game: dst_port == 3074 and now.hour < 7
rules:
- SCRIPT,late-night-game,DIRECT
- MATCH,Select
Оговорки
- Скрипт выполняется на каждом соединении; тяжёлая логика умножает задержку. Всё, что выражается правилами, - правилами.
- Упавший скрипт валит соединение; после правок смотрите Logs.
- Никогда не запускайте скрипты из чужих конфигов - чем мощнее функция, тем опаснее вредоносный профиль.