Floxy

Floxy позволяет распределять трафик от экспортера flow по нескольким коллекторам, указывая правила пересылки для каждого экспортера отдельно.

Это позволяет решать задачи:

  • обхода ограничения количества получателей flow на экспортере;
  • распределения на коллекторы от разных вендоров;
  • распределения нагрузки по нескольким коллекторам одного вендора;
  • единой настройки получателей на экспортерах.

Floxy принимает пакеты UDP и пересылает их на коллекторы по правилам, сохраняя у пакета адрес и порт отправителя.

Правила

Каждое правило задает от какого экспортера каким коллекторам пересылать пакеты. Экспортеры и коллекторы задаются как адреса и порты. Структуру правил описывает сообщение ProxyRules в gRPC API. Пример правил в формате protobuf text:

# Пакеты от 192.0.2.1:1000 будут пересылаться 192.0.2.11:1001 и [2001:db8::12]:1002.
rules: {
    exporter: {endpoint: {host: "192.0.2.1" port: 1000}}
    outputs: {
        collectors: {endpoint: {host: "192.0.2.11"   port: 1001}}
    }
    outputs: {
        collectors: {endpoint: {host: "2001:db8::12" port: 1002}}
    }
}
# Пакеты с любого другого порта 192.0.2.1 будут пересылаться на 192.0.2.21:2001.
rules: {
    exporter: {endpoint: {host: "192.0.2.1"}}
    outputs: {
        collectors: {endpoint: {host: "192.0.2.21" port: 2001}}
    }
}
# Пакеты от [2001:db8::3]:3000 будут пересылаться [2001:db8::31]:3001,
# а также на [2001:db8::32] и тот порт, на который пришел пакет.
rules: {
    exporter: {endpoint: {host: "2001:db8::3" port: 3000}}
    outputs: {
        collectors: {endpoint: {host: "2001:db8::31" port: 3001}}
    }
    outputs: {
        collectors: {endpoint: {host: "2001:db8::32"}}
    }
}
# Пакеты от 192.0.2.4:4000 будут пересылаться:
# - на 192.0.2.41:4001 и 192.0.2.42:4002 с равномерной балансировкой между ними;
# - на 192.0.2.43:4003 все без исключения.
rules: {
    exporter: {endpoint: {host: "192.0.2.4" port: 4000}}
    outputs: {
        collectors: {endpoint: {host: "192.0.2.41" port: 4001}}
        collectors: {endpoint: {host: "192.0.2.42" port: 4002}}
    }
    outputs: {
        collectors: {endpoint: {host: "192.0.2.43" port: 4003}}
    }
}
# Пакеты, не соответствующие ни одному правилу,
# будут пересылаться на 192.0.2.51:5001 (IPv4) и [2001:db8::52]:5002 (IPv4 и IPv6),
# равномерно распределяясь между ними,
# а также на 192.0.2.53 (IPv4) с сохранением порта, на который пришел пакет.
default_outputs: {
    collectors: {endpoint: {host: "192.0.2.51"   port: 5001}}
    collectors: {endpoint: {host: "2001:db8::52" port: 5002}}
}
default_outputs: {
    collectors: {endpoint: {host: "192.0.2.53"}}
}

Порядок правил (rules), выходов (outputs, default_outputs) и коллекторов (collectors) не имеет значения. Правила, где указан порт экспортера, имеют приоритет над правилами, где порт экспортера не указан.

Пересылка IPv6-пакетов IPv4-коллектору не поддерживается, потому что при этом невозможно сохранить адрес отправителя у пакета.

Системные настройки

Системные настройки задаются через переменные окружения сервиса collector. Чтобы их изменение вступило в силу, нужно перезапустить коллектор.

