
一部のトラフィックを VPN 経由で通過させ、他のトラフィックを VPN 経由で通過させないようにしようとしています。
指定された fwmark を持つパケットはデフォルトのインターフェイス ( ) に送られwlo1
、その他のすべてのトラフィックはtun0
メイン テーブルのトンネル インターフェイス ( 、OpenVPN を使用) に送られるはずです。nftables に次のルールを追加しました。
table ip test {
chain test {
type route hook output priority mangle; policy accept;
meta cgroup 1234 meta mark set 1
}
}
メイン ルーティング テーブルには次のエントリがあります。
default via 10.11.0.1 dev tun0
10.11.0.0/16 dev tun0 proto kernel scope link src 10.11.0.20
[WANIP.0]/24 dev wlo1 proto kernel scope link src [WANIP]
128.0.0.0/1 via 10.11.0.1 dev tun0
[VPNIP] via [WANGATEWAY] dev wlo1
fwmark の付いたパケットは1
、代わりに独自のルーティング テーブルに導かれます: ip rule add from all fwmark 1 lookup test
。テーブルにtest
次のルートを追加しました:
default via [WANGATEWAY] dev wlo1
この cgroup から実行するとping 8.8.8.8
、スタックします。パケットの送信はできるようですが、受信はできません。
VPN トラフィックは期待どおりに動作します。
いったい何が起こっているのでしょうか?
答え1
パケットが送信されると、ルーティングの決定が行われます。この決定により、送信インターフェースが選択されます。そして使用する一致する送信元 IP アドレス。
ときルート/出力チェーンがマークを設定すると、ルート変更チェック、この図からわかるように概略図(これはiptables念頭に置いていますが、完全に使用可能ですnftables)。再ルート チェックによりルートは変更されますが、送信元 IP アドレスは変更されません。そのため、さらに作業を行う必要があります。
- 送信元 IP アドレスを変更するには、NAT ルールを追加します。
これはやらなければならない後ルート変更のチェックはnat/ポストルーティング同じテーブルに異なるチェーンタイプが存在する場合があることに注意してください(iptablesここで、テーブル <=> タイプ)。
nft add chain ip test testnat '{ type nat hook postrouting priority srcnat; policy accept; }'
nft add rule ip test testnat meta mark 1 masquerade
これで正しいパケットが実際に送信されます。
- デフォルトルート経由で到着していない場合でも、応答フローを受け入れることを許可する
リラックスするかリバースパス転送ルーズモードに変更
rp_filter
:sysctl -w net.ipv4.conf.wlo1.rp_filter=2
または、返信フローをマークして、送信フローと同じルーティング テーブルを使用します。セキュリティが実際に向上するわけではありませんが、とにかく:
nft add chain ip test testpre '{ type filter hook prerouting priority mangle; policy accept; }' nft add rule ip test testpre iif "wlo1" meta mark set 1
残念ながら、これは、新しい文書化されていない機能2010年に登場:
sysctl -w net.ipv4.conf.wlo1.src_valid_mark=1
ノート:
マークをconntrackに保存することで、セキュリティ面でより優れたものになる可能性がある。コネマーク(
ct mark
)は、正しい応答フローのみを許可し、それ以外のものは厳密なリバースパス転送をバイパスしないようにします。厳密モードでは、何も通過しません。ウィロー1送信トラフィックからの応答でない限り、これはもう必要ありません。これに対応する完全な nftables ルール ファイルは次のとおりです (nftables ルールを置き換える際に、上記のオプション 2 で使用します)。table ip test { chain test { type route hook output priority mangle; policy accept; meta cgroup 1234 meta mark set 1 ct mark set meta mark } chain testnat { type nat hook postrouting priority srcnat; policy accept; meta mark 1 masquerade } chain testpre { type filter hook prerouting priority mangle; policy accept; ct mark 1 meta mark set ct mark } }
また、マーク再ルートチェックは、正しいPMTU / TCP MSSを妨げる可能性があると、私が読んだところによると、uidrangeエントリ:https://kernelnewbies.org/Linux_4.10#ネットワーク
代わりに cgroups の使用を限定された uid セットに変換できる場合は、
ip rule add ... uidrange ...
上記のように、netfilter や nftables を使用せずにルーティング スタックのみを使用してこれを正しく実行できます。これについては、私の回答を参照してください。特定のインターフェース (tum1) を介してユーザーのトラフィックをルーティングする。