Anti-DDoS Proxy のような FullNAT シナリオでは、クライアントアドレスは FullNAT ノードのアドレスに変換されます。Alibaba Cloud Linux 3 (カーネルバージョン 5.10.134-15 以降) に vtoa がインストールされたバックエンドサーバーは、TCP Option Address (TOA) を使用して、getsockopt または getpeername を呼び出すことで、実際のクライアントアドレスを取得できます。これは IPv4 と IPv6 の両方をサポートします。
制限事項
システム要件:Alibaba Cloud Linux 3、カーネルバージョン 5.10.134-15 以降。
uname -r コマンドを実行して、イメージのカーネルバージョンを確認します。
利用シーン
Anti-DDoS Proxy:ユーザーリクエストは、図中の Anti-DDoS ノードである転送ノードでアドレス変換 (FullNAT) を受けます。Anti-DDoS は TOA メカニズムを有効にします。実際のクライアント IP アドレスとポート情報を TCP オプションに配置し、バックエンドのオリジンサーバーに渡します。その後、バックエンドのオリジンサーバーは
vtoaを使用して実際のクライアント IP アドレスを取得します。
CDN アクセラレーション:サービスリクエストは CDN アクセラレーションノードによってオリジンサーバーに転送されます。オリジンサーバーは
vtoaを使用して実際のクライアントアドレスを取得できます。
インストールと構成
vtoa は getpeername システムコールの戻り値を変更します。これにより、以下の脅威が発生します。この機能が必要であることを確認した上で、インストールしてください:
Cilium などの他のネットワークコンポーネントが eBPF のようなメソッドを使用して
getpeernameの結果を変更する場合、vtoaと競合して異常な動作を引き起こす可能性があります。アプリケーションが
getpeernameに依存している場合、その動作が影響を受ける可能性があります。
インストールとアンインストール
インストール
sudo yum install vtoa -yアンインストール
sudo yum remove vtoa -y
インストール後、vtoa はすぐに有効になり、デフォルトでシステム起動時に自動的に起動するように設定されます。アンインストール後、vtoa 機能は無効になります。
vtoa の構成
インストール後、vtoa はすぐに有効になり、デフォルトでシステム起動時に自動的に起動するように設定されます。通常、vtoa を手動で構成する必要はありません。
vtoa の起動
sudo systemctl start vtoavtoa の停止
sudo systemctl stop vtoaシステム起動時の vtoa の自動起動を有効化
sudo systemctl enable vtoaシステム起動時の vtoa の自動起動を無効化
sudo systemctl disable vtoavtoa のステータス確認
systemctl status vtoa
実際のクライアントアドレスの取得
vtoa を有効にすると、getsockopt または getpeername システムコールを使用して実際のクライアントアドレスを取得できます。
(推奨) getsockopt 呼び出しの使用
これにはカーネルバージョン 5.10.134-17 以降が必要です。uname -r コマンドを実行してカーネルバージョンを確認できます。
vtoa は、実際のクライアントアドレスを取得するための新しい optname を提供します。その静的フィールドは 1348 です。以下の C コードは一例です。
struct sockaddr caddr;
int optlen = sizeof(caddr);
int optname = 1348;
getsockopt(fd, IPPROTO_IP, optname, &caddr, &optlen);
// caddr.sa_family は AF_INET または AF_INET6 になり、それぞれ IPv4 と IPv6 アドレスに対応します。getpeername 呼び出しの使用
この機能は Alibaba Cloud Linux 3 (カーネルバージョン 5.10.134-15 以降) でサポートされています。将来的に非推奨になる可能性があります。
vtoa を有効にすると、実際のクライアントアドレス情報が返されます。以下の C コードは一例です。
struct sockaddr caddr;
int caddr_len = sizeof(caddr);
getpeername(fd, &caddr, &caddr_len);
// caddr.sa_family は AF_INET または AF_INET6 になり、それぞれ IPv4 と IPv6 アドレスに対応します。
// accept() を使用しても同様の方法でクライアントアドレスを取得できます。よくある質問
サポートされる TOA オプションフォーマット
vtoa が解析するアドレス情報は TCP option に含まれます。このオプションは特定のフォーマット要件を満たす必要があります。TCP option がフォーマット要件を満たさない場合、vtoa はそれを無視します。これはアプリケーションに影響を与えず、vtoa が無効になっている場合と同等です。
TOA (opcode = 254)
opsize = 8、
ip/portはネットワークバイトオーダーです0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | opcode | opsize | port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ip | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+TOA_V6 (opcode = 253)
opsize = 20、
ip/portはネットワークバイトオーダーです0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | opcode | opsize | port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + + | | + ip + | | + + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
コンテナーシナリオでの vtoa の有効化
vtoa はコンテナーレベルの隔離をサポートしていません。
ACK containerd ランタイムなどの一般的なコンテナーシナリオでは、ホストに vtoa をインストールします。これにより、ノード上のすべてのコンテナーに対して有効になります。したがって、コンテナー内ではなく、ホストに vtoa をインストールしてください。