OpenSSL の AES-NI とカーネルオフロード:必要なのはどちらか
CPU 命令のサポートと、パケットが処理される場所を切り分けます。調整の前に、暗号バックエンド、合意された暗号方式、実際の経路を確認してください。
二つのラベルが同じもののように使われています。ハードウェアによる高速化と、カーネルへのオフロードです。前者はライブラリの AES ルーチンがどの命令を実行するかを示し、後者はパケット処理がどこで行われるかを示します。VPN は前者だけを持つことも、後者だけを持つことも、両方を持つこともできます。性能について何かを決めるなら、まずどちらを変えようとしているのかを名指しするところから始める必要があります。
軸は二つ、点数は一つではない
第一の軸は実装です。AES-256-GCM を行うコードが、プロセッサ固有の命令を使う版に振り分けられているのか、それとも通常の演算として実行する移植性のあるルーチンに振り分けられているのか。この選択は暗号ライブラリの内部にあり、初期化の時点で決まります。
第二の軸は配置です。パケットがカーネルの変換経路を通るのか、それともユーザー空間のデーモンがトンネルデバイスから読み、暗号化して書き戻すのか。
どちらの軸も他方を制約しません。AES 命令を持つ CPU 上のユーザー空間 VPN は、その命令をずっと使っている可能性があります。逆に、それを持たない CPU 上のカーネル経路はソフトウェア実装に戻ります。ベンダーの資料のラベルはこの区別をほとんど示さないため、二つの状況の間でコピーされた調整の助言が何の効果も生まないことがよくあります。
第一の軸:どのコードが暗号化を行うか
OpenSSL は初期化の際にプロセッサの機能を検出し、その結果を使って最適化されたコード経路を選びます。これは x86 の機能に関する文書 が説明しているとおりです。AES-NI はその振り分けの背後にある文書化された機能の一つです。このどれも、ライブラリがカーネルの構成要素になることを要求しません。
高速な経路が使われていると決めつける前に、その機能がプロセスから見えることを確認してください。Linux では /proc/cpuinfo の flags フィールドが情報源であり、ゲストの内部ではハイパーバイザーが公開している内容を反映していて、物理ホストのモデル名ではありません。
grep -m1 '^flags' /proc/cpuinfo | grep -o '\baes\b'
openssl list -providers -verbose二番目のコマンドは、そのビルドで読み込まれたプロバイダを示します。VPN サービスがどのライブラリにリンクしているかは分かりませんし、一つのホストに二つの OpenSSL が入っていて、実行中のプロセスがそのうち一つだけを使うこともあります。
第二の軸:パケット経路がどこで動くか
カーネルへの配置とは、変換がカーネル自身の IPsec 機構の中で、あるいはカーネル内のトンネルドライバの中で行われるということです。そのためパケットは、まとまりごとにユーザー空間のプロセスを往復する必要がありません。これによりコピーやコンテキストスイッチを減らせ、単一スレッドのデーモンにはできない形で作業をコアに分散できます。一方で、スループットが落ちたときに読むカウンタやトレースも移ります。作業が、自分では制御できない境界の向こう側で起きるようになるからです。これは性能の判断だけでなく、デバッグのコストとして捉えてください。
命令のサポートを作るわけでも、暗号方式を設定するわけでも、既存の経路を動くようにするわけでもありません。
仮想化はこの軸にもしわを寄せます。ホストが持つ機能を隠したマスク済みの CPU モデルがゲストに渡されることがあり、入れ子のゲストはさらに少なくしか見えないことがあります。機能の見え方は、VPN が実際に動いている環境の内側から読んでください。ハイパーバイザーのコンソールからではありません。
それぞれの選択が何を買い、何ができないか
実際の問いは、時間がどこへ消えているかです。一つのビジーなスレッド、繰り返されるバッファのコピー、パケットごとのシステムコールがスループットを制限しているなら、それらのコストを取り除く経路へ変換を移すことは助けになります。ただしカーネルが必要な変換を実装している場合に限ります。
制限が、混雑した上り回線、損失のある経路、長い往復時間、飽和した宛先サービス、一つのコアに固定されたスレッドのいずれかなら、配置を変えても重要なことは変わりません。命令の選択も同じです。専用ハードウェア上の AES は欠けた経路を直せませんし、名前解決の失敗でトンネルが遊んでいるなら役に立ちません。
両方が当てはまる場所では、両者は組み合わさります。カーネル経路はカーネルの暗号 API の内部で同じ命令レベルの振り分けを使えますし、よく選ばれたライブラリを使うユーザー空間の経路はすでにそれを使っています。判断すべきは、抽象的にどちらが速いかではなく、どのコストについて証拠があるかです。
何かを変える前に四つの事実を記録する
サービスのバイナリと、それがリンクしている暗号ライブラリを書き留めてください。この二つが第一の軸を決めるからです。次に、合意されたデータ保護を記録します。専用の命令経路を持たない暗号は、持つものとは振る舞いが異なり、その組み合わせは双方が選ぶからです。
続いて、実行中の環境の内側から見た機能の見え方、そして最後に、有効だと思っているモードが本当に有効であるという証拠を伴う実際のパケット経路です。読み込まれたモジュールは、あるプロファイルがそれを使っている証拠にはなりません。設定行も、カーネルがそれを受け入れた証拠にはなりません。
一つだけ変えて、同じ端点と同じ転送方向の一貫した負荷と比べてください。測っていない速度の主張は、バックエンドが疑われたことは一度もないというメモよりも価値が低いのです。