Вопрос или проблема
На системе FreeBSD с интерфейсом петлевого устройства …
% ifconfig lo0 lo0 link up loopback drv_running running multicast nd6 performnud auto_linklocal no_radr link rxcsum txcsum hwcsum rxcsum_ipv6 txcsum_ipv6 link address metric 0 mtu 16384 type 24 linkstate 0 physical 0 baudrate 0 inet4 address 127.0.0.1 prefixlen 8 bdaddr 127.0.0.1 inet6 address ::1 scope 0 prefixlen 128 bdaddr ::1 scope 0 inet6 address fe80::1 scope 3 prefixlen 64 inet6 address ::2 scope 0 prefixlen 128 inet4 address 127.53.0.1 prefixlen 8 bdaddr 127.53.0.1 inet4 address 127.53.1.1 prefixlen 8 bdaddr 127.53.1.1 %
… пингование IP-адреса 127.0.0.2, который не назначен этому (или любому другому) сетевому интерфейсу, приводит к ошибке:
% ping -c 1 127.0.0.2 PING 127.0.0.2 (127.0.0.2): 56 data bytes ping: sendto: Network is unreachable --- 127.0.0.2 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss %
То же самое верно для OpenBSD:
% ping -c 1 127.0.0.2 PING 127.0.0.2 (127.0.0.2): 56 data bytes ping: sendto: Network is unreachable ping: wrote 127.0.0.2 64 chars, ret=-1 --- 127.0.0.2 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss %
Но на Linux, где также не настроен адрес 127.0.0.2 …
% ifconfig lo lo link up loopback running link address 00:00:00:00:00:00 bdaddr 00:00:00:00:00:00 inet4 address 127.0.0.1 prefixlen 8 bdaddr 127.0.0.1 inet4 address 127.53.0.1 prefixlen 8 bdaddr 127.255.255.255 inet6 address ::2 scope 0 prefixlen 128 inet6 address fe80:: scope 1 prefixlen 10 inet6 address ::1 scope 0 prefixlen 128 %
… пинг неожиданно успешен:
% ping -c 1 127.0.0.2 PING 127.0.0.2 (127.0.0.2) 56(84) bytes of data. 64 bytes from 127.0.0.2: icmp_seq=1 ttl=64 time=0.044 ms --- 127.0.0.2 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.044/0.044/0.044/0.000 ms %
Как так?
Связанные вопросы
- “Когда IP-адресу не нужно быть назначенным сетевому интерфейсу?” — очень обходной вопрос, запрашивающий объяснение “виртуальных интерфейсов”, на который данный вопрос отвечает прямо
- “Как возможно успешно пинговать все 127.0.0.0/8?” — несколько вопросов в одном, а не по одному вопросу на вопрос, и фактически не отвечает на предполагаемый дубликат
- “почему такое поведение в Linux Network через интерфейс петлевого устройства” — вопрос о том, почему в Linux интерфейс
lo
кажется также контролирует пингование IP-адресов, назначенных другим сетевым интерфейсам (поведение, аналогично не то, что получают на BSD) - “Что происходит с локальным LAN-трафиком на linux для не-петлевых адресов?” — вопрос о не-петлевом поведении
Другие ссылки
- Джонатан де Бойне Поллард (2019).
ifconfig
. Руководство по nosh. Программы.
ip-route
используется для управления записями в таблицах маршрутизации ядра.Типы маршрутов:
unicast
– запись маршрута описывает реальные пути к пунктам назначения, покрываемые префиксом маршрута.…
local
– пункты назначения назначены этому хосту. Пакеты
замыкаются и доставляются локально.
$ ip -4 route show table all type local
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
local 172.16.8.139 dev wlp2s0 table local proto kernel scope host src 172.16.8.139
local 192.168.122.1 dev virbr0 table local proto kernel scope host src 192.168.122.1
$ ip -4 address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
4: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 172.16.8.139/24 brd 172.16.8.255 scope global dynamic noprefixroute wlp2s0
valid_lft 36391sec preferred_lft 36391sec
5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
Когда адрес добавляется к интерфейсу, для адреса автоматически добавляется локальный маршрут. Кроме того, когда адрес добавляется к интерфейсу петлевого устройства (IFF_LOOPBACK
), для сетевого префикса адреса добавляется локальный маршрут. В Linux 5.0 это можно найти в реализации fib_add_ifaddr().
В отличие от этого, когда адрес добавляется к не-петлевому интерфейсу, для сетевого префикса добавляется unicast маршрут.
$ ip -4 route show table all type unicast
default via 172.16.8.1 dev wlp2s0 proto dhcp metric 600
172.16.8.0/24 dev wlp2s0 proto kernel scope link src 172.16.8.139 metric 600
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
Локальные маршруты добавляются в специальную таблицу, называемую “local”. Наиболее очевидное значение этого заключается в том, что быстрый ip -4 route
не покажет локальную таблицу. Это потому, что он эквивалентен ip -4 route show table main
.
linux-ip.net предоставляет некоторую более широкую информацию. Он упоминает еще два использования локальной таблицы.
Вышеописанное, вероятно, применимо ко всем версиям Linux, с которыми вы столкнетесь. Я не уверен, насколько далеко это заходит в прошлое. Однако команда ip route
уже древняя; она существует, по крайней мере, со времен Linux 2.2.
Ключевым является RFC 5735 и, в частности, раздел 3 Global and Other Specialized Address Blocks, в котором говорится:
127.0.0.0/8
– Этот блок назначен для использования в качестве адреса петлевого устройства Интернет-хоста. Датаграмма, отправленная протоколом более высокого уровня на адрес в пределах этого блока, замыкается внутри хоста. Это обычно реализуется с использованием только127.0.0.1/32
для петлевого устройства.
Обратите внимание, что в последнем предложении используется слово “обычно“. Я бы предположил, что это позволяет различному поведению, которое демонстрируют две системы BSD и система на основе Linux, быть обеими допустимыми.
Согласно стандартам, весь диапазон IP-адресов 127.*.*.*
относится к localhost
. См. RFC0791, STD005 (https://datatracker.ietf.org/doc/html/rfc791)
.
Ответ или решение
Вопрос о том, почему в Linux можно успешно отправить ping на IP-адрес 127.0.0.2, в то время как аналогичные попытки на FreeBSD и OpenBSD приводят к ошибкам, связан с особенностями того, как разные операционные системы обрабатывают IP-адреса в диапазоне 127.0.0.0/8. Данная ситуация объясняется различиями в реализации и интерпретации сетевых стандартов, а также конфигурацией маршрутизации в системах.
Теория
RFC 5735 описывает блок IP-адресов 127.0.0.0/8 как зарезервированный для служебных loopback-адресов. Пакеты, отправленные на любой адрес из данного диапазона, должны возвращаться обратно на машину-отправителя без их физической отправки в сетевую среду. Обычно используется только 127.0.0.1 для обозначения интерфейса loopback, но сетевая спецификация допускает использование других адресов из этого диапазона, хотя и имеет ремарку об «обычном использовании».
На FreeBSD и OpenBSD наблюдается строгая интерпретация стандарта, где используется конкретно адрес 127.0.0.1, в то время как Linux демонстрирует более гибкий подход. В Linux вся сеть 127.0.0.0/8 рассматривается как относящаяся к loopback-интерфейсу. Это поведение обусловлено особенностями обработки локальных маршрутов в ядре Linux.
Пример
В FreeBSD при попытке отправить ping на 127.0.0.2 система возвращает ошибку «Network is unreachable», что свидетельствует о том, что этот адрес не распознан как часть маршрутизируемой сети loopback. Аналогичная реакция наблюдается и в OpenBSD.
Первый раз команда ifconfig
показывает, что настроен только адрес 127.0.0.1 на loopback-интерфейсе (lo0), и другие адреса из диапазона 127.0.0.0/8 не считаются частью loopback. Сама конфигурация этого интерфейса не предполагает маршрутизации других адресов этого сегмента.
В Linux команда ifconfig lo
также показывает назначенный адрес 127.0.0.1. Однако при отправке ping на 127.0.0.2 пинг проходит успешно. Это связано с тем, как система Linux обрабатывает маршрутизацию локальных IP-адресов.
Применение
В Linux при добавлении адреса на loopback-интерфейс автоматически создается локальный маршрут для целой сети, к которой этот адрес принадлежит. Таким образом, в Linux, если вы настроили 127.0.0.1 с маской 255.0.0.0 на loopback-интерфейсе, вся сеть 127.0.0.0/8 работает как локальная сеть. Это объясняет возможность успешного пингования адресов, которые технически не назначены ни на один интерфейс, но остаются частью этой сети.
Если рассматривать это с точки зрения маршрутизации, команда ip -4 route show table all type local
показывает, что сеть 127.0.0.0/8 действительно связана с интерфейсом lo, что поддерживает возможность успешной доставки пакетов внутри этой сети, независимо от назначения конкретных IP-адресов.
Заключение
Таким образом, разница между тем, как FreeBSD/OpenBSD и Linux обрабатывают адреса loopback, связана с разной реализацией стандартов и интерпретацией спецификаций RFC. Linux применяет более широкий подход, позволяя всей сети 127.0.0.0/8 функционировать как локальной. Понимание этих различий важно для администраторов систем, которые занимаются настройкой сетевых интерфейсов и маршрутизацией. Правильное использование этих функций может повысить надежность и функциональность сетевых конфигураций в зависимости от нужд бизнеса и условий работы.