Можно ли построить карту nftables на основе метки времени?
В настоящее время использую:
numgen random mod 2 map {
0: 10.10.10.1,
1: 10.10.10.2,
}
Но как преобразовать random mod 2
выражение для (timestamp / 1800) mod 2
, т.е. для создания ключей для карты вроде 0
и 1
чередуя каждые 30 минут?
Можно обойти столы ограничения с использованием предварительно вычисленного поиска с именем карта.
Необходимые:
meta hour
typeof
который можно использовать вместо type
и который, по-видимому, является единственным синтаксисом, поддерживаемым в карта для meta hour
. type meta hour
или type hour
не будет принято, даже если typeof meta hour
читается как type hour
с более старой версией nftables.nftables
не может выполнять произвольные арифметические (логические и т. д.) операции. В настоящее время он ограничен выполнением нескольких операций в левой части (LHS) с данными, которые должны поступать из пути пакета или несколькими расширениями, такими как numgen
и сравните его с постоянной правой частью (RHS), включая получение значения RHS из наборов и карт.
Нет возможности иметь столы вычислить произвольное деление в LHS (используя сдвиг вправо для деления на степень двух, работает, но см. позже). И, похоже, также нет способа выразить результат такого вычисления как тип данных, принятый в качестве ключа в именованной карте, потому что "неквалифицированный" целое число Тип, который часто является результатом таких операций, не является допустимым типом ключа в именованной карте, по крайней мере, в настоящее время. Например, я не уверен numgen
выражение может использоваться с названный map, даже если он работает с анонимной картой.
В этом случае Ядро Linux 5.4 вводит мета-операторы, связанные с отметкой времени пакета в ядре:
- Ввести мета-совпадения в ядро для времени, дня и часа совершить
Вот, meta hour
обеспечивает отсутствующую требуемую операцию "mod 86400", которая достаточно связана с требованием OP "timestamp / 1800": дает время пакета с начала дня. Более того, он имеет определенный тип, что позволяет использовать его в именованной карте.
Как метод, аналогичный разворачивание петли для упрощения сложных операций значения, которые нельзя вычислить в выражениях, можно предварительно вычислить и сохранить в таблице карты, если тип допустим для именованной карты. Это приемлемо, потому что количество записей будет известно заранее и все еще ограничено: в этом случае в сутках 48 полчасов.
После этого сопоставление может дать окончательный результат: адрес IPv4.
Пример набора правил для балансировщика нагрузки (выполнение dnat), который перенаправляет весь трафик, полученный на wan0 до 10.10.10.1 первые полчаса каждого часа и до 10.10.10.2 вторые полчаса:
table ip mytable
delete table ip mytable
table ip mytable {
map hour2ip {
typeof meta hour : ip daddr
flags interval
}
chain mylb {
type nat hook prerouting priority dstnat; policy accept;
iif wan0 dnat to meta hour map @hour2ip
}
}
Скрипт, генерирующий команды nftables для заполнения карты hour2ip (используйте ./script.sh | nft -f -
):
#!/bin/sh
for h in $(seq 0 23); do
for m in 0 30; do
printf 'add element ip mytable hour2ip { "%02d:%02d:00"-"%02d:%02d:59" : %s }\n' $h $m $h $((m+29)) '$ip'
done
done |
sed 's/$ip/10.10.10.X/g' |
awk '{ printf "%s\n",gensub("X",(NR-1)%2+1,1) }'
который будет генерировать такие команды:
add element ip mytable hour2ip { "00:00:00"-"00:29:59" : 10.10.10.1 }
add element ip mytable hour2ip { "00:30:00"-"00:59:59" : 10.10.10.2 }
[...]
add element ip mytable hour2ip { "23:00:00"-"23:29:59" : 10.10.10.1 }
add element ip mytable hour2ip { "23:30:00"-"23:59:59" : 10.10.10.2 }
ноты:
meta hour
(который является модулем) отправляются или отображаются обратно из ядра, которое, как обычно, использует только время UTC. Вот почему порядок будет отображаться смещенным в зависимости от текущего часового пояса, но будет вести себя так, как ожидалось. Вы можете проверить эффект использования или отсутствия переменной среды TZ=UTC
при отображении назад nft list map ip mytable hour2ip
чтобы лучше понять это.Если вы предпочитаете использовать отметка для большей гибкости (повторное использование отметка в другом месте, кроме dnat правило, включая сохранение его в Connmark), вы можете использовать, например, две карты: одну для отображения час к отметка и другой на карту отметка на IP-адрес.
Для этого замените, например, предыдущий набор правил на:
table ip mytable
delete table ip mytable
table ip mytable {
map hour2mark {
typeof meta hour : meta mark
flags interval
}
map mark2ip {
typeof meta mark : ip daddr
elements = { 1 : 10.10.10.1, 2 : 10.10.10.2 }
}
chain mylb {
type nat hook prerouting priority dstnat; policy accept;
iif wan0 meta mark set meta hour map @hour2mark dnat to meta mark map @mark2ip
}
}
и замените в предыдущем скрипте, генерирующем записи:
sed 's/$ip/10.10.10.X/g' |
с участием:
sed 's/hour2ip/hour2mark/;s/$ip/X/g' |
для создания команд для заполнения hour2mark, лайк:
add element ip mytable hour2mark { "00:00:00"-"00:29:59" : 1 }
add element ip mytable hour2mark { "00:30:00"-"00:59:59" : 2 }
[...]
add element ip mytable hour2mark { "23:00:00"-"23:29:59" : 1 }
add element ip mytable hour2mark { "23:30:00"-"23:59:59" : 2 }