Функциональность Floxy доступна, если задана переменная среды COLLECTOR_FLOXY_ADDRESS (в логах контейнера collector будут сообщения, что она запущена).

  • COLLECTOR_FLOXY_ADDRESS (по умолчанию не задано, формат host:port): адрес и порт, на которые принимается трафик для пересылки. При указании адреса IPv6 также работает и пересылка трафика IPv4.

  • COLLECTOR_FLOXY_PACKET_BUFFER_SIZE (от 1496 до 65535, по умолчанию 1496): максимальный размер данных в пакете (UDP payload). Должен быть увеличен, если используются Ethernet jumbo frames или большие фрагментированные IP-пакеты. Если придут данные большего размера, Floxy обрежет их и перешлет обрезанными.

  • COLLECTOR_FLOXY_THREAD_COUNT: количество потоков, пересылающих трафик. По умолчанию выбирается как число ядер, доступных сервису collector. Может регулироваться параметром cpuset этого сервиса.

Управление правилами (gRPC API)

Floxy управляется через gRPC API на том же адресе и порту, что и API коллектора (по умолчанию 8853, регулируется COLLECTOR_BACKEND_METRICS_PORT в .env).

Точное описание находится в floxy.proto.

Для каждой версии Collector vXX.YY.Z публикуется образ docker.mitigator.ru/collector/grpcurl:vXX.YY.Z с утилитой grpcurl и файлами *.proto, описывающими API указанной версии. Ниже приведены примеры её использования. Запрос и ответ могут задаваться и выводиться в формате JSON с ключом -format json или в формате protobuf text с ключом -format text. Полную справку можно получить, запустив контейнер с ключом -help.

Все вызовы, изменяющие правила, сохраняют их во внутренней базе данных. При перезапуске Collector восстанавливаются последние настройки, заданные через API.

  • Settings.ListProxyRules: возвращает конфигурацию всех правил.

  • Settings.ReplaceProxyRules: принимает новую конфигурацию правил и заменяет ею текущую.

  • Settings.UpdateProxyRules: принимает конфигурацию правил и добавляет к текущей. Если уже было правило с тем же экспортером, у него заменяется список коллекторов на список из нового правила.

  • Settings.DeleteProxyRules: удаляет правила с указанными экспортерами.

  • Metrics.GetProxyStats: возвращает статистику либо по правилам для указанных экспортеров, либо по всем правилам, если указан пустой список.

  • Settings.GetBuildInfo: возвращает информацию о сборке системы.

  • Settings.GetSystemStatus: возвращает состояние системы, в частности, подсистемы Floxy (proxy).

    Значения состояний (state):

    • OK: подсистема работает и готова к использованию.
    • Configuring: подсистема временно не работает, так как находится в процессе настройки.
    • NotConfigured: подсистема работает, но не удалось восстановить сохраненные настройки. Описание ошибки в error, для её устранения нужно изменить настройки.
    • Offline: подсистема недоступна, решение требует действий на сервере.

Во всех запросах можно указать gRPC-заголовок collector-address-format=binary, чтобы в ответе у Endpoint заполнялось поле octets (бинарное представление адреса), а не host (текстовое представление адреса, по умолчанию или ...=text). В теле запроса и в файлах настроек можно использовать любое из этих полей.

Настройка правил

Если правила записаны в floxy-rules.txtpb, как в примере выше, то следующая команда заменяет текущие правила на правила из файла:

VERSION=$(grep '^VERSION=' .env | cut -d '=' -f 2) && \
docker run --rm --network=host -i docker.mitigator.ru/collector/grpcurl:${VERSION} -proto settings.proto -format text -d "$(sed -s 's/#.*//' floxy-rules.txtpb)" :8853 collector.proto.Settings/ReplaceProxyRules

В случае успеха команда ничего не печатает.

Запрос статистики

Следующая команда запрашивает статистику:

VERSION=$(grep '^VERSION=' .env | cut -d '=' -f 2) && \
docker run --rm --network=host docker.mitigator.ru/collector/grpcurl:${VERSION} -proto settings.proto -format text :8853 collector.proto.Settings/GetProxyStats

В случае успеха вывод может быть таким (на примере тех же правил):

