Можно ли получить доступ к фрагментам ip с помощью libnetfilter_queue

Я использую libnetfilter_queue в C для захвата пакетов. Я устанавливаю правило iptable для постановки в очередь входящих пакетов, которые позже будут обработаны реализацией пользовательского пространства, например: iptables -A INPUT -j NFQUEUE --queue-num 0, Я использовал пример nfqnl_test в качестве основы для реализации захвата. Все работает как положено. Однако я заметил, что невозможно проверить очередь на уровне ip-фрагментов. То есть, если пакет приходит фрагментарно, он сначала пересобирается, прежде чем помещается в очередь. Но я бы хотел работать с фрагментами. Так есть ли способ обеспечить такое поведение? То, что я хочу иметь, - это очередь, в которой я мог бы наблюдать необработанные входящие пакеты (как фрагментированные, так и нефрагментированные), чтобы я мог действовать соответственно с ними.

Я читал, что сборка действительно происходит раньше. С другой стороны, с iptables есть -f флаг доступен, поэтому должна быть "гранулярность фрагментации", которую я ищу. Я также попытался настроить правила iptable (например, iptables -t raw -D PREROUTING -i eth0 -j NFQUEUE --queue-num 0), но результат все тот же. Я могу только наблюдать за уже пересобранным пакетом, который я точно знаю, который приходит фрагментарно.

Любая помощь очень ценится.

2 ответа

Решение

Итак, я нашел решение проблемы и делюсь им здесь на случай, если кому-то будет интересно. Авторы получают Адель из списка рассылки netfilter, который предложил возможный обходной путь. По сути, решение состоит в том, чтобы использовать nftables и настроить цепочку с приоритетом ниже, чем для дефрагментации. Я протестировал этот параметр с кодом C, и он, кажется, работает довольно хорошо (я не заметил никаких побочных эффектов). Однако я должен отметить, что я использовал его только для наблюдения за фрагментами IP, и я не вмешивался в них.

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

void set_nftable() {

    int status = 0;

    // Create a nftable 
    status = system("nft add table ip filter");

    // Add a chain to the nftable called "predefrag" which has lower priority than the defragmentation -450 < -400
    status = system("nft add chain ip filter predefrag { type filter hook prerouting priority -- -450 \\; }");

    // Set the nftable rule (queue packets to be accessed by a user-space application)
    status = system("nft add filter predefrag meta iif eth0 counter queue num 0 bypass"); 
}

void remove_nftable() {

    int status = 0;

    // Flush the rules that are stored in the chains that belong to the nftable
    status = system("nft flush table ip filter");

    // Delete the chain from the nftable
    status = system("nft delete chain ip filter predefrag");

    // Delete the nftable
    status = system("nft delete table ip filter");
}

С этими функциями код nfqnl_test может использоваться для захвата фрагментов IP. Ниже приведены полезные ссылки для настройки nftables и понимания того, как они работают (комментарии в функциях не требуют пояснений после ознакомления с руководством по nftables).

http://wiki.nftables.org/wiki-nftables/index.php/Building_and_installing_nftables_from_sources

http://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables

http://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains

http://wiki.nftables.org/wiki-nftables/index.php/Simple_rule_management

http://wiki.nftables.org/wiki-nftables/index.php/Queueing_to_userspace

Прежде всего убедитесь, что ваша сетевая карта не является той, которая выполняет сборку.

Различные методы разгрузки, выполняемые современными сетевыми картами, такими как LRO, UFO и другие, могут собирать фрагменты уровня IP. Я предлагаю использовать ethtool -k чтобы проверить, какие разгрузки активны на соответствующем интерфейсе, а затем отключить их один за другим, используя ethtool -K,

Другие вопросы по тегам