TLS クライアント Hello の SNI 拡張機能のサーバ名に基づいて、レイヤー 4 アプリケーションのロード バランシングを行うことが可能です。DataScript は、TLS ペイロードを検査するのに十分なバイト数を取得してから呼び出されるようにします。ロード バランシングが完了すると、同じ接続内の後続のパケットに対する DataScript の呼び出しが停止します。
NSX Advanced Load Balancer ユーザー インターフェイスを使用して構成するには、次の手順を実行します。
手順
- の順に移動します。
- [作成] をクリックします。[新しい DataScript セット] ウィンドウが表示されます。[名前] の値を入力します。
- 下にスクロールして、[L4 イベント] フィールドを表示します。ファイルをインポートするには、[ファイルのインポート] ボタンをクリックします。また、[説明] フィールドに説明を指定することもできます。
- [プロトコル パーサー] フィールドで、ドロップダウン メニューから [デフォルト TLS] を選択します。そのパーサを DataScript に接続して、スクリプトが TLS 解析機能と API 呼び出しを使用できるようにする必要があります。
- [保存] をクリックします。
例: サンプルの DataScript
Default-TLS
プロトコル パーサを選択する必要があります。この DataScript を仮想サービスに関連付けることで、クライアントからの最初の TLS パケット(理想的にはクライアント Hello)が DataScript によって検査されます。
local avi_tls = require "Default-TLS" -- Buffer minimum of 20 bytes of data buffered = avi.l4.collect(20) -- Read the gathered payload payload = avi.l4.read() -- Obtain the length of the payload len = avi_tls.get_req_buffer_size(payload) if ( buffered < len ) then -- Wait till len bytes are collected at TCP layer avi.l4.collect(len) end -- Verify if client hello and handshake. if ( avi_tls.sanity_check(payload) ) then -- Parse the TLS payload local h = avi_tls.parse_record(payload) -- Obtain the SNI name local sname = avi_tls.get_sni(h) if sname == nil then avi.vs.log('SNI not present') avi.vs.close_conn() else avi.vs.log("SNI=".. sname) avi.vs.persist(sname) end else avi.vs.close_conn() end -- Stop invoking DataScript after the first payload. avi.l4.ds_done() avi_tls = nil
たとえば、SNI 名は TLS ペイロードを解析することによって取得されます。
avi_tls.parse_record
はペイロードを解析し、ヘルパー API avi_tls.get_sni(h)
を使用して SNI 名を取得します。この SNI 名を使用して、プール サーバまたはロード バランシングを選択し、そのパーシステンス エントリを作成できるようになりました。または、これを使用して、avi.pool.select("pool_name")
を使用して特定のプールを選択することもできます。
注:
プール名と SNI 名を同じにする必要はありません。ただし、特定の使用事例では、SNI 名をプール名と同じにして、SNI 名に基づいてプールを選択できます。