タイムスタンプに基づいて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分ごとに交互に生成する方法はありますか?
map という名前の事前に計算されたルックアップを使用することで、nftablesの制限を回避することができます。
必須:
meta hour
の場合typeof
の代わりに使用できる新しいtype
の場合、これはmeta hour
のmapでサポートされている唯一の構文のようです。 type meta hour
が古いnftablesでtype hour
として読み戻された場合でも、typeof meta hour
またはtype hour
は受け入れられません。nftables
は、任意の算術(または論理など)演算を実行できません。現在、パケットパスまたはnumgen
のようないくつかの拡張子から取得する必要があるデータに対して、左側(LHS)でいくつかの操作を実行し、それを一定の右側(RHS)と比較することに制限されています。セットとマップからRHS値を取得することを含みます。
nftables LHSで任意の除算を計算する方法はありません(右シフトを使用して2の累乗で除算しますが、後で参照してください)。また、名前付きマップでキーとして受け入れられるデータ型などの計算結果を表現する方法もないようです。これは、「非修飾」integer型がそのような操作の結果であることが多いためです。少なくとも現在のところ、名前付きマップでは有効なキータイプではありません。たとえば、匿名マップで機能する場合でも、numgen
式をnamedマップで使用できるかどうかはわかりません。
この場合、 Linuxカーネル5.4 は、カーネル内のパケットのタイムスタンプに関連するメタステートメントを導入します。
- 時間、日、時間のメタ一致をカーネルに導入します commit
ここで、meta hour
は、不足している必須操作「mod 86400」を提供します。これは、OPの「タイムスタンプ/ 1800」の要件に十分に関連しています。1日の始まりからのパケットの時刻を示します。さらに、特定のタイプがあり、名前付きマップで使用できます。
loop unrolling と同様の方法として、複雑な操作を簡略化するため、式で計算できない値は、型が名前付きで有効である限り、事前に計算してマップテーブルに格納できます。地図。エントリの数は事前にわかっていて、まだ制限されているため、これは許容されます。この場合、1日は48時間半です。
マッピングにより、最終結果であるIPv4アドレスを提供できます。
wanで受信したすべてのトラフィックを各時間の最初の30分で10.10.10.1に転送し、後半の10.10.10.2に転送するロードバランサーのルールセットの例(実行dnat) :
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
を使用するかどうかの効果を確認して、理解を深めることができます。markを使用して柔軟性を高める場合(dnatルール以外の場所でmarkを再利用することにより、-に保存することを含む) connmark)、たとえば2つのマップを使用できます。1つはマップにhourからmarkに、もう1つはマップにmark 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 }