rules: {
    exporter: {
        endpoint: {host: "127.0.0.1" port: 2345}
        input: {packets: 1 bytes: 160}
    }
    outputs: {
        collectors: {
            endpoint: {host: "192.0.2.11" port: 1001}
            output: {packets: 1 bytes: 160}
        }
    }
    outputs: {
        collectors: {
            endpoint: {host: "2001:db8::12" port: 1002}
            output: {packets: 0 bytes: 0}
        }
    }
}
rules: {
    exporter: {
        endpoint: {host: "192.0.0.1"}
        input: {packets: 1 bytes: 160}
    }
    outputs: {
        collectors: {
            endpoint: {host: "192.0.2.21" port: 2001}
            output: {packets: 1 bytes: 160}
        }
    }
}
rules: {
    exporter: {
        endpoint: {host: "2001:db8::3" port: 3000}
        input: {packets: 0 bytes: 0}
    }
    outputs: {
        collectors: {
            endpoint: {host: "2001:db8::31" port: 3001}
            output: {packets: 0 bytes: 0}
        }
    }
    outputs: {
        collectors: {
            endpoint: {host: "2001:db8::32"}
            output: {packets: 0 bytes: 0}
        }
    }
}
rules: {
    exporter: {
        endpoint: {host: "192.0.2.4" port: 4000}
        input: {packets: 2 bytes: 320}
    }
    outputs: {
        collectors: {
            endpoint: {host: "192.0.2.41" port: 4001}
            output: {packets: 1 bytes: 160}
        }
        collectors: {
            endpoint: {host: "192.0.2.42" port: 4002}
            output: {packets: 1 bytes: 160}
        }
    }
    outputs: {
        collectors: {
            endpoint: {host: "192.0.2.43" port: 4003}
            output: {packets: 2 bytes: 320}
        }
    }
}
default_outputs: {
    collectors: {
        endpoint: {host: "192.0.2.51" port: 5001}
        output: {packets: 3 bytes: 480}
    }
    collectors: {
        endpoint: {host: "2001:db8::52" port: 5002}
        output: {packets: 5 bytes: 800}
    }
}
default_outputs: {
    collectors: {
        endpoint: {host: "192.0.2.53"}
        output: {packets: 3 bytes: 480}
    }
}
mismatched: {packets: 5 bytes: 800}

Все счетчики накопительные. Байты (bytes) считаются по UDP payload.

  • rules.exporter.input: принятые пакеты от экспортера. Счетчик растет в том числе тогда, когда не задано коллекторов.

  • rules.exporter.collectors.output: пакеты, которые пересланы от экспортера соответствующему коллектору.

    • Если пакет невозможно было отправить, например, не нашлось подходящего интерфейса по правилам маршрутизации, пакет не учитывается в этом счетчике.
    • Если отправляемый пакет сброшен ядром ОС из-за перегрузки, он все равно учитывается в этом счетчике.
    • Если коллектор был добавлен не при создании, а при обновлении правила, счетчик будет меньше rules.exporter.input.
  • default_collectors.output: пакеты, отправленные каждому из коллекторов в выходах по умолчанию.

    • Включаются в выдачу при запросе статистики для всех правил.
    • IPv4-коллекторам не пересылается трафик IPv6, их счетчики могут быть меньше.
    • Если одни коллекторы по умолчанию добавлены позже других, их счетчики могут быть меньше.
  • mismatched: пакеты, которые не подходили под запрошенные правила.

    • Если статистика запрошена для всех правил, это пакеты, не попавшие ни под одно правило.
    • Если статистика запрошена для части правил, это пакеты, не попавшие ни под одно правило + пакеты, попавшие под правила, для которых статистика не запрошена.

При обновлении правил сохраняется статистика экспортеров и коллекторов, которые есть и в старой, и в новой версии правил.

Отказоустойчивость

В целях повышения отказоустойчивости могут одновременно применяться несколько Floxy.

Для этого на loopback-интерфейсах обоих Floxy задается одинаковый IP-адрес — IPfloxy. С обоих серверов, на которых работают Floxy, устанавливаются BGP-сессии с вышестоящим оборудованием, и в анонсе сообщается, что IPfloxy доступен через их nexthop. На всех источниках настраивается отправка flow на IPfloxy.

В этом случае сетевое оборудование будет самостоятельно выполнять балансировку трафика между двумя устройствами.

В случае нештатного отключения одного из Floxy, неработающий маршрут будет удален из таблиц маршрутизации на сетевом оборудовании, и трафик перестанет балансироваться на неработающее устройство.

Установка и настройка gobgp

Настройка BGP выполняется по инструкции.