Материал открыт для чтения

Войдите, чтобы сохранять прогресс и результаты.

Войти
Linux: Продвинутый

База сети: IP, порты, DNS и маршруты

чтение ~15 минУрок 2 из 22

Основы сети: минимальный ликбез перед Linux-командами

module linux advanced Image08

Это не курс по сетям. Полноценные сети — это отдельная большая тема: модели OSI/TCP-IP, маршрутизация, NAT, DNS, TLS, балансировка, сетевые правила доступа, BGP, overlay-сети, Kubernetes networking и много других деталей. По-хорошему этому нужно посвящать отдельный большой курс.

Но дальше в Linux Advanced мы будем смотреть на ip addr, ip route, ss, curl, traceroute, SSH и сетевую диагностику. Без минимальной базы эти команды выглядят как набор случайных строк. Поэтому здесь только самое необходимое: что такое IP-адрес, порт, маршрут, DNS, localhost и как запрос примерно проходит от команды curl до процесса на сервере.


С чего вообще начинается сеть

Компьютеры редко работают совсем сами по себе. Браузер открывает сайт, телефон получает сообщения, сервер скачивает пакет, приложение обращается к базе, kubectl ходит в Kubernetes API. Во всех этих случаях одна программа хочет передать данные другой программе и получить ответ.

Самая простая модель такая:

клиент -> запрос -> сервер
клиент <- ответ  <- сервер

Клиент — это тот, кто начинает разговор. Сервер — тот, кто ждёт запросы и отвечает на них.

Например:

Клиент Сервер Что происходит
Браузер сайт браузер просит HTML-страницу
apt репозиторий пакетов сервер отдаёт список пакетов или .deb-файл
docker pull registry registry отдаёт слои образа
kubectl Kubernetes API API принимает команды и возвращает состояние кластера
curl HTTP-сервер сервер возвращает HTTP-ответ

curl — это просто программа, которая умеет отправлять сетевые запросы из терминала. Чаще всего её используют для HTTP и HTTPS: проверить сайт, API, healthcheck, заголовки ответа, код 200/404/500, время ответа.

То есть curl не является "магической сетевой командой". Это маленький клиент. Он делает примерно то же, что браузер, но без красивого интерфейса: отправляет запрос и печатает ответ в терминал.

Браузер показывает пользовательское представление сайта: отрисованный HTML, стили, кнопки и layout. curl показывает инженерное представление того же ответа: тело, заголовки, статус-код, время запроса. Поэтому в лабораторных можно открыть Web Preview, чтобы увидеть страницу глазами пользователя, но в реальной диагностике часто быстрее начать с curl: он работает прямо в SSH-сессии, легко сохраняется в файл и хорошо подходит для автоматических проверок.


Чтобы отправить запрос, нужны адрес и правила

Перед тем как клиент сможет что-то спросить у сервера, он должен понять несколько вещей:

  1. Куда идти: какой IP-адрес у сервера.
  2. В какой сервис попасть: какой порт слушает нужная программа.
  3. Как туда добраться: через какой сетевой интерфейс и gateway отправить пакет.
  4. На каком "языке" разговаривать: HTTP, HTTPS, SSH, DNS, PostgreSQL protocol и так далее.

Можно думать так:

IP      -> на какую машину
порт    -> в какую программу на этой машине
протокол -> как именно общаться

Если ты открываешь https://example.com/api,

там уже спрятано несколько решений:

  • example.com — имя сервера, его надо превратить в IP через DNS;
  • https — протокол HTTPS;
  • порт явно не указан, значит по умолчанию будет 443;
  • /api — путь, который клиент попросит у HTTP-сервера.

Если написать http://localhost:8080/health,

то смысл другой:

  • localhost — эта же машина;
  • http — обычный HTTP без TLS;
  • 8080 — конкретный порт;
  • /health — путь проверки здоровья приложения.

IP, порт и MAC: разные адреса на разных уровнях

В сети одновременно используются разные адреса. Для начала важно не смешивать три вещи:

Что Как думать Пример
IP-адрес до какой машины или узла надо добраться 93.184.216.34
порт в какую программу на этой машине попасть 443
MAC-адрес какому соседнему устройству в этой локальной сети отдать данные сейчас 52:54:00:12:34:56

IP-адрес нужен для пути до конечного узла. Порт нужен уже на конечной машине, чтобы попасть в правильный процесс: nginx, sshd, PostgreSQL и так далее.

MAC-адрес нужен для ближайшего шага внутри текущей локальной сети: от ноутбука до домашнего роутера, от VM до виртуального роутера, от одного маршрутизатора до следующего. Твоя машина не отправляет данные "сразу в интернет". Если сервер далеко, она сначала отдаёт данные ближайшему роутеру, а для этого ей нужен MAC-адрес этого роутера.

Упрощённо:

HTTP-запрос -> что попросили у приложения
порт        -> в какую программу попасть
IP          -> к какому конечному адресу идти
MAC         -> кому отдать данные на этом ближайшем шаге

Почему не хватает одного IP? Во-первых, частные IP-адреса повторяются в разных сетях. Например, 192.168.1.10 может быть у тебя дома, в офисе и внутри виртуальной лаборатории. Это разные машины в разных локальных сетях. Внутри одной локальной сети IP тоже должен быть уникальным; если два устройства получили один IP, это уже конфликт.

Во-вторых, даже когда IP назначения известен, устройству всё равно нужно понять, кому физически отдать данные прямо сейчас: соседнему компьютеру или ближайшему роутеру.

Когда пакет идёт через маршрутизаторы, IP-адрес назначения обычно остаётся адресом конечного сервера. А MAC-адрес назначения меняется на каждом участке: сначала MAC ближайшего роутера, потом MAC следующего роутера, потом MAC сервера. IP отвечает за путь "в целом", а MAC — за один ближайший шаг.


Запрос и ответ на примере HTTP

В вебе чаще всего используется HTTP. В HTTP клиент отправляет запрос, а сервер возвращает ответ.

У запроса есть метод и путь, например GET /api.

GET означает "получить данные". Путь /api говорит серверу, какую часть приложения попросили.

Кроме метода и пути, в HTTP-запросе есть заголовки. Они передают служебную информацию: какое имя сайта запросил клиент, какой клиент отправил запрос, какие форматы ответа он принимает, есть ли cookie или авторизация.

Упрощённый запрос выглядит так:

GET /api HTTP/1.1
Host: example.com
User-Agent: curl/8.5.0
Accept: */*

Host — один из самых важных заголовков. Он отвечает на вопрос "какой сайт хотел открыть клиент?". Это не всегда то же самое, что IP-адрес подключения. На одном IP и порту могут жить несколько сайтов или приложений, и сервер выбирает нужный virtual host именно по Host.

Когда ты открываешь https://example.com/api в браузере, браузер сам отправляет Host: example.com. Когда ты запускаешь curl https://example.com/api, curl делает то же самое. Вручную Host обычно задают только для диагностики:

curl -H "Host: app.internal" http://127.0.0.1/api

Так можно подключиться к локальному IP, но проверить, как приложение поведёт себя для имени app.internal.

У ответа есть статус:

200 OK
404 Not Found
500 Internal Server Error

Это очень важная идея для диагностики:

  • если нет DNS, клиент даже не узнает IP сервера;
  • если нет маршрута, пакет не доедет;
  • если порт закрыт, соединение не откроется;
  • если HTTP отвечает 500, сеть уже сработала, но приложение сломалось внутри;
  • если HTTP отвечает 404, сервер жив, но такого пути нет.

Поэтому DevOps-инженер не просто спрашивает "сайт работает?". Он раскладывает проблему на уровни: имя, IP, маршрут, порт, процесс, протокол, приложение.


Что происходит, когда ты пишешь curl

Представь команду:

curl https://example.com/api

Теперь эта команда уже читается понятнее: curl как клиент хочет отправить HTTPS-запрос на сервер example.com и попросить путь /api.

Очень упрощённо происходит такая цепочка:

  1. Система должна понять, какой IP-адрес стоит за именем example.com.
  2. Для этого она делает DNS-запрос: example.com -> 93.184.216.34.
  3. Затем Linux смотрит таблицу маршрутов: через какой интерфейс и шлюз отправлять пакет к этому IP.
  4. Клиент открывает TCP-соединение к IP и порту. Для HTTPS это обычно порт 443, для HTTP — 80.
  5. Если это HTTPS, поверх TCP начинается TLS: клиент и сервер договариваются о шифровании.
  6. Потом уже идёт HTTP-запрос: GET /api.
  7. На сервере какой-то процесс слушает нужный порт и отвечает.

Если что-то сломалось, проблема может быть на любом шаге: DNS не резолвит имя, нет маршрута, доступ к порту запрещён, процесс не слушает, приложение отвечает 500, TLS-сертификат не подходит.


IP-адрес: куда подключаемся

IP-адрес — это адрес узла в сети. В Linux ты часто увидишь IPv4-адреса вроде:

192.168.1.20
10.0.2.15
172.17.0.2
127.0.0.1

Частные адреса 10.x.x.x, 172.16.x.x-172.31.x.x, 192.168.x.x обычно живут внутри локальных сетей, облачных VPC, Docker-сетей и домашних роутеров. Они не уникальны во всём интернете: один и тот же 192.168.1.10 может существовать в тысячах разных локальных сетей.

127.0.0.1 — это localhost. Он всегда означает "эта же машина". Если сервис слушает только 127.0.0.1:8080, к нему можно подключиться с этой машины, но нельзя напрямую с другой машины.


Маска сети: кто рядом

IP-адрес сам по себе не всегда говорит, кто находится "рядом" с машиной в той же локальной сети. Поэтому адрес часто пишут вместе с маской, например 192.168.1.20/24.

192.168.1.20 — это адрес машины. /24 — это маска сети. Она говорит: первые три части адреса, 192.168.1, считаются номером локальной сети. Последняя часть — номер конкретного устройства внутри этой сети.

В практическом виде 192.168.1.20/24 означает, что локальная сеть примерно охватывает адреса 192.168.1.0–192.168.1.255.

То есть 192.168.1.50 находится рядом, а 192.168.2.50 уже не рядом.

Зачем это нужно Linux:

  1. Если адрес назначения в той же локальной сети, можно отправить данные напрямую этому устройству.
  2. Если адрес назначения не в той же локальной сети, нужно отправить данные на шлюз, то есть ближайший роутер.

Пример:

IP твоей машины:     192.168.1.20/24
сосед в той же сети: 192.168.1.50
другая сеть:         192.168.2.50
интернет-адрес:      8.8.8.8

К 192.168.1.50 можно идти напрямую через локальный интерфейс. К 192.168.2.50 и 8.8.8.8 напрямую нельзя: Linux отправит данные на шлюз, а дальше уже роутеры будут передавать их по маршруту.

Если маску поменять, граница "кто рядом" тоже поменяется:

Адрес на машине Кто считается рядом
192.168.1.20/24 обычно 192.168.1.x
192.168.1.20/16 обычно 192.168.x.x

Поэтому маска отвечает не на вопрос "какой у меня IP?", а на вопрос "какая часть адресов считается моей локальной сетью?". Без неё Linux не смог бы уверенно решить, куда отправлять данные: напрямую соседу или через шлюз.


Порт: в какой процесс попадаем

IP-адрес отвечает на вопрос "на какую машину". Порт отвечает на вопрос "в какой сервис на этой машине".

Примеры:

Порт Частое назначение
22 SSH
80 HTTP
443 HTTPS
5432 PostgreSQL
6379 Redis
8080 HTTP-приложения, тестовые сервисы

На одном IP может быть много процессов, если они слушают разные порты:

192.168.1.20:22    -> sshd
192.168.1.20:80    -> nginx
192.168.1.20:5432  -> postgres

Когда говорят "сервис недоступен", всегда уточняй адрес и порт. host доступен по ping и порт 8080 открыт — это разные проверки.


TCP и UDP: разные типы соединений

Для начала достаточно помнить:

Протокол Как думать
TCP соединение с подтверждениями: SSH, HTTP, PostgreSQL
UDP отправка отдельных сообщений без постоянного соединения: DNS, часть VPN, метрики

Когда мы смотрим ss -tlnp, флаг -t означает TCP. Для UDP будет ss -ulnp.


DNS: имя превращается в IP

Людям удобно помнить имя api.example.com.

Сетевому стеку нужен IP, например 203.0.113.10.

DNS — это система, которая отвечает на вопрос "какой IP у этого имени?". В Linux это можно проверить командами:

dig example.com
dig +short example.com
nslookup example.com

Если DNS не работает, curl https://example.com может упасть ещё до попытки подключения к серверу. При этом curl http://203.0.113.10 может работать, потому что DNS уже не нужен.

Есть ещё локальный файл /etc/hosts. Это маленькая таблица на самой машине: какое имя к какому IP привязать без запроса к DNS.

Пример:

127.0.0.1      localhost
192.168.1.10   myapp.local

Если в /etc/hosts есть строка 192.168.1.10 myapp.local, то команда:

curl http://myapp.local

пойдёт на 192.168.1.10, даже если настоящий DNS сказал бы другой IP.

Зачем это нужно:

  • дать локальное имя тестовому серверу;
  • проверить новый сервер до изменения DNS;
  • временно направить домен на нужный IP во время диагностики.

Важно: /etc/hosts действует только на этой машине. Если ты поменял его у себя, это не меняет DNS для других людей и серверов. Поэтому при странной проблеме с именем полезно проверить не только DNS, но и локальный /etc/hosts.


Маршрут и шлюз: куда отправить пакет

Linux хранит таблицу маршрутов. Она отвечает на вопрос: "если пакет идёт к такому IP, через какой интерфейс его отправить?"

Типичная идея такая:

адреса моей локальной сети -> отправить напрямую через eth0
всё остальное             -> отправить на gateway

Gateway, или шлюз, — это следующий узел, которому Linux отдаёт пакет, если адрес не находится в локальной сети. В домашней сети это обычно роутер. В облаке — виртуальный маршрутизатор VPC.

Команда:

ip route

покажет эти правила. Важная строка обычно начинается с default: это маршрут "для всего, что не подошло под более точные правила".


127.0.0.1, 0.0.0.0 и внешний IP

Эти адреса часто путают.

127.0.0.1 — только эта машина, например 127.0.0.1:8080.

Сервис доступен локально, но не снаружи.

0.0.0.0 в выводе слушающих портов означает "все IPv4-интерфейсы", например 0.0.0.0:8080.

Сервис принимает подключения на всех адресах машины, если маршруты и настройки доступа это разрешают.

Внешний или локальный адрес интерфейса:

192.168.1.20:8080
10.0.2.15:8080

Сервис слушает конкретный сетевой адрес.


Минимальная модель диагностики

Когда приложение не отвечает, удобно идти снизу вверх:

  1. Есть ли IP-адрес на интерфейсе? ip addr
  2. Есть ли маршрут к нужному адресу? ip route, ip route get IP
  3. Резолвится ли имя? dig domain
  4. Слушает ли процесс нужный порт? ss -tlnp
  5. Есть ли сетевой путь до хоста? ping, traceroute
  6. Отвечает ли HTTP-уровень? curl -v, curl -I
  7. Что говорит приложение и его логи?

Главная мысль: не делай вывод по одной команде. ping может работать, а HTTP — нет. DNS может быть исправен, но порт закрыт. Порт может слушать, но приложение внутри отдаёт 500.


Что запомнить перед следующей статьёй

  • IP отвечает на вопрос "куда".
  • Порт отвечает на вопрос "в какой сервис".
  • DNS превращает имя в IP.
  • Маршрут говорит Linux, через какой интерфейс и шлюз отправить пакет.
  • 127.0.0.1 — только локальная машина.
  • 0.0.0.0 у слушающего сервиса — слушать все IPv4-интерфейсы.
  • curl проверяет прикладной HTTP-уровень, а не просто "есть ли сеть".

В следующей статье мы будем смотреть, как эти понятия видны в реальном выводе Linux-команд.

Материал изучен?

Войдите, чтобы сохранить прогресс и перейти к практической лаборатории.

Войти и продолжить