Можно ли получить доступ к фрагментам 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
,