curl 127.0.0.1 --interface eth0を使用すると、eth0がループバックインターフェイスにアクセスできないのはなぜですか?

curl 127.0.0.1 --interface eth0を使用すると、eth0がループバックインターフェイスにアクセスできないのはなぜですか?

問題を再現する方法は次のとおりです。

  1. ポート 80 でリスニングサービスを開始します。nc -l 80 -k
  2. このサービスにアクセスするにはカールを使用してください。curl 127.0.0.1 --interface eth0
  3. eth0tcpdumpを使用して、次のパケットをloキャプチャしますtcpdump -i eth0 port 80 -nn -vtcpdump -i lo port 80 -nn -v

出力は、パケットが送信されたが応答を受け取らず、TCPクライアントが再送信制限に達するまでパケットを再送信したことをtcpdump示します。SYNeth0SYN

ただし、宛先IPを(またeth0にバインドされたローカルIP)に変更すると、アクセスが192.168.16.4成功し、tcpdump出力にパケットがありSYNますlo

ifconfig出力は次のとおりです。

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.16.4  netmask 255.255.240.0  broadcast 192.168.31.255
        inet6 fe80::f820:20ff:fe16:588c  prefixlen 64  scopeid 0x20<link>
        ether fa:20:20:16:58:8c  txqueuelen 1000  (Ethernet)
        RX packets 16248748  bytes 2161348902 (2.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15203841  bytes 4648786129 (4.3 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 4832071  bytes 2872871764 (2.6 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4832071  bytes 2872871764 (2.6 GiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ルーティングテーブルの内容は次のとおりです。

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.16.1    0.0.0.0         UG    100    0        0 eth0
169.254.169.254 192.168.16.2    255.255.255.255 UGH   100    0        0 eth0
192.168.16.0    0.0.0.0         255.255.240.0   U     100    0        0 eth0

$ ip route show table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1 
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1 
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1 
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1 
broadcast 192.168.16.0 dev eth0 proto kernel scope link src 192.168.16.4 
local 192.168.16.4 dev eth0 proto kernel scope host src 192.168.16.4 
broadcast 192.168.31.255 dev eth0 proto kernel scope link src 192.168.16.4

straceシステムコールを記録するために使用すると、オプションの意味curlが表示されます--interface eth0setsockopt(3, SOL_SOCKET, SO_BINDTODEVICE, "eth0\0", 5)

議論を見ました。https://github.com/iputils/iputils/issues/198ping -I同じように進む)とhttps://stackoverflow.com/questions/46036667/route-Between-network-interfaces-ubuntu

私は考えています:

  1. curl 127.0.0.1 --interface eth0サービスにアクセスできないのはなぜですか、SYNパケットはどうなり、いつ削除されますか?
  2. curl 192.168.16.4 --interface eth0インターフェイスを使用してlo通信するがcurl 127.0.0.1 --interface eth0使用する理由eth0
  3. 私がやりたいことは、私がやりたいことであればcurl 127.0.0.1 --interface eth0可能です。

修正する:

私が使用するLinuxカーネルのバージョンはです4.18.0。出力は次のとおりですcurl 192.168.16.4 --interface eth0tcpdump -i lo

$ tcpdump -i lo port 80 -nn
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
09:15:38.915880 IP 192.168.16.4.40850 > 192.168.16.4.80: Flags [S], seq 1020241664, win 43690, options [mss 65495,sackOK,TS val 2673572844 ecr 0,nop,wscale 7], length 0
09:15:38.915891 IP 192.168.16.4.80 > 192.168.16.4.40850: Flags [S.], seq 3808229193, ack 1020241665, win 43690, options [mss 65495,sackOK,TS val 2673572844 ecr 2673572844,nop,wscale 7], length 0
09:15:38.915900 IP 192.168.16.4.40850 > 192.168.16.4.80: Flags [.], ack 1, win 342, options [nop,nop,TS val 2673572844 ecr 2673572844], length 0
09:15:38.915928 IP 192.168.16.4.40850 > 192.168.16.4.80: Flags [P.], seq 1:77, ack 1, win 342, options [nop,nop,TS val 2673572844 ecr 2673572844], length 76: HTTP: GET / HTTP/1.1
09:15:38.915931 IP 192.168.16.4.80 > 192.168.16.4.40850: Flags [.], ack 77, win 342, options [nop,nop,TS val 2673572844 ecr 2673572844], length 0

答え1

XYの問題と非常によく似ているようですが、

システムには2つのインターフェースがあります。

  • eth0、IPアドレスは192.168.16.4
  • lo、IPアドレスは127.0.0.1です。

もちろん、このインターフェイスに直接接続されているすべてのIPアドレスは、このインターフェイスを介してアクセス可能です。の場合はeth0192.168.16.0/20 のいずれかになり、 の場合はlo127.0.0.1 のいずれかになります。

直接結合範囲に含まれないデータの場合、データは最初にゲートウェイに送信され、次にゲートウェイから宛先に追加ルーティングされます。今まではそんなに良くなった。

ただし、127.0.0.0/8はループバックネットワーク用に予約されています。ルータはもはやルーティングしません。したがって、ゲートウェイに送信してもルーティングされなくなります。

ルータがさらにルーティングしてもインターフェイスにアクセスできませんlo。の場合eth0、ルーターに接続したケーブルを介してルーターにアクセスできます。あなたのインターフェースにはそのようなアクセス権がありませんlo。ローカルシステムからのみアクセスできます。

したがって、あなたの質問に:

  • サービスにアクセスできないのはなぜですかcurl 127.0.0.1 --interface eth0、SYNパケットはどうなり、いつ破棄されますか?

削除される場所はオペレーティングシステムによって異なります。しかし、それは玄関口よりも遠くはありません。

  • curl 192.168.16.4 --interface eth0インターフェイスを使用してlo通信するがcurl 127.0.0.1 --interface eth0使用する理由eth0

これは決して起こらないでしょう。curl 192.168.16.4 --interface eth0使用しないでくださいlo

  • 私がやりたいことは、私がやりたいことであればcurl 127.0.0.1 --interface eth0可能です。

カーネルパッチを実行している場合は、systemdそこにもパッチを適用してください。curl大丈夫でしょう。また、ルーターにカスタムソフトウェアをインストールする必要があります。システムでルーティングを有効にする必要があります(もちろん、カーネルパッチと上記の修正バージョンが適用されますzebra)。私のアドバイス:それについて考えてもしないでください。なぜこれを試みたいか真剣に再評価しなさい。

サプリメントとして、サプリメントとして

ただし、curl 192.168.16.4 --interface eth0 は lo インタフェースを使用します。

本機で見られる内容はsystemd次のとおりです(使用curl dullaart.website)。

07:41:06.008577 IP localhost.domain > localhost.45840: 6127 1/0/0 PTR localhost. (64)
07:41:12.433744 IP localhost.52411 > localhost.domain: 39930+ A? dullaart.website. (34)
07:41:12.433795 IP localhost.52411 > localhost.domain: 49165+ AAAA? dullaart.website. (34)
07:41:12.550329 IP localhost.domain > localhost.52411: 39930 1/0/0 A 212.1.212.17 (50)
07:41:12.582833 IP localhost.domain > localhost.52411: 49165 0/0/0 (34)

/etc/resolve.confこれは、次に指定されたサーバーで実行される名前解決です。

nameserver 127.0.0.53

ループバックネットワークにあります。

質問の結果のように自分のシステムに移動すると、一部(すべてではない)がショートカットloとして使用されることがあります。curlこれは、カーネルが両方のインタフェースの背後に同じシステムがあることを知っているので可能です。したがって、ターゲットが自分のシステムの場合にのみ使用できますcurllo

関連情報