cgroup 内のトラフィックを VPN トンネル外にルーティングする

cgroup 内のトラフィックを VPN トンネル外にルーティングする

一部のトラフィックを 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

これで正しいパケットが実際に送信されます。

  • デフォルトルート経由で到着していない場合でも、応答フローを受け入れることを許可する
  1. リラックスするかリバースパス転送ルーズモードに変更rp_filter:

        sysctl -w net.ipv4.conf.wlo1.rp_filter=2
    
  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) を介してユーザーのトラフィックをルーティングする

関連情報