Перейти к содержимому
Полный пример конфигурации

Полный пример конфигурации

На этой странице приведён один полный пример конфигурации с комментариями, который показывает все поддерживаемые разделы и все поддерживаемые опции.

Комментарии поддерживаются в реальных конфигурационных файлах keen-pbr, поэтому этот пример можно использовать напрямую как стартовую точку.

Имена списков, теги outbound и теги DNS-серверов должны соответствовать шаблону ^[a-z][a-z0-9_]*$ и не превышать 24 символа.
config.json
{
  // Глобальные настройки демона.
  // Все поля в этом разделе необязательны.
  "daemon": {
    // Путь к PID-файлу.
    // По умолчанию: PID-файл не создаётся, если поле опущено.
    "pid_file": "/var/run/keen-pbr.pid",

    // Каталог для кэша удалённых списков и метаданных кэша.
    // По умолчанию: (показано ниже)
    "cache_dir": "/var/cache/keen-pbr",

    // Выбор backend firewall.
    // Поддерживаемые значения: "auto", "iptables", "nftables".
    // По умолчанию: (показано ниже)
    "firewall_backend": "auto",

    // Пропускать пакеты, которые уже имеют fwmark, до обработки keen-pbr.
    // По умолчанию: (показано ниже)
    "skip_marked_packets": true,

    // Глобальное поведение strict routing для outbounds типа interface.
    // По умолчанию: (показано ниже)
    "strict_enforcement": false,

    // Максимальный допустимый размер загружаемого удалённого контента, например URL-списков.
    // По умолчанию: (показано ниже)
    "max_file_size_bytes": 8388608,

    // Максимальный размер stdout, сохраняемый для одной команды проверки firewall.
    // Используйте 0, чтобы не ограничивать размер.
    // По умолчанию: (показано ниже)
    "firewall_verify_max_bytes": 262144
  },

  // Настройки встроенного HTTP API и Web UI.
  // ВНИМАНИЕ: этот раздел недоступен в пакете keen-pbr-headless
  "api": {
    // Включить или выключить HTTP API / Web UI.
    // По умолчанию: false.
    "enabled": true,

    // Адрес прослушивания API-сервера.
    // По умолчанию: (показано ниже)
    "listen": "0.0.0.0:12121"
  },

  // Все поддерживаемые типы outbounds.
  // Их теги используются в route rules, detour у DNS-серверов и detour у списков.
  "outbounds": [
    {
      // "interface" отправляет трафик через конкретный сетевой интерфейс.
      "type": "interface",

      // Уникальный тег outbound.
      // По умолчанию: нет, поле обязательно.
      "tag": "vpn",

      // Имя исходящего интерфейса.
      // По умолчанию: нет, обязательно для type="interface".
      "interface": "wg0",

      // Необязательный IPv4-шлюз для interface outbound.
      // По умолчанию: null
      "gateway": "10.8.0.1",

      // Необязательный IPv6-шлюз для interface outbound.
      // По умолчанию: null
      "gateway6": "2001:db8::1",

      // Переопределение strict_enforcement для конкретного outbound.
      // Если указано, имеет приоритет над daemon.strict_enforcement.
      // По умолчанию: наследуется daemon.strict_enforcement.
      "strict_enforcement": true
    },
    
    {
      // Ещё один пример interface outbound, часто используется как обычный WAN-путь.
      "type": "interface",
      "tag": "wan",
      "interface": "eth0",
      // Указывайте gateway только если уверены, что он не изменится в будущем
      // Лучший способ — создать outbound с table=254, что соответствует основной таблице маршрутизации (main)
      "gateway": "172.12.33.1"
    },
    
    {
      // "table" использует уже существующую таблицу маршрутизации ядра.
      "type": "table",

      // Уникальный тег outbound.
      "tag": "wan_as_table",

      // ID существующей Linux routing table.
      // По умолчанию: нет, обязательно для type="table".
      "table": 254
    },

    {
      // "blackhole" отбрасывает совпавший трафик.
      "type": "blackhole",
      
      // Уникальный тег outbound.
      "tag": "block"
    },

    {
      // "ignore" позволяет совпавшему трафику пройти мимо обработки keen-pbr
      // и использовать обычную системную маршрутизацию.
      "type": "ignore",

      // Уникальный тег outbound.
      "tag": "direct"
    },

    {
      // "urltest" проверяет несколько кандидатов и автоматически выбирает один outbound.
      "type": "urltest",

      // Уникальный тег outbound.
      "tag": "auto_select",

      // URL для проверки задержки / доступности.
      // По умолчанию: нет, обязательно для type="urltest".
      "url": "https://www.gstatic.com/generate_204",

      // Интервал проверок в миллисекундах.
      // По умолчанию: (показано ниже)
      "interval_ms": 180000,

      // Таймаут каждой отдельной попытки проверки в миллисекундах.
      // По умолчанию: (показано ниже)
      "probe_timeout_ms": 5000,

      // Не переключаться, если новый кандидат лишь немного лучше текущего.
      // По умолчанию: (показано ниже)
      "tolerance_ms": 100,

      // Поле оставлено для совместимости со старыми конфигами.
      // Urltest всегда добавляет терминальные IPv4/IPv6 маршруты unreachable как kill-switch.
      // Сейчас это поле не даёт дополнительного эффекта для outbounds типа urltest.
      "strict_enforcement": true,

      // Упорядоченные группы outbounds.
      // По умолчанию: нет, обязательно для type="urltest".
      // Меньший weight имеет более высокий приоритет.
      "outbound_groups": [
        {
          // Относительный приоритет этой группы.
          // По умолчанию: (показано ниже)
          "weight": 1,

          // Теги кандидатов внутри этой группы.
          // Поддерживаемые дочерние типы: interface, table, blackhole.
          "outbounds": ["vpn", "custom_table"]
        },
        {
          // Если первая группа нездорова, keen-pbr может переключиться на эту.
          "weight": 2,
          "outbounds": ["wan", "block"]
        }
      ],

      // Поведение повторных проверок.
      "retry": {
        // Число повторных попыток до признания проверки неуспешной.
        // По умолчанию: (показано ниже)
        "attempts": 3,

        // Задержка между повторами в миллисекундах.
        // По умолчанию: (показано ниже)
        "interval_ms": 1000
      },

      // Настройки circuit breaker для нестабильных outbounds.
      "circuit_breaker": {
        // Число последовательных ошибок до открытия circuit breaker.
        // По умолчанию: (показано ниже)
        "failure_threshold": 5,

        // Число успешных проверок для возврата в нормальное состояние.
        // По умолчанию: (показано ниже)
        "success_threshold": 2,

        // Пауза перед переходом из open в half-open.
        // По умолчанию: (показано ниже)
        "timeout_ms": 30000,

        // Максимум проверок, разрешённых в состоянии half-open.
        // По умолчанию: (показано ниже)
        "half_open_max_requests": 1
      }
    }
  ],

  // Все поддерживаемые варианты списков.
  // Каждый список должен содержать хотя бы одно из полей: url, domains, ip_cidrs, file.
  "lists": {

    "inline_domains": {
      // Домены, заданные прямо в конфиге.
      // Совпадают и с самим доменом, и с его поддоменами.
      // Шаблоны вида "*.example.com" допустимы, но не обязательны. Поведение будет таким же, как при вводе "example.com"
      "domains": ["example.com", "othersite.net"],

      // Сколько времени IP, разрешённые dnsmasq для этих доменов,
      // живут в динамическом наборе.
      // 0 означает бессрочно.
      // Должно быть больше, чем значение опции dnsmasq max-cache-ttl. 
      // ПРИМЕЧАНИЕ: dnsmasq max-cache-ttl задаётся в секундах, а ttl_ms здесь — в миллисекундах. Поэтому если max-cache-ttl=300, я бы рекомендовал поставить ttl_ms как минимум (max-cache-ttl * 1000 + 30мин) = 2100000 (35 мин)
      // По умолчанию: значение ниже (24 часа).
      "ttl_ms": 86400000
    },

    "inline_ips": {
      // IPv4/IPv6-адреса или CIDR, заданные прямо в конфиге.
      "ip_cidrs": [
        "93.184.216.34",
        "10.0.0.0/8",
        "2001:db8::1",
        "2001:db8::/32"
      ]

      // Нет необходимости задавать ttl_ms, если ваш список не содержит доменов
      // "ttl_ms": 0
    },

    "remote_list": {
      // URL удалённого списка.
      "url": "https://raw.githubusercontent.com/v2fly/domain-list-community/refs/heads/master/data/apple",

      // Необязательный outbound, через который будет загружаться этот список.
      // Поддерживаются routable-типы, такие как interface, table или urltest.
      // По умолчанию: null (используется обычная системная маршрутизация)
      "detour": "auto_select",

      // Сколько времени IP, разрешённые dnsmasq для этих доменов,
      // живут в динамическом наборе.
      // 0 означает бессрочно.
      // Должно быть больше, чем значение опции dnsmasq max-cache-ttl. 
      // ПРИМЕЧАНИЕ: dnsmasq max-cache-ttl задаётся в секундах, а ttl_ms здесь — в миллисекундах. Поэтому если max-cache-ttl=300, я бы рекомендовал поставить ttl_ms как минимум (max-cache-ttl * 1000 + 30мин) = 2100000 (35 мин)
      // По умолчанию: значение ниже (24 часа).
      "ttl_ms": 86400000
    },
  
    "local_file_list": {
      // Путь к локальному файлу списка.
      "file": "/etc/keen-pbr/local.lst",
      
      // Сколько времени IP, разрешённые dnsmasq для этих доменов,
      // живут в динамическом наборе.
      // 0 означает бессрочно.
      // Должно быть больше, чем значение опции dnsmasq max-cache-ttl. 
      // ПРИМЕЧАНИЕ: dnsmasq max-cache-ttl задаётся в секундах, а ttl_ms здесь — в миллисекундах. Поэтому если max-cache-ttl=300, я бы рекомендовал поставить ttl_ms как минимум (max-cache-ttl * 1000 + 30мин) = 2100000 (35 мин)
      // По умолчанию: значение ниже (24 часа).
      "ttl_ms": 86400000
    },

    "mixed_sources": {
      // В текущих версиях keen-pbr можно объединять несколько источников в одном списке.
      // Это поддерживается, но отдельные списки обычно проще сопровождать.
      "domains": ["intranet.example"],
      "ip_cidrs": ["192.168.50.0/24"],
      "file": "/etc/keen-pbr/mixed.lst",
      "url": "https://example.com/mixed.lst",
      "detour": "vpn",
      "ttl_ms": 86400000
    }
  },

  // DNS-конфигурация.
  // dns.system_resolver обязателен для работающего демона.
  "dns": {
    // Резолвер, используемый для runtime-интеграции и TXT health checks.
    // По умолчанию: нет, поле обязательно для работающего демона.
    "system_resolver": {
      "address": "127.0.0.1"
    },

    // Необязательный встроенный DNS probe server для Web UI и инструментов диагностики.
    // Вы можете проверить, что на ПК корректно настроен DNS, выполнив следующую команду:
    // > nslookup check.keen.pbr
    // Эта команда должна вернуть IP answer_ipv4 (127.0.0.88), что означает, что DNS-настройка вашего ПК корректна и keen-pbr видит ваши DNS-запросы
    "dns_test_server": {
      // IPv4-адрес прослушивания в формате host:port.
      // По умолчанию: нет, обязателен если dns_test_server присутствует.
      "listen": "127.0.0.88:12153",

      // IPv4 A-record, возвращаемый probe server.
      // По умолчанию: значение ниже, если поле опущено в этом примере.
      "answer_ipv4": "127.0.0.88"
    },

    // Все поддерживаемые типы DNS-серверов.
    "servers": [
      {
        // Обычный static DNS-сервер без detour.
        "tag": "google_dns",

        // Поддерживаемые значения: "static" (по умолчанию) или "keenetic".
        // По умолчанию: значение ниже, если поле опущено.
        "type": "static",

        // Адрес для static DNS-серверов.
        // По умолчанию: нет, обязателен для type="static".
        "address": "8.8.8.8"
      },

      {
        // Static DNS-сервер, доступ к которому идёт через interface outbound.
        "tag": "vpn_dns",
        "address": "10.8.0.1:5353",

        // Необязательный outbound, через который нужно обращаться к этому DNS-серверу.
        // Поддерживаемые detour-цели: interface, table, urltest.
        // Не допускаются: blackhole, ignore.
        // По умолчанию: использовать обычную системную маршрутизацию.
        "detour": "vpn"
      },

      {
        // Static DNS-сервер через urltest outbound.
        "tag": "auto_dns",
        "address": "[2606:4700:4700::1111]:53",
        "detour": "auto_select"
      },

      {
        // Источник Keenetic DNS, который использует встроенные DNS-настройки роутера через RCI.
        // Это самый простой способ настроить DoT/DoH на Keenetic. Просто настройте DoT/DoH на роутере и добавьте DNS типа Keenetic в keen-pbr.
        // ВНИМАНИЕ: эта опция поддерживается только на роутерах Keenetic и Netcraze
        "tag": "keenetic_dns",
        "type": "keenetic"
      }
    ],

    // Правила сопоставления доменов и DNS-серверов.
    "rules": [
      {
        // Активно ли это DNS-правило.
        // По умолчанию: true, если поле опущено или равно null.
        "enabled": true,

        // Списки, чьи домены нужно резолвить этим сервером.
        "list": ["inline_domains", "remote_list"],

        // Тег DNS-сервера.
        "server": "vpn_dns",

        // Разрешить ответы, которые указывают на приватные / локальные IP-диапазоны.
        // По умолчанию: (показано ниже)
        "allow_domain_rebinding": false
      },

      {
        // Пример правила для локальных сервисов, которые специально резолвятся в RFC1918-адреса.
        "list": ["mixed_sources"],
        "server": "keenetic_dns",
        "allow_domain_rebinding": true
      },

      {
        // Пример отключённого DNS-правила, оставленного на будущее.
        "enabled": false,
        "list": ["inline_domains"],
        "server": "table_dns"
      }
    ],

    // Upstream DNS-серверы, используемые если ни одно DNS-правило не совпало.
    // По умолчанию: upstream-серверы не заданы.
    // ВНИМАНИЕ: если вы не укажете здесь хотя бы один DNS-сервер, доступ в интернет может перестать работать.
    "fallback": ["google_dns", "auto_dns", "keenetic_dns"]
  },

  // Настройки распределения firewall mark.
  // Этот раздел необязателен.
  "fwmark": {
    // Первый fwmark, который назначается routable outbounds, в hex-строке.
    // По умолчанию: (показано ниже)
    "start": "0x00010000",

    // Битовая маска fwmark в hex-строке.
    // Должна содержать один или несколько последовательных F-нибблов.
    // По умолчанию: (показано ниже)
    "mask": "0x00FF0000"
  },

  // Настройки выделения policy-routing table.
  // Этот раздел необязателен.
  "iproute": {
    // Первый ID таблицы маршрутизации для автоматически выделяемых outbound-таблиц.
    // По умолчанию: (показано ниже)
    // Избегайте зарезервированных ID, таких как 128 и 250-260.
    "table_start": 150
  },

  // Правила обработки маршрутизации.
  "route": {
    // Необязательный фильтр по входящим интерфейсам.
    // Если поле опущено или пустое, keen-pbr обрабатывает пакеты с любых интерфейсов.
    // По умолчанию: фильтр отсутствует.
    "inbound_interfaces": ["br0", "wg-lan"],

    "rules": [
      {
        // Базовое правило маршрутизации по списку.
        // По умолчанию для enabled: true, если поле опущено или равно null.
        "list": ["inline_domains", "remote_list"],
        "outbound": "auto_select"
      },

      {
        // Маршрутизировать inline IP через существующую таблицу маршрутизации.
        "list": ["inline_ips"],
        "outbound": "custom_table"
      },

      {
        // Пример полного фильтра с proto, адресом источника/назначения и портом назначения.
        "enabled": true,

        // Сопоставлять трафик только если домен/IP назначения есть в списке
        "list": ["mixed_sources"],

        // Сопоставлять трафик только если протокол TCP
        // Возможные значения: null (любой протокол), tcp, udp, tcp/udp
        "proto": "tcp",

        // Сопоставлять трафик только если совпадает IP источника
        // Поддерживается: один IP, CIDR
        "src_addr": "192.168.10.0/24,192.168.20.0/24",

        // Сопоставлять трафик только если совпадает IP назначения
        // Поддерживается: один IP, CIDR
        "dest_addr": "203.0.113.0/24",

        // Сопоставлять трафик только если совпадает порт источника
        // Поддерживается: один порт, несколько портов через запятую, диапазон
        "src_port": "1024-65535",

        // Сопоставлять трафик только если совпадает порт назначения
        // Поддерживается: один порт, несколько портов через запятую, диапазон
        "dest_port": "443,8443",

        // Направить весь совпавший трафик в этот outbound
        "outbound": "vpn"
      },

      {
        // В rules можно не указывать "list", если есть другое условие.
        // Этот пример блокирует DNS на любые адреса, кроме доверенной подсети резолвера.
        "proto": "udp",
        "dest_port": "53",
        "dest_addr": "!10.10.0.0/16",
        "outbound": "block"
      },

      {
        // Пример правила "ignore", используемого как исключение перед более широкими VPN-правилами.
        "src_addr": "192.168.1.0/24",
        "dest_addr": "192.168.0.0/16",
        "outbound": "direct"
      },

      {
        // Пример IPv6: направить HTTPS-трафик к подсети документации через VPN.
        "proto": "tcp",
        "src_addr": "2001:db8:10::/64",
        "dest_addr": "2001:db8:203::/48",
        "dest_port": "443",
        "outbound": "vpn"
      },

      {
        // Пример отключённого правила, оставленного на будущее.
        "enabled": false,
        "list": ["inline_domains"],
        "proto": "tcp/udp",
        "dest_port": "!80,443",
        "outbound": "wan"
      }
    ]
  },

  // Автоматическое обновление URL-списков.
  // Этот раздел необязателен.
  "lists_autoupdate": {
    // Включить или выключить периодическое обновление.
    // По умолчанию: false.
    "enabled": true,

    // Стандартное 5-полевое cron-выражение.
    // Обязательно, когда enabled=true.
    // Значение по умолчанию отсутствует.
    "cron": "0 4 * * 0"
  }
}

Примечания

  • dns.servers[].detour поддерживает outbounds типов interface, table и urltest, но не blackhole и не ignore.
  • lists[].detour полезен, когда удалённый список нужно загружать через VPN или другой нестандартный маршрут.
  • route.rules[] должен содержать хотя бы одно условие совпадения: list, src_port, dest_port, src_addr или dest_addr.
  • dns.rules[].allow_domain_rebinding в основном нужен для внутренних доменов, которые специально резолвятся в приватные IP-адреса.