これは この質問 に似ていますが、異なります:
Linuxコンピュータには2つのNICがあります。 eth0
には静的にIPが割り当てられます。 eth1は、同じIPまたは異なるIPである可能性のあるフィールドの担当者によって支援されます。計画では、eth0
とeth1
を異なるネットワーク上に配置し、パケットを交換したりブリッジしたりしないでください。そして、私のLinuxアプリケーションは、eth0
とeth1
でのみ接続をリッスンして受け入れ、受信時にパケットの送信を開始しますが、アクティビティを開始しようとはしません。
2つのNICは同じサブネットにIPを持つことができます:192.168.1.4
と192.168.1.5?ご覧のとおり、eth0
とeth1
は同じサブネットに割り当てられています(255.255.255.0
)しかし、それらは接続されておらず、接続されているはずではありません。
この場合、アプリケーションがeth0
ポート55555
でリッスンし、接続を受け入れてパケットを返すと、基盤となるレイヤーはeth0に戻る必要があることを認識していますか?または、OSが同じサブネット上にあると見なすため、eth1
を試す可能性がありますか?これらの2つのNICが実際に同じサブネット上にあると見なされないようにするために、ルーティングテーブルに対して行う必要があることはありますか?
この場合、類似したIPだけでなく、同じサブネットも避ける必要がありますか?
PC0とPC1のIPが同じ場合はどうなりますか?
PC0 (1.100) <-------> [eth0 (1.4) My System eth1 (1.5)]<-------PC1(1.100)
私のアプリケーションはeth0とeth1のポート55555でリッスンする必要があり、リクエストはeth1を介して受信され、OSはeth1を介して応答することを認識できますか?この構成は問題を引き起こしますか?
ビジネスケースは、私がこの組み込みシステムを構築していて、eth0とPC0のIPを事前に定義していることです(PC0はDHCPでもかまいません)。しかし、私の顧客はすでに右側にネットワークを持っています。 PC0またはeht0のいずれかと競合するデバイスがある場合はどうなりますか? eth0にDHCPサーバーがある場合でも、PC0にIPを割り当てるときに右側のIPを除外する方法はありません。これが問題を引き起こす場合、私には多くの解決策があります。でも、それが問題なのか、仲間の意見を聞きたいです。
私の同僚の2人は、それは問題ではないと考えています。私の意見では、IP層は、ソケットを使用してもパケットに応答するために使用するインターフェイスを認識していません(右側にバインドすると仮定します)。ルーティングテーブルをどのように設定しても、1つだけが選択されます。
おそらく、宛先ネットワークは、デフォルトゲートウェイを介して、デフォルトルート(0.0.0.0/0)内に含まれています。
私を信じないでください?
調べてみましょう:
[root@localhost ~]# ip address show label eth* | grep -v 'link\|val'
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 192.168.1.4/24 brd 192.168.1.255 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 192.168.1.5/24 brd 192.168.1.255 scope global eth1
質問のようにIPアドレスとマスクを備えた2つのインターフェースeth0とeth1。
完全なスタートアップ構成:
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE=Ethernet
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
Name="eth0"
BOOTPROTO=none
IPADDR=192.168.1.4
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE="eth1"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE=Ethernet
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
Name="eth1"
BOOTPROTO=none
IPADDR=192.168.1.5
NETMASK=255.255.255.0
GATEWAY=192.168.1.2
.1と.2ごとに異なるゲートウェイアドレスが設定されていることに注意してください。
次に、ルーティングテーブルを見てみましょう。
[root@localhost ~]# ip route list
default via 192.168.1.2 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.4
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5
なんらかの理由でデフォルトルートが1つだけ選択されているようです(わかりませんが、NICの番号が小さいためだと思います)が、ゲートウェイを使用しています。おそらく後者のゲートウェイステートメントだったからですか?私が知っているなら地獄。
カーネルが、いずれかのローカルIPアドレスから供給された特定のパブリックアドレス宛先の適切なルートをどのように考慮するかを見てみましょう。
[root@localhost ~]# ip route get to 8.8.8.8 from 192.168.1.4
8.8.8.8 from 192.168.1.4 via 192.168.1.2 dev eth0
cache
[root@localhost ~]# ip route get to 8.8.8.8 from 192.168.1.5
8.8.8.8 from 192.168.1.5 via 192.168.1.2 dev eth0
cache
「default ... dev eth0」から予想されるように、パブリックIPアドレス宛てのパケットはeth0を終了します。
送信元IPアドレスが何であるかは問題ではないことに注意してください。
でも確認してみましょう!
いずれかのインターフェイスといずれかの送信元アドレスからpingを実行している間、eth0とeth1の両方をスニッフィングします。
まず、eth0のIPアドレスを送信元として使用してpingを実行します(.4):
[root@localhost ~]# tcpdump -ni eth0 'icmp' & tcpdump -ni eth1 'icmp' & ping -nc 3 -I 192.168.1.4 8.8.8.8 2>&1 > /dev/null ; sleep 4 ; pkill tcpdump
[1] 2603
[2] 2604
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
23:30:30.347429 IP 8.8.8.8 > 192.168.1.4: ICMP echo reply, id 2605, seq 1, length 64
23:30:31.331631 IP 192.168.1.4 > 8.8.8.8: ICMP echo request, id 2605, seq 2, length 64
23:30:31.350134 IP 8.8.8.8 > 192.168.1.4: ICMP echo reply, id 2605, seq 2, length 64
23:30:32.333378 IP 192.168.1.4 > 8.8.8.8: ICMP echo request, id 2605, seq 3, length 64
23:30:32.350145 IP 8.8.8.8 > 192.168.1.4: ICMP echo reply, id 2605, seq 3, length 64
5 packets captured
5 packets received by filter
0 packets dropped by kernel
0 packets captured
0 packets received by filter
0 packets dropped by kernel
[1]- Done tcpdump -ni eth0 'icmp'
[2]+ Done tcpdump -ni eth1 'icmp'
見栄えが良い-ルーティングテーブルと一致しています!
予想どおり、eth1(2番目の要約)には何も表示されません。
ソース.5(eth1に属する)からpingを実行しましょう:
[root@localhost ~]# tcpdump -ni eth0 'icmp' & tcpdump -ni eth1 'icmp' & ping -nc 3 -I 192.168.1.5 8.8.8.8 2>&1 > /dev/null ; sleep 4 ; pkill tcpdump
[1] 2609
[2] 2610
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
23:32:31.284113 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 2611, seq 1, length 64
23:32:32.269281 IP 192.168.1.5 > 8.8.8.8: ICMP echo request, id 2611, seq 2, length 64
23:32:32.284493 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 2611, seq 2, length 64
23:32:33.270735 IP 192.168.1.5 > 8.8.8.8: ICMP echo request, id 2611, seq 3, length 64
23:32:33.286849 IP 8.8.8.8 > 192.168.1.5: ICMP echo reply, id 2611, seq 3, length 64
5 packets captured
5 packets received by filter
0 packets dropped by kernel
0 packets captured
0 packets received by filter
0 packets dropped by kernel
[1]- Done tcpdump -ni eth0 'icmp'
[2]+ Done tcpdump -ni eth1 'icmp'
Pingの送信元アドレスがeth1のIPアドレスに設定されていても、パケットがeth0を離れた方法を確認してください。
ただし、送信元アドレスではなく送信元インターフェイスからpingを実行するように指定できます。
eth0の指定は期待どおりに機能しますが(成功)、eth1をソースとして設定すると何か面白いことが起こります。
[root@localhost ~]# tcpdump -ni eth0 'icmp' & tcpdump -ni eth1 'icmp' & ping -nc 3 -I eth1 8.8.8.8 2>&1 > /dev/null ; sleep 4 ; pkill tcpdump
[1] 2751
[2] 2752
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
...何が得られますか?
まあ、私たちはICMPトラフィックをスニッフィングしているだけです。 eth1以外にはデフォルトルート(または8.8.8.8へのより具体的なルート)が存在しないため、宛先は同じブロードキャストドメインに存在すると見なされます。
つまり、送信するパケットを作成する前に、宛先のMACアドレスを取得しようとします。 MACアドレスを取得できない場合、パケットは送信されません。
[root@localhost ~]# tcpdump -eni eth1 'icmp or arp' & ping -nc 3 -I eth1 8.8.8.8 2>&1 > /dev/null ; sleep 10 ; pkill tcpdump
[5] 2759
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
00:00:26.075685 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:26.075685 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:27.075945 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:27.075945 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:27.075945 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:28.077935 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:28.077935 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
00:00:28.077935 08:00:27:48:e7:5d > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 8.8.8.8 tell 192.168.1.5, length 28
(GoogleのDNSサーバーは、私のLAN上にないのと同じように、おそらくLAN上にありません。)
大丈夫、大丈夫、大丈夫。
デフォルトルートをouteth0からouteth1に置き換えるとどうなりますか?
接続状況がミラーリングされることを期待する必要がありますよね? :
[root@localhost ~]# ip ro
default via 192.168.1.2 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.4
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5
[root@localhost ~]# ping -nc 3 -I eth0 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 192.168.1.4 eth0: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=17.5 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=15.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=15.5 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 15.547/16.331/17.526/0.864 ms
[root@localhost ~]# ping -nc 3 -I eth1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 192.168.1.5 eth1: 56(84) bytes of data.
From 192.168.1.5 icmp_seq=1 Destination Host Unreachable
From 192.168.1.5 icmp_seq=2 Destination Host Unreachable
From 192.168.1.5 icmp_seq=3 Destination Host Unreachable
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 1999ms
pipe 3
[root@localhost ~]# ip route replace default via 192.168.1.1 dev eth1
[root@localhost ~]# ip ro
default via 192.168.1.1 dev eth1
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.4
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5
[root@localhost ~]# ping -nc 3 -I eth0 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 192.168.1.4 eth0: 56(84) bytes of data.
From 192.168.1.4 icmp_seq=1 Destination Host Unreachable
From 192.168.1.4 icmp_seq=2 Destination Host Unreachable
From 192.168.1.4 icmp_seq=3 Destination Host Unreachable
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 1999ms
pipe 3
[root@localhost ~]# ping -nc 3 -I eth1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 192.168.1.5 eth1: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=14.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=18.8 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=21.0 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 14.760/18.216/21.010/2.596 ms
そしてそうです!これで、eth0はeth1以外には到達できません。
両方のインターフェースを「正しく機能」させたいと仮定して、負荷分散である狂気の道を進みましょう...:
[root@localhost ~]# ip route delete default
[root@localhost ~]# ip route add default scope global nexthop via 192.168.1.2 dev eth0 weight 1 nexthop via 192.168.1.1 dev eth1 weight 1
[root@localhost ~]# ip ro
default
nexthop via 192.168.1.2 dev eth0 weight 1
nexthop via 192.168.1.1 dev eth1 weight 1
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.4
192.168.1.0/24 dev eth1 proto kernel scope link src 192.168.1.5
しかし、それは機能しますか?
[root@localhost ~]# ping -nc 3 -I eth0 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 192.168.1.4 eth0: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=17.9 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=16.2 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=17.4 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 16.281/17.238/17.986/0.727 ms
[root@localhost ~]# ping -nc 3 -I eth1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) from 192.168.1.5 eth1: 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=16.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=54 time=17.3 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=54 time=26.0 ms
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 16.612/20.025/26.091/4.300 ms
...でも、私でも少し驚いています。
あなた自身のマイレージは異なる場合があります。私はこの狂気に反対することをお勧めします。
私のテストでは、ローカルサブネット上の宛先に到達しようとすると、状況が不安定になります。
これは、通常のシステム使用(つまり、出口インターフェースを明示的に指定しない)では、1つのインターフェースが選択されるためです。
たとえば、サブネット上に存在しないホスト(.17)にpingを実行すると、ARP要求はeth0からのみ送信されます。
理論的には、ホストdidがeth1の外に存在する場合、ARPは機能しますか?
そうではないようです:
[root@localhost ~]# ping 192.168.1.17
PING 192.168.1.17 (192.168.1.17) 56(84) bytes of data.
From 192.168.1.4 icmp_seq=1 Destination Host Unreachable
From 192.168.1.4 icmp_seq=2 Destination Host Unreachable
From 192.168.1.4 icmp_seq=3 Destination Host Unreachable
...
[root@localhost ~]# tcpdump -eni eth0 'arp'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
00:25:29.167575 08:00:27:f6:8f:c2 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.17 tell 192.168.1.4, length 28
00:25:30.168001 08:00:27:f6:8f:c2 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.17 tell 192.168.1.4, length 28
00:25:31.169967 08:00:27:f6:8f:c2 > Broadcast, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.17 tell 192.168.1.4, length 28
...
[root@localhost ~]# tcpdump -eni eth1 'arp'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
乾杯。