SNI に基づく Linux netfilter NAT?

SNI に基づく Linux netfilter NAT?

src IP を維持しながら、ルーター上のサブネットに SNI プロキシを実行しようとしています。

背景: 多くのアプリケーション ポートのポート転送を行うために DNAT を実行するルーターがあり、異なるバックエンドを持つサブネットに接続されています (実際には VPN を使用)。リクエストに基づいて異なる IP にルーティングできる HTTP ホストや TLS SNI のようなものがないプロトコルの場合、TCP ポート フィルターで DNAT を使用するだけで、うまく機能しています。

TLSでは、SNIプロキシTLS SNI に基づいて、着信接続を異なるサーバーに多重化します。これは非常にうまく機能しますが、SINProxy はルーター自体から TLS パケットを送信し、src アドレスを破棄します。これにより、src IP に依存する一部のバックエンド サービスが機能しなくなります。

したがって、netfilter が TLS SNI (オプションで外部モジュールを使用) を使用してトラフィックをフィルタリングし、DNAT を使用してルーティングする (単にドロップする代わりに) ことが可能かどうか疑問に思っています。それが不可能な場合、代替手段はありますか?

ちなみに、私はルーターに完全な HTTP (または L5 サーバー) を展開したくありません。その理由は次のとおりです。

  1. トラフィックを復号化してバックエンドにプロキシする必要があります。これは大きなオーバーヘッドです。
  2. 管理が複雑なため、ルーターに TLS 証明書を導入したくありません。

役に立つご返答をいただければ幸いです。

答え1

理論上は、-j NFQUEUEユーザー空間で最初のパケットを変更して NAT を実行するために使用することで、このようなことを行うことができます。しかし、実際には、新しい宛先アドレスを推測するには SNI 拡張を含む完全な ClientHello メッセージを受信する必要があり、最初の TCP パケットは空であるため、または UDP の場合、DTLS はいずれにしても数ラウンドを必要とするため、conntrack によって管理されるフローを NAT するには遅すぎます。

プロキシが必要です。ただし、プロキシを透過的にすることも、バックエンド アプリケーションがサポートする PROXY プロトコルを使用することもできます (ただし、バックエンド アプリケーションは PROXY プロトコルと TLS の併用をサポートしている必要があります)。

例えば、haproxyゲートウェイ上で実行することで、次のいずれかを実行できます。PROXYプロトコルLinuxも使用可能tプロキシ透過的 (送信元と送信先の両方で透過的) プロキシのターゲット。

両方の選択肢を提供している github gist へのリンクを次に示します。HAProxyを活用して、ホスト名で識別されるWebサービスへのリクエストを透過的にルーティングします。. Linuxカーネルで使用される透過プロキシ設定についていくつか説明します。tプロキシドキュメント(同じ gist 内にあります):

HAProxy サーバーの構成は次のようになります。TCP モードと HTTP モードの両方で機能します。

server app1-tls 192.0.2.10:3001 source * usesrc client weight 0

答え2

そこで、netfilterがTLS SNI(オプションで外部モジュールを使用)を使用してトラフィックをフィルタリングできるかどうか疑問に思っています。

これは不可能です。NAT は、接続の最初のパケット、つまり TCP ハンドシェイクを開始する TCP SYN から実行する必要があります。ただし、SNI は TLS ハンドシェイクの ClientHello にのみ含まれており、TCP ハンドシェイクが完了した後にのみ送信されます。言い換えると、NAT に必要な情報は、必要なときにはまだ利用できないということです。

それが不可能な場合、代替手段はありますか?

haproxyはTCP接続を終了し、ClientHelloのSNIに基づいてデータを転送することができます。プロキシでTLSを終了させる必要はありません。その後、PROXYプロトコル(基本的には転送された接続の先頭のヘッダー)を使用して、TCP接続内のクライアントの元のソースIPを転送できます。上流サーバーがPROXYプロトコル自体を理解していない場合は、次のようなソフトウェアを使用できます。mmプロキシhaproxy からの接続を SNAT して、元の送信元 IP を表示します。

関連情報