(詳細に入る前に、例としてApacheとSSHでこの問題を提示しますが、これはTCPトラフィックに固有のものではなく、両方のTCPおよびUDPベースのプロトコル。)
Ubuntu 9.04を実行しているマルチリンクされたマルチホームサーバーがあり、eth0はoutsideネットワークに接続され、eth1はinsideネットワークに接続されています。外部ネットワークは「世界の残りの部分」に提示され、内部ネットワークにはすべての開発者ワークステーションと主力サーバーが含まれます。 「その他の国」から内部ネットワークへのトラフィックをブロックするファイアウォールがありますが、発信要求はブロックしません。
$ /sbin/ifconfig
eth0 Link encap:Ethernet HWaddr 00:30:18:a5:62:63
inet addr:xxx.yyy.159.36 Bcast:xxx.yyy.159.47 Mask:255.255.255.240
[snip]
eth1 Link encap:Ethernet HWaddr 00:02:b3:bd:03:29
inet addr:xxx.zzz.109.65 Bcast:xxx.zzz.109.255 Mask:255.255.255.0
[snip]
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
xxx.yyy.159.32 0.0.0.0 255.255.255.240 U 0 0 0 eth0
xxx.zzz.109.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
0.0.0.0 xxx.yyy.159.33 0.0.0.0 UG 100 0 0 eth0
Apacheはポート80でリッスンしており、sshdは22でリッスンしています。
$ netstat --tcp -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:www *:* LISTEN
tcp 0 0 *:ssh *:* LISTEN
[snip]
内部の開発マシンxxx.zzz.109.40から、内部アドレスに接続でき、すべて問題ありません。外部から外部アドレスに接続でき、すべてが正常に機能します。
しかし、ある種のテストでは、開発マシンから外部アドレスに接続したいのですが、サーバーは接続要求を拒否しています。ルーティングテーブルを調べており、受信データはeth1にあるはずのアドレスから送信されているが、おそらくセキュリティ上の予防措置として、eth0に到着しているためにドロップしていると推測しています。
この制限を緩和する方法はありますか?
奇妙なことに、これは以前は8.04で機能していましたが、8.10または9.04では機能しないため、昨年のある時点でカーネルが追加のチェックを行っています。接続が機能するためには、リターンパスがソースパスと同じである必要があります。つまり、eth0に到着した開発マシンからのメッセージは、eth0に戻って、マシンにルーティングされる必要があります。
これが図です。NATどこにもありません。
これを防ぐiptablesルールがないと仮定すると、リターンパスフィルタリングを無効にする必要があります。これは、次を使用して実行できます。
# echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
すべての代わりに特定のインターフェース名を使用することもできます。また、新しく作成されたインターフェースに影響を与えるデフォルトもあります。
から:
リバースパスフィルター;これは、インターフェイスに到着したパケットの場合、元のパケットの送信元アドレスに送信されたパケットがそのインターフェイスで送信されるかどうかを確認するためのチェックです。そうでない場合、到着したパケットはドロップされます。これは、スプーフィングされた送信元アドレスを持つパケットを検出する試みと見なすことができます。
肛門であるために、私は上記のネットワーク構成をマルチホームとは呼びません。同じAS内の2つのネットワーク間で転送するだけです。最近のマルチホームとは、実際には、2つ以上のネイバー(AS)に接続すること、または単一のアップストリーム接続プロバイダーを持つリーフネットワークの場合は同じアップストリームネイバー(AS)に少なくとも複数のルートを接続することを意味します。
すでに与えられた多くの有用なアイデア。 a)ファイアウォール/ NATではないことを再確認します。 REJECTルールとDROPルールの前に-jLOGルールを追加し、疑わしいものが検出されないかどうかを確認します。 b)両方のインターフェイス(-i any)でtcpdumpを実行し、パケットを探します。
ところで、「サーバーが接続要求を拒否している」とはどういう意味ですか? (即時の)拒否メッセージが表示されますか、それとも接続がタイムアウトしますか?
Iptablesを使用してインターネットNATルーターとしてそのボックスを使用していると思いますNAT-明らかにそうでない場合、これは役に立ちません。そうでない場合は、おそらく何かが必要になりますお気に入り:
iptables -t nat -I POSTROUTING -s xxx.zzz.109.0/24 -d xxx.yyy.159.36 -j ACCEPT
これにより、そのサーバーの外部IP宛てのパケットに対して、内部から外部に移動するパケットに対して行っているソースナッティングがスキップされます。
これはファイアウォールルールの問題である必要があります。ボックス自体の外部IPが「すべての外部トラフィック」に集中している可能性が高いため、内部クライアントへの復帰が許可されていません。そのIPアドレスのファイアウォールルールに例外を設定してみてください。つまり、Webサーバーの外部IPアドレスがトラフィックを内部ネットワークに送信することを明示的に許可します。
より多くのデバッグを行うには、ファイアウォールルールを投稿する必要があります。
ファイアウォールの構成は表示されていませんが、内部から外部IPアドレスへの接続をフィルタリングすることで不利なことをしているルールがあるに違いありません。ひどく台無しにされたNAT configにも問題がある可能性がありますが、通常の構成の試みの結果として非常に病的なものを想像するのに苦労しています。
1つのポイントも明確にするために、パケットが別のインターフェイスのIPアドレスにアドレス指定された1つのインターフェイスから送信されたからといって、カーネルが拒否することはありませんnotそのパケット。何が起こっていても、それはカーネルのせいではありません。
また、トラフィックのtcpdump(サーバーの内部インターフェイスと外部インターフェイスの両方、およびクライアント上)は診断上有用です。
開発マシンのデフォルトゲートウェイは何ですか?レイヤ3スイッチ/ルーターを想定したデフォルトゲートウェイは、サーバーの他のインターフェイスに到達する方法を知っている必要があります。
あなたは次のようなものを持っている必要があります
ip route xxx.yyy.159.36 netmask 255.255.255.240 gw xxx.zzz.109.65
これでうまくいくはずです。ただし、これでは不十分な場合は、を使用してマシンxxx.zzz.109.65でIP転送を有効にします。
sysctl net.ipv4.ip_forward = 1
また、/ etc/sysctl.confを編集して、そこでもip転送を有効にします。
Xxx.zzz.109.65のフィルターテーブルのiptablesFORWARDチェーンで、開発マシンのパケット転送が許可されていることを確認してください。