症状
複数のネットワークインターフェースコントローラー (NIC) や、LVS ロードバランシング、オーバーレイネットワーク、非対称ルートなどを使用する複雑なネットワークルーティング環境では、以下の問題が発生することがあります。
サービスアクセスの問題:Server Load Balancer (SLB) 経由でバックエンドサーバーにアクセスすると、ヘルスチェックが失敗したり、サービスへのアクセスがブロックされたりすることがあります。しかし、バックエンドサーバーに直接ログインすると、サービスポートには正常にアクセスできます。
ネットワーク接続のタイムアウト:複数の NIC またはポリシーベースルーティングが設定された ECS インスタンスで、一部の方向へのネットワーク接続が断続的にタイムアウトしたり、完全に失敗したりします。
システムのパケット損失:
tcpdumpなどのツールを使用してパケットをキャプチャすると、データグラムが NIC に到達しているにもかかわらず、アプリケーション層がデータを受信していないことが観測される場合があります。
原因
この問題は通常、非対称ルート環境でカーネルパラメーター rp_filter がストリクトモード (値 1) に設定されている場合に発生します。非対称ルートとは、データグラムの受信パスと送信パスが異なることを意味します。rp_filter のストリクトモードが有効になっている場合、カーネルは受信した各パケットに対して逆方向パス検証を実行します。パケットの受信 NIC が、システムのルートテーブルにおける最適な送信インターフェースでない場合、そのパケットは破棄されます。
原因 1:複数の NIC またはポリシーベースルーティングによる非対称ルート:複数の NIC を持つ ECS インスタンスでポリシーベースルーティングが設定されている場合、パケットが
eth0NIC から受信されても、その応答パケットはルーティングポリシーに基づいてeth1NIC から送信されることがあります。この場合、rp_filterのストリクトモードはパケットパスを無効とみなし、パケットを破棄します。原因 2:ロードバランシング (LVS-DR モード) による非対称ルート:Classic Load Balancer (CLB) などの Alibaba Cloud ロードバランサーでレイヤー 4 (TCP/UDP) リスナーを使用する場合、バックエンドサーバーはデフォルトでダイレクトルーティング (DR) モードを使用します。このモードでは、クライアントのリクエストパケットは LVS を経由してバックエンドの ECS インスタンスに到達しますが、ECS インスタンスからの応答パケットは LVS をバイパスして直接クライアントに返されます。これは、ECS インスタンスにとって典型的な非対称ルートのシナリオです。ECS インスタンスで
rp_filterのストリクトモードが有効になっている場合、LVS からのリクエストパケットは破棄されます。
ソリューション
方法 1:ルースモードへの設定 (推奨)
rp_filter をルースモード (値 2) に設定します。カーネルは、送信元 IP アドレスがルートテーブルに存在し、到達可能であるかどうかのみをチェックします。受信 NIC が最適な送信インターフェースである必要はありません。この方法は、すべての非対称ルートのシナリオに適しています。
カーネルパラメーターを一時的に変更して、変更を即座に適用します。
# すべての NIC の rp_filter モードをルースモードに設定 echo 2 > /proc/sys/net/ipv4/conf/all/rp_filter echo 2 > /proc/sys/net/ipv4/conf/default/rp_filterサービスが回復したかどうかをテストします。問題が解決した場合は、次の手順に進み、変更を永続化します。
/etc/sysctl.confファイルを編集します。システム再起動後も設定が維持されるように、以下の設定を追加または変更します。# 設定ファイルを編集 vi /etc/sysctl.conf # 以下の 2 行を追加または変更 net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.rp_filter = 2sysctl -pコマンドを実行して、永続的な設定を適用します。sudo sysctl -p
方法 2:特定の NIC での検証の無効化
LVS からのトラフィックを受信する NIC が eth0 など特定のものだけである場合は、その NIC のみで逆方向パス検証を無効にします。
eth0NIC のrp_filterを一時的に無効にします。echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filterサービスが回復したかどうかをテストします。問題が解決した場合は、次の手順に進み、変更を永続化します。
/etc/sysctl.confファイルを編集します。以下の設定を追加または変更します。# 設定ファイルを編集 vi /etc/sysctl.conf # 以下の行を追加または変更 net.ipv4.conf.eth0.rp_filter = 0sysctl -pコマンドを実行して、永続的な設定を適用します。sudo sysctl -p
方法 3:検証のグローバルな無効化
この方法は逆方向パス検証を完全に無効にするため、システムが IP スプーフィング攻撃のリスクにさらされます。
カーネルパラメーターを一時的に変更します。
# 警告:この操作はシステムのセキュリティを低下させます。注意して使用してください。 echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter echo 0 > /proc/sys/net/ipv4/conf/default/rp_filterサービスが回復したかどうかをテストします。問題が解決した場合は、次の手順に進み、変更を永続化します。
/etc/sysctl.confファイルを編集します。以下の設定を追加または変更します。# 設定ファイルを編集 vi /etc/sysctl.conf # 警告:以下の設定は、サーバーを IP スプーフィング攻撃のリスクにさらします。 net.ipv4.conf.all.rp_filter = 0 net.ipv4.conf.default.rp_filter = 0sysctl -pコマンドを実行して、永続的な設定を適用します。sudo sysctl -p
推奨事項
最小権限の原則に従う:rp_filter パラメーターを調整する際は、影響範囲が最小限のソリューションを優先してください。例えば、機能を完全に無効にする (rp_filter=0) よりも、ルースモード (rp_filter=2) を使用する方が望ましいです。また、グローバル設定を変更するよりも、単一の NIC の設定を変更する方が望ましいです。