web-dev-qa-db-ja.com

nftablesを使用してUIDに基づいてルーティングを決定する

元のプロセスのuidに基づいてパケットをルーティングしようとしています。

PREROUTINGが発信パケットに対してヒットしないことを私は知っています。 iptablesでは、これらのルールをOUTPUTチェーン内に配置できるMANGLEテーブルがあります。 nftablesにはMANGLEフックなどがありません。 OUTPUTフックのみがあります。

これは、ルーティング決定の前にホストで発信された発信パケットをマークする方法がないというnftablesの制限ですか?

nftables v0.7 (Scrooge McDuck)
Linux 4.14.5-1-Arch #1 SMP PREEMPT Sun Dec 10 14:50:30 UTC 2017 x86_64 GNU/Linux
1

Nftablesの命名規則により、この機能が存在しないと誤解された可能性があります。

nftablesのwiki から:

route。これは、関連するIPヘッダーフィールドまたはパケットマークが変更された場合にパケットを再ルーティングするために使用されます。 iptablesに精通している場合、このチェーンタイプは、mangleテーブルと同等のセマンティクスを提供しますが、outputフック(他のフックの場合は、代わりにタイプfilterを使用してください)。これは、ipおよびip6テーブルファミリでサポートされています。

したがって、debianstretchのカーネル4.9.0-4-AMD64 #1 SMP Debian 4.9.65-3 (2017-12-03)を使用してLXCコンテナーからこれらすべてを実行し、uid 1001をインターネット(ここではTCPを使用するGoogleのパブリックDNS)に接続できる唯一のユーザーにします。

#ip route 
 default via 10.0.3.1 dev eth0 
 10.0.3.0/24 dev eth0 proto kernel scope link src 10.0.3.66 
#pkill -9 dhclient 
#ip route del default 
#ip route add default via 10.0.3.2 dev eth0#10.0.3.2は存在しませんが、ルーティングコードがfwmarkルールをトリガーするにはデフォルトルートが必要ですそれ以外の場合は、パケットが生成されない直接の「ネットワークに到達できません」があります。
#ip route add default via 10.0.3.1 table 10 
#ip rule add fwmark 1 table 10 

以下のマングルの正規の名前は、 ここ (または/ usr/share/doc ...)にあります。 -150はNF_IP_PRI_MANGLEの値です

#nft add table ip mangle 
#nft'add chain ip mangle output {type route hook output priority -150; } '
#nft add rule ip mangle output skuid 1001 counter mark set 1 
#id 
 uid = 0(root)gid = 0(root)groups = 0(root) 
#nc -v -n -z 8.8.8.8 53#10.0.3.2へのARP要求でタイムアウトします
 nc:8.8.8.8ポート53(tcp)への接続に失敗しました:ホストへのルートがありません
#su --test 
 $ id 
 uid = 1001(test)gid = 1001(test)groupes = 1001(test)
 $ nc -v -n -z 8.8.8.8 53 
 8.8.8.853ポート[tcp/*]への接続に成功しました!

最後の注意。ネットワーク名前空間を使用して構成を簡素化することについてのコメントがありますが、私は同意することしかできません。コンテナーなしで(独自のネットワーク名前空間を使用して)この例を示すのは困難でした。また、たとえば、ネットワークを使用するsuid rootコマンドがある場合、コマンドの動作に応じて、マークとルートがトリガーされるかどうかが決まります。

更新:ユーザーの接続によって開始された一部のパケットは、(もう)ユーザーのものではありません。これは、最後のACKが接続の終了時にFINパケットを確認した場合に発生する可能性があり、接続が途中で中止された場合のRSTパケットの場合はさらに多くなります。これらのパケットは所有者と一致しないため、マークを受信せず、再ルーティングされません。これにより、転送の終了時にタイムアウトが発生する可能性があります。これを回避するには、これをct mark set mark/mark set ct markiptables'CONNMARKと同等)などの他の機能と組み合わせる必要があります。 conntrackマークおよび同等のiptablesの問題と解決策に関する詳細情報:

nftablesのマークとconntrackのマーク

Netfilter Connmark

Iptables:発信トラフィックをconntrackおよびownerと照合します。奇妙なドロップで動作します

任意のTCP応答パケットでfwmarkリフレクションを強制することは可能ですか?

idなしのiptablesパケット

上記のncを使用した前回の「成功した」テストでタイムアウトが発生しましたが、コマンドが返されたため、ネットワークキャプチャなしでは表示されませんでした。タイムアウトはピアサーバー側で発生しました。これを解決するには、同じルーティングコマンドを維持しますが、上記のnftルールを次のように置き換えます。

# nft add table ip mangle
# nft 'add chain ip mangle output { type route hook output priority -150; }'
# nft flush chain ip mangle output
# nft add rule ip mangle output mark set ct mark counter
# nft add rule ip mangle output mark ne 0 counter accept
# nft add rule ip mangle output skuid 1001 counter mark set 1
# nft add rule ip mangle output ct mark set mark counter

countersはデバッグ用です。

2
A.B