
以下の回答に基づいて作業しています。これ質問と私の構成にいくつかのルールを作成するman nft
ために 。dnat
nftables
関連構成の抜粋は次のとおりです。
define src_ip = 192.168.1.128/26
define dst_ip = 192.168.1.1
define docker_dns = 172.20.10.5
table inet nat {
map dns_nat {
type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service
flags interval
elements = {
$src_ip . $dst_ip . udp . 53 : $docker_dns . 5353,
}
}
chain prerouting {
type nat hook prerouting priority -100; policy accept;
dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat;
}
}
このルールを適用すると、nft -f
コマンド出力が表示されないため、成功したと想定されます。ところで、ルールを利用してルールセットを確認してみるとnft list ruleset
ルールがありません。その行がコメントアウトされるdnat to ...
と、ルールが適用されるように見えますが、その行がある場合は適用されません。
prerouting
交換するチェーンのルールセットは次のとおりです。
ip saddr $src_ip ip daddr $dst_ip udp dport 53 dnat to $docker_dns:5353;
...
バージョン情報:
# nft -v
nftables v1.0.6 (Lester Gooch #5)
# uname -r
6.1.0-11-amd64
なぜこれがうまくいかないのですか?ありがとう
答え1
質問が3つあります。
エラーが表示されない
これはバグのようです。nftables1.0.6、下の箇条書きを参照してください。
同じバージョンとOPのルールセットは次のとおりです
/tmp/ruleset.nft
。# nft -V nftables v1.0.6 (Lester Gooch #5) [...] # nft -f /tmp/ruleset.nft /tmp/ruleset.nft:7:38-45: Error: unknown datatype ip_proto type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service ^^^^^^^^ /tmp/ruleset.nft:6:9-15: Error: set definition does not specify key map dns_nat { ^^^^^^^
エラー:不明なデータ型
ip_proto
元のリンクされたQ&Aは正しいタイプを使用します
inet_proto
。ip_proto
不明なタイプと交換しないでください。したがって、次のように変更してください。type ipv4_addr . ipv4_addr . ip_proto . inet_service : ipv4_addr . inet_service
元のスペルを編集してください。
type ipv4_addr . ipv4_addr . inet_proto . inet_service : ipv4_addr . inet_service
利用可能なタイプのリストは、以下
nft(8)
にあります。ペイロード表現より正確には、この場合IPv4ヘッダー表現:キーワード 説明する タイプ [...] protocol
上位層プロトコル inet_proto
[...] typeof ip protocol
<=>type inet_proto
(いいえtype ip_proto
)。これは正しいタイプを推測するのを避けるために一般的
typeof
に好まれますが、type
私がリンクされたQ&Aに書いたように、一部のバージョンnftablesこの特定のケースは正しく処理されない可能性があります。選択肢は次のとおりです。typeof ip saddr . ip daddr . ip protocol . th dport : ip daddr . th dport
これは使用規則を切り取り、貼り付けたのと似ていますが、動作を徹底的にテストする必要があります。
表示エラーなし - テイク2
以前のエラーを修正して結果を入れると、
/tmp/ruleset2.nft
OPが作成したようにルールセットを再試行すると自動的に失敗します。# nft -V nftables v1.0.6 (Lester Gooch #5) cli: editline json: yes minigmp: no libxtables: yes # nft -f /tmp/ruleset2.nft # echo $? 1 #
失敗の唯一の手がかりはゼロ以外の戻りコードです。
最新製品を使用しながらnftablesバージョン:
# nft -V nftables v1.0.8 (Old Doc Yak #2) cli: editline json: yes minigmp: no libxtables: yes # nft -f /tmp/ruleset2.nft /tmp/ruleset2.nft:16:9-12: Error: specify `dnat ip' or 'dnat ip6' in inet table to disambiguate dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat; ^^^^ #
これでエラーが表示されます。 1.0.6に何か問題があっても、少なくともバージョン1.0.8では修正されました。
エラー:明確にするには、inetテーブルに「dnat ip」または「dnat ip6」を指定してください。
NATは(IPv4)または(IPv6)
inet
ファミリではなくファミリ(IPv4 + IPv6の組み合わせ)で実行されるため、通常はオプションのパラメータが必要です。 NATを適用する必要があるIPバージョン宣言(可能であっても)マップテーブルレイアウト(IPv4)から推論)。文書には次のように記載されています。ip
ip6
snat [[ip | ip6] to] ADDR_SPEC [:PORT_SPEC] [FLAGS] dnat [[ip | ip6] to] ADDR_SPEC [:PORT_SPEC] [FLAGS] masquerade [to :PORT_SPEC] [FLAGS] redirect [to :PORT_SPEC] [FLAGS]
[...]
inetシリーズで使用する場合(カーネル5.2で利用可能)dnatおよびsnatステートメントにはipおよびip6キーワードを使用する必要があります。住所が提供されている場合は、下記の例をご覧ください。
だから:
dnat to ip saddr . ip daddr . ip protocol . th dport map @dns_nat;
次に交換する必要があります。
dnat ip to ip saddr . ip daddr . ip protocol . th dport map @dns_nat
ip
もともとQ/Aにはこのシリーズへの言及はなかったので、基本シリーズと仮定してあえてする必要はないようです。もちろんこれはうまくいきますnftables1.0.6 ではバグ報告のみ問題になります。これで戻りコードは0になります。