От понятий к наблюдениям
В прошлом уроке мы разобрали, что такое IP-адрес, префикс, маршрут по умолчанию и порты. Теперь у нас появилась база, чтобы начать смотреть на сеть. Но смотреть на сеть — это не значит запомнить список команд и по очереди запускать их. Это значит уметь задавать вопросы: какой у меня адрес? Куда уходят пакеты? Слушает ли кто-нибудь порт? Отвечает ли удалённая программа?
Каждая команда в этом уроке — один из таких вопросов. Мы будем двигаться от самой машины наружу: сначала посмотрим на собственные сетевые интерфейсы, потом на маршруты, потом на слушающие программы, и только в конце попробуем достучаться до внешнего адреса. Такая последовательность не случайна. Если внешний доступ не работает, сначала нужно убедиться, что наша машина вообще подключена к сети и знает, куда отправлять пакеты.
Команды просмотра не меняют настройки сети. ping и curl дополнительно отправляют запросы, чтобы проверить обмен данными. Мы не добавляем маршруты, не меняем адреса и не останавливаем процессы.
Если нужной команды нет, установите её из официального репозитория Ubuntu: ip и ss входят в iproute2, ping — в iputils-ping, а curl — в одноимённый пакет.
sudo apt update
sudo apt install iproute2 iputils-ping curl
Какие у нас адреса: ip -br address
Первый вопрос — какие сетевые интерфейсы есть у машины и какие адреса им присвоены. Для этого в современных Linux используется команда ip из пакета iproute2. Вариант с опциями -br address даёт краткий, удобный для чтения вывод:
ip -br address
Опция -br означает «brief», то есть сокращённый формат. Вместо подробного описания каждого интерфейса мы получим по одной строке на каждый. Вывод может выглядеть примерно так:
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.50.10/24 fe80::1/64
Имена интерфейсов на разных машинах отличаются. У вас вместо eth0 может быть enp0s3, wlan0 или другое имя. Это нормально, и в наших примерах конкретные имена условны.
Разберём, что мы видим. Интерфейс lo — это loopback, тот самый локальный адрес 127.0.0.1, о котором мы говорили. Он всегда существует, даже если компьютер вообще не подключён ни к какой сети. Состояние UNKNOWN у него бывает потому, что loopback — внутренний интерфейс, у него нет физического кабеля или беспроводного соединения. Адрес 127.0.0.1 с префиксом /8 — указывает на принадлежность к диапазону 127.0.0.0/8, зарезервированному для loopback. Рядом показан адрес ::1/128 — это IPv6-эквивалент loopback.
Второй интерфейс в примере — eth0 — представляет подключение к сети; в WSL и виртуальной машине сам интерфейс обычно виртуальный. Состояние UP само по себе не подтверждает доступность интернета или нужной программы. Ему присвоен адрес 192.168.50.10/24. Это ровно та запись, которую мы разбирали в прошлом уроке: адрес машины и префикс, который показывает размер сети. Адрес fe80::1/64 — это условный IPv6-адрес канала (link-local): он предназначен для связи в пределах этого канала, а не для выхода в интернет. Такие адреса часто настраиваются автоматически. Для наших задач IPv6 не будет основным, но он часть реальной картины.
Куда уходят пакеты: ip route
Теперь мы знаем, какой адрес у машины. Следующий вопрос — куда машина будет отправлять пакеты для разных адресов. За это отвечает таблица маршрутизации:
ip route
Вывод может быть таким:
default via 192.168.50.1 dev eth0 proto dhcp src 192.168.50.10 metric 100
192.168.50.0/24 dev eth0 proto kernel scope link src 192.168.50.10
Первая строка — маршрут по умолчанию. Когда адрес назначения не подходит ни под какой более конкретный маршрут, пакет отправляется через шлюз 192.168.50.1 по интерфейсу eth0. Слова proto dhcp означают, что маршрут пришёл от DHCP, то есть был получен автоматически при подключении к сети. Число metric задаёт приоритет, если маршрутов по умолчанию несколько.
Вторая строка — маршрут для нашей собственной сети. Она говорит: пакеты для адресов 192.168.50.0/24 отправляются прямо через интерфейс eth0, без шлюза. Это и есть то, что мы обсуждали: машины одной сети общаются напрямую.
Порядок работы маршрутизатора важен. Сначала проверяются более конкретные маршруты, и только если ничего не подошло — маршрут по умолчанию. Для адреса 192.168.50.20 подойдёт вторая строка, и пакет уйдёт напрямую. Для адреса 203.0.113.20 не подойдёт ничего, кроме default, и пакет уйдёт через шлюз.
Какой маршрут будет выбран: ip route get
Иногда полезно не просто читать таблицу маршрутов, а спросить систему: а что будет с пакетом для такого-то адреса? Для этого есть команда ip route get. Она показывает, какой маршрут будет выбран, не отправляя при этом сам пакет. Это важно: ip route get не проверяет доступность адреса и не посылает пробу. Она только моделирует выбор маршрута по таблице.
Проверим адрес в своей сети:
ip route get 192.168.50.20
Вывод может быть таким:
192.168.50.20 dev eth0 src 192.168.50.10
Это означает: пакет уйдёт напрямую через eth0, и отправитель представится адресом 192.168.50.10. Теперь проверим внешний адрес, например документационный 203.0.113.20 из нашей схемы:
ip route get 203.0.113.20
Вывод будет другим:
203.0.113.20 via 192.168.50.1 dev eth0 src 192.168.50.10
Здесь появилось слово via — через. Пакет пройдёт через шлюз 192.168.50.1. Так мы можем убедиться, что таблица маршрутов понимает разницу между локальной сетью и всем остальным миром.
Если маршрут не найден вовсе, команда выведет ошибку. Если маршрут найден, но физически адрес недоступен, ip route get всё равно покажет выбранный маршрут — она ничего не проверяет, кроме таблицы. Поэтому она хороша для вопроса «как бы я пошёл?», а не «дойдёт ли?».
Есть ли связь: ping
Мы знаем свой адрес и знаем, куда пойдут пакеты. Следующий вопрос — есть ли связь с конкретным адресом. Классическая команда для этого — ping. Она отправляет пробные пакеты и ждёт ответы. Но у ping есть особенность: без ограничений она будет работать бесконечно, пока вы её не остановите. Для диагностики нам нужен ограниченный запуск:
ping -c 4 192.168.50.20
Опция -c 4 задаёт количество проб: четыре пакета, затем ping завершится сам. Вывод будет примерно таким:
PING 192.168.50.20 (192.168.50.20) 56(84) bytes of data.
64 bytes from 192.168.50.20: icmp_seq=1 ttl=64 time=0.512 ms
64 bytes from 192.168.50.20: icmp_seq=2 ttl=64 time=0.487 ms
64 bytes from 192.168.50.20: icmp_seq=3 ttl=64 time=0.493 ms
64 bytes from 192.168.50.20: icmp_seq=4 ttl=64 time=0.501 ms
--- 192.168.50.20 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 0.487/0.498/0.512/0.011 ms
Каждая строка — это полученный ответ. Время time показывает задержку. В конце — статистика: сколько пакетов отправлено, сколько получено, какой процент потерян. Ноль потерь — хороший признак.
Для наших учебных целей ping -c 4 к локальному адресу 127.0.0.1 — это способ проверить, что сетевой стек системы вообще работает:
ping -c 4 127.0.0.1
Ответы придут практически мгновенно, потому что данные не покидают машину. Это не проверка внешней сети, а проверка самого механизма отправки и приёма пакетов.
Кто слушает порты: ss -ltn и ss -lun
Когда связь на уровне адресов проверена, можно спросить: а какие программы на нашей машине вообще слушают порты? Для этого есть команда ss. Сначала посмотрим слушающие TCP-порты:
ss -ltn
Опции здесь: -l — только слушающие сокеты, -t — только TCP, -n — показывать порты числами, не преобразуя их в имена служб. Вывод может выглядеть так:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
LISTEN 0 128 127.0.0.1:631 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
Здесь мы видим несколько слушающих программ. Адрес 127.0.0.1 перед портом означает, что программа слушает только локальный адрес. К такой программе нельзя подключиться с другой машины — только с самой машины по 127.0.0.1. Адрес 0.0.0.0 означает, что программа слушает на всех IPv4-адресах машины. Это не подтверждает внешнюю доступность: соединение ещё должно пройти маршрут и сетевой экран.
Порт 22 — это стандартный порт SSH. Если он слушается на 0.0.0.0, значит, он принимает подключения на IPv4-адресах машины; доступ извне ещё зависит от маршрута и сетевых экранов. Для наших учебных задач мы позже будем использовать SSH на loopback, и тогда в выводе может появиться именно 127.0.0.1:22 или другой порт.
Теперь посмотрим слушающие UDP-порты:
ss -lun
Здесь -u вместо -t — протокол UDP. Вывод построен так же, но состояние LISTEN у UDP не отображается, потому что UDP не устанавливает соединений. Мы можем увидеть записи вида 0.0.0.0:68 или 127.0.0.53:53. UDP и TCP имеют разные пространства портов: порт 53 TCP и порт 53 UDP могут использоваться разными программами одновременно, и это не конфликт.
В выводе ss могут встречаться IPv6-адреса, записанные в квадратных скобках. Например, [::]:22 означает, что программа слушает порт 22 на всех IPv6-адресах. Адрес :: — это IPv6-аналог 0.0.0.0. Многие программы слушают одновременно IPv4 и IPv6. Для наших задач это не помеха, но важно узнавать такие записи и не путать их с IPv4.
Что отвечает удалённый сервис: curl
Пока мы проверяли собственную машину. Теперь попробуем обратиться к конкретной программе на удалённой машине. Для этого подойдёт curl — инструмент для работы с URL. Чтобы не ждать долго и не получать лишних данных, используем ограничения по времени и запрос только заголовков:
curl -I --connect-timeout 5 --max-time 10 https://example.com
Опция -I просит выполнить HEAD-запрос, то есть попросить у сервера только заголовки ответа, без тела страницы. Опция --connect-timeout 5 ограничивает время установления соединения пятью секундами. Опция --max-time 10 ограничивает общее время выполнения команды десятью секундами.
Вывод будет содержать HTTP-статус и заголовки ответа. Например:
HTTP/2 200
content-type: text/html
content-length: 1256
...
HTTP-статус 200 — это штатный ответ: сервер понял запрос и отвечает. Но нужно помнить два нюанса. Во-первых, HEAD поддерживают не все серверы. Если сервер не поддерживает HEAD, curl -I может вернуть ошибку или пустой ответ, хотя обычный GET-запрос к тому же адресу сработал бы. Это не обязательно означает сетевую проблему. Во-вторых, HTTP-ошибки не являются сетевыми сбоями. Если сервер ответил HTTP 404, значит, соединение установилось, обмен данными прошёл успешно, но сервер сообщает, что такого ресурса нет. Без опции -f curl в такой ситуации вернёт код 0, потому что сам обмен прошёл успешно. Код 0 отражает успех сетевого взаимодействия, а не то, что запрошенный ресурс существует.
Для учебного запуска мы взяли example.com — домен, специально предназначенный для документации. Это не обязательный внешний сервер: если у вас нет выхода в интернет, вы можете не использовать эту команду вообще, а сосредоточиться на предыдущих проверках. Мы не будем обещать, что этот адрес всегда доступен и что его ответы одинаковы. Но когда доступ есть, curl -I — отличный способ увидеть, что цепочка «имя → адрес → соединение → ответ» работает целиком.
Здесь впервые в сетевом блоке возникает DNS — преобразование имени в IP-адрес. curl сам выполняет это преобразование перед подключением. Мы не будем сейчас углубляться в DNS; достаточно знать, что это ещё один этап, который проходит до установления TCP-соединения. Подробный разбор DNS — тема следующего урока.
Диагностическая последовательность
Теперь видно, как эти команды складываются в единую логику. Представим, что мы не можем достучаться до какой-то программы на другой машине. С чего начать? С самого близкого: ip -br address покажет, есть ли у нас вообще адрес. Если у нужного интерфейса нет подходящего адреса или он отключён, это первая гипотеза для проверки; другой интерфейс при этом может работать.
Если адрес есть, смотрим ip route. Видим ли мы сеть назначения? Если да, пакеты пойдут напрямую. Если нет, есть ли маршрут по умолчанию? Без него остаются доступны адреса, для которых есть другие подходящие маршруты. Команда ip route get помогает уточнить, какой именно маршрут выберет система для конкретного адреса, не отправляя никаких проб.
Дальше проверяем связь. ping -c 4 покажет, доходят ли пакеты до адреса и приходят ли ответы. Если пинг успешен, сетевой уровень работает. Если нет, мы не делаем поспешных выводов: возможно, ICMP закрыт, и нужно продолжать диагностику.
Потом проверяем, слушает ли нужный порт локальная или удалённая программа. На своей машине это ss -ltn. Для удалённой машины в следующих уроках появятся свои инструменты, но сейчас curl показывает, что соединение с конкретным портом удалённой машины устанавливается и что приложение отвечает.
Каждая команда даёт ответ на один вопрос. Вместе они выстраиваются в путь от собственного интерфейса до удалённого приложения. Не нужно запускать их все подряд без необходимости — нужно понимать, какую гипотезу вы проверяете на каждом шаге. Если локальный адрес в порядке, а соединение не устанавливается, проверяем маршрут. Если маршрут есть, а соединения нет, проверяем связь. Если связь есть, а сервис не отвечает, проверяем порт. Так диагностика превращается из каталога команд в последовательное рассуждение.
Команда ip -br address показывает сетевые интерфейсы и их адреса: loopback всегда присутствует с 127.0.0.1, а физический интерфейс обычно имеет адрес вида 192.168.50.10/24. Имена интерфейсов на разных машинах различаются. Команда ip route выводит таблицу маршрутизации: маршрут для собственной сети и маршрут по умолчанию через шлюз. Более конкретный маршрут проверяется раньше, и только если адрес не подходит ни под один более конкретный маршрут, пакет уходит через default. ip route get показывает, какой маршрут система выберет для указанного адреса, но не отправляет пробу и не проверяет доступность.
ping -c 4 отправляет ограниченное число ICMP-проб и показывает, доходят ли пакеты. Успешный пинг подтверждает связь, но его неудача не всегда означает выключенную машину: некоторые системы не отвечают на ICMP. Команда ss -ltn показывает слушающие TCP-порты, ss -lun — слушающие UDP-порты. Адрес 127.0.0.1 означает, что программа слушает только локально, 0.0.0.0 — на всех IPv4-адресах. Записи вида [::] относятся к IPv6. TCP и UDP имеют отдельные пространства портов. curl -I --connect-timeout 5 --max-time 10 делает HEAD-запрос, показывая, что цепочка «имя → адрес → соединение → ответ» работает. HTTP-статус 200 — это штатный ответ, но HEAD поддерживают не все серверы, а HTTP-ошибки вроде 404 не являются сетевыми сбоями: без опции -f curl возвращает код 0, если сетевой обмен прошёл успешно.
В теории мы разобрали, какие вопросы задаёт каждая сетевая команда и как из них складывается диагностика. Сейчас посмотрим на несколько конкретных выводов и потренируемся выбирать проверку под задачу. Задания опираются только на `ip`, `ping`, `ss` и `curl`, без будущих тем.
HTTP 404 или сетевая ошибка
Пользователь запустил curl и получил неожиданный ответ. Нужно понять, случился ли сбой в сети или сервер просто ответил по-своему.
Разберите предоставленный пример ответа.
На учебной машине выполнена команда:
curl -I --connect-timeout 5 --max-time 10 http://example.com/missing-page
Вывод:
HTTP/1.1 404 Not Found
date: Mon, 10 Sep 2026 10:00:00 GMT
server: example
content-length: 0
$ echo $?
0
Как правильно объяснить этот результат?
Какая команда отвечает на какой вопрос
У каждой команды в этом уроке — свой вопрос. Нужно соотнести инструмент с той гипотезой, которую он проверяет.
Сопоставьте команду с диагностическим вопросом, на который она отвечает лучше всего. Каждый инструмент используется один раз.
Команды: ip -br address, ip route, ss -ltn, ping -c 4, curl -I.
Вопросы:
- Есть ли у интерфейса подходящий адрес и префикс?
- Куда система отправит пакет для адреса вне своей сети?
- Слушает ли кто-нибудь TCP-порт на этой машине?
- Отвечает ли удалённый адрес на ICMP-пробы?
- Устанавливается ли соединение с конкретным сервисом и приходит ли ответ приложения?
Диагностика по готовым выводам
Ученик собрал несколько наблюдений с одной машины и просит помочь разобраться, где искать проблему. Нужно рассуждать по данным, не выполняя ничего самостоятельно.
На учебной машине 192.168.50.10 собраны такие наблюдения:
$ ip -br address
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.50.10/24 fe80::1/64
$ ip route
default via 192.168.50.1 dev eth0
192.168.50.0/24 dev eth0 scope link src 192.168.50.10
$ ss -ltn
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:*
$ ping -c 4 192.168.50.20
4 packets transmitted, 4 received, 0% packet loss
Известно дополнительно:
- На этой же машине запущен учебный веб-сервер, который должен отвечать по адресу
http://127.0.0.1:8080/. - Пользователь жалуется, что открыть
http://192.168.50.10:8080/с другой машины в той же сети 192.168.50.0/24 не получается.
Опишите словами, что показывают эти наблюдения, где вероятная причина отказа для второй машины и как это можно было бы подтвердить, не меняя настройки и не останавливая процессы. Ответ должен быть связным текстом, 5–7 предложений. Учтите, что успешный ping до 192.168.50.20 сам по себе ничего не говорит о работе веб-сервера на порту 8080. Для этого стенда проброс портов и прокси отсутствуют, вывод ss относится к тому же сетевому пространству, где работает веб-сервер.