Урок 4 — Порты, TCP и UDP

У сервера один IP — но на нём работает 5 разных программ: web-сервер, SSH, БД, мониторинг. Как пакеты не путаются и попадают к нужной программе? Ответ: порты. А TCP и UDP — это два способа, которыми пакеты доставляются. Знать обязательно.

В этом уроке
  1. Зачем нужны порты
  2. Диапазон портов: well-known, registered, ephemeral
  3. Сокет — IP + порт
  4. TCP — доставка с гарантией
  5. Three-way handshake
  6. Состояния TCP-соединения
  7. UDP — быстро и без гарантий
  8. Сравнение, когда что использовать
  9. Что с этим делает DevOps
  10. Команды и упражнения
  11. Чек-лист «понимаю это»
  12. Плейбук: «сервис не отвечает»
  13. Задачи с ответами
Вспомни из прошлых уроков

Данные летят пакетами (урок 1); IP-адрес доставляет пакет на нужный компьютер, а маска решает, «сосед или через шлюз» (уроки 2–3). Сегодня — последний недостающий кусочек адресации: как пакет находит нужную программу внутри компьютера. После этого урока ты сможешь прочитать адрес вида 192.168.1.10:443 целиком.

1. Зачем нужны порты

IP-адрес говорит, на какой компьютер доставить пакет. Но на одном компьютере одновременно работают много программ — браузер, мессенджер, web-сервер, SSH. Как операционная система решает, какой из них отдать пакет?

Ответ: каждая программа «садится» на свой порт — это число от 0 до 65535. IP плюс порт — уникальный адрес конкретной программы.

Один сервер — много программ — много портов 🖥️ Сервер 203.0.113.10 📨 SSH :22 🌐 Web-сервер :80 🔒 HTTPS :443 🗄️ PostgreSQL :5432 → :22 (вход по SSH) → :443 (открываю сайт) ОС смотритна номер портаи отдаёт пакетнужной программе IP — это адрес компьютера. Порт — это «номер квартиры» программы внутри.
Один IP, разные порты — разные программы. ОС маршрутизирует пакеты по номеру порта.
Аналогия

Порт = номер квартиры в большом доме

Дом (IP) на улице — один. Но в нём 100 квартир. Курьер с пиццей знает не только адрес дома, но и номер квартиры. Если бы номера квартир не было — пицца бы досталась первому встречному.

Так же ОС: получила пакет на 203.0.113.10:443 — передала именно процессу, который слушает 443.

2. Диапазон портов

Портов 65 536 штук (от 0 до 65535). Они официально разделены на три группы:

ДиапазонНазваниеКто использует
0 — 1023Well-known (общеизвестные)Системные службы. На Linux/macOS для биндинга нужны root-права
1024 — 49151Registered (зарегистрированные)Конкретные приложения, выделено IANA. Например, PostgreSQL 5432
49152 — 65535Dynamic / ephemeralВременные порты, которые ОС сама раздаёт клиентам

Порты, которые нужно знать наизусть

ПортПротокол / службаОписание
20, 21FTPПередача файлов (устаревший)
22SSHУдалённое управление сервером
23TelnetСтарый удалённый шелл, без шифрования. Не использовать.
25, 587, 465SMTPОтправка почты
53DNSРезолвинг имён — урок 5
80HTTPНезашифрованный веб
443HTTPSЗашифрованный веб (TLS)
3306MySQLБаза данных
5432PostgreSQLБаза данных
6379RedisКэш / БД в памяти
8080, 3000, 5000HTTP-приложенияЛюбимые порты разработчиков для локальных запусков
9090, 9100Prometheus / node_exporterМониторинг
Зачем учить

Видишь в логе «connection refused on 5432» — сразу думаешь «постгрес недоступен», а не лезешь искать что такое 5432. Это экономит часы.

3. Сокет — IP + порт

Сокет (socket) — это пара «IP-адрес + порт». То есть конкретная точка общения. 203.0.113.10:443 — это сокет.

Чтобы соединение установилось, нужны два сокета:

# Клиентский сокет (выдан ОС динамически из ephemeral)
192.168.1.42:54321

# Серверный сокет (где живёт программа)
203.0.113.10:443

# Пара = уникальное соединение
(192.168.1.42:54321) ↔ (203.0.113.10:443)

Каждое соединение — это уникальная четвёрка: IP1+порт1+IP2+порт2. Если ты одновременно открыл 5 вкладок одного и того же сайта, у тебя 5 разных клиентских портов, и сервер видит 5 разных соединений.

4. TCP — доставка с гарантией

В уроке 1 мы говорили: данные дробятся на пакеты. Но «дробятся» — это слишком просто. Кто гарантирует, что пакеты дойдут? В правильном порядке? Без потерь? Без дубликатов?

За это отвечает TCP (Transmission Control Protocol). Это «надёжная» доставка. TCP делает три ключевые вещи:

📦 Гарантия доставки

Если пакет потерялся — TCP его переотправит. Если не дошёл ответ — повторит. Программа просто не знает о потерях.

🔢 Сохранение порядка

Каждый пакет нумеруется. Приёмник собирает их в правильной последовательности, даже если пришли вразнобой.

⚖️ Контроль перегрузки

TCP «прощупывает» канал: начинает медленно, разгоняется. Если потери — снижает скорость. Уважает другие соединения.

🔐 Установление соединения

Прежде чем слать данные, стороны «здороваются» — three-way handshake. Об этом ниже.

5. Three-way handshake

Прежде чем обмениваться данными, клиент и сервер выполняют 3-шаговое «рукопожатие». Запомни эти три шага — это любимый вопрос на собеседовании.

💻 Клиент 🖥️ Сервер 1. SYN «Хочу установить соединение. Мой стартовый № = 1000» 2. SYN + ACK «Согласен. Мой стартовый № = 5000, подтверждаю твой 1001» 3. ACK «Подтверждаю твой 5001. Готов к данным» → ESTABLISHED — соединение готово, можно слать данные
TCP three-way handshake: SYN → SYN-ACK → ACK. После этого соединение установлено.

SYN = synchronize («синхронизировать»), ACK = acknowledge («подтверждаю»). Это специальные флаги в TCP-заголовке пакета.

Зачем такая сложность? Чтобы:

Закрытие соединения тоже не «бац, и нет». Там 4 шага: FIN → ACK → FIN → ACK. Не нужно сейчас зубрить — главное помнить «открытие и закрытие — это процедуры, а не моментальные действия».

6. Состояния TCP-соединения

В любой момент времени соединение находится в одном из «состояний». Их можно увидеть командой ss -tan или старой netstat. Главные:

СостояниеЧто значитDevOps-интерпретация
LISTENСервер слушает портНорма. Так должен выглядеть твой web-сервер на 443
ESTABLISHEDСоединение активноНорма. Идёт обмен данными
SYN_SENTКлиент отправил SYN, ждёт SYN-ACKЕсли застряло — сервер не отвечает (упал, фаервол)
SYN_RECVСервер получил SYN, отправил SYN-ACKМного таких = возможна SYN-flood атака
TIME_WAITСоединение закрыто, ждём 60 сек на «застрявшие» пакетыМного TIME_WAIT под нагрузкой — типичная боль. Решается tuning'ом ядра
CLOSE_WAITУдалённая сторона закрыла, мы — нетРастёт = баг в приложении (не закрывает сокеты). Серьёзный сигнал
CLOSE_WAIT — типовая боль

Если ты видишь сотни/тысячи CLOSE_WAIT у приложения — это утечка сокетов. Программа не закрывает соединения после получения FIN от собеседника. Это приводит к исчерпанию файловых дескрипторов и падению. Чинят в коде, не в инфраструктуре.

7. UDP — быстро и без гарантий

UDP (User Datagram Protocol) — противоположность TCP. Минимум формальностей:

Звучит «плохо», но в нужных задачах — это огромный плюс. Какие задачи?

Аналогия

TCP = заказная посылка с уведомлением. UDP = открытка на «авось».

Заказное письмо с уведомлением — дойдёт, и ты узнаешь, что дошло. Но медленнее и дороже.

Открытку бросил в почтовый ящик — и забыл. Может дойдёт, может нет, ответа не будет. Зато бесплатно и сразу. Для «привет, поздравляю» — норм. Для «вышли мне 100 000 рублей» — категорически нет.

8. Сравнение — когда что использовать

TCPUDP
Установка соединения3-way handshakeНет — сразу слать
Гарантия доставкиДаНет
Порядок пакетовСохраняетсяНе гарантируется
Скорость / latencyВыше overhead, выше задержкаМинимальный overhead
Контроль перегрузкиЕстьНет (приложение разбирается само)
Заголовок пакета20 байт минимум8 байт
ПримененияHTTP/HTTPS, SSH, БД, файлы, почтаDNS, VoIP, видео, игры, метрики, QUIC

Правило: если ты сомневаешься, какой использовать — выбирай TCP. UDP — только когда понимаешь, зачем тебе именно он.

9. Что с этим делает DevOps

10. Команды и упражнения

Что слушает на твоём хосте

# Linux — современный инструмент
ss -tlnp                       # TCP + LISTEN + numeric + processes
ss -ulnp                       # UDP + LISTEN + numeric + processes
ss -tan                        # все TCP-соединения и их состояния

# Старый netstat (всё ещё работает)
netstat -tlnp
netstat -tan | grep ESTABLISHED

# Узнать, какой процесс слушает порт 443
sudo lsof -i :443
sudo ss -tlnp 'sport = :443'

Проверить, открыт ли порт удалённо

# Самый быстрый способ — netcat
nc -zv example.com 443         # -z = только сканировать, -v = вербозно

# Через nmap (если установлен)
nmap -p 22,80,443 example.com

# Через curl — если HTTP-порт
curl -v telnet://example.com:22

Сделать запрос вручную (без браузера)

# Откроем TCP-соединение и пошлём HTTP «руками»
nc example.com 80
GET / HTTP/1.1
Host: example.com

# После двух Enter сервер ответит. Это и есть «голый» HTTP

Посмотреть трёхэтапное рукопожатие в живую

# tcpdump — слушает пакеты на сетевом интерфейсе
# Запускай в одной вкладке:
sudo tcpdump -i any -nn port 80 and host example.com

# Во второй вкладке — сделай запрос:
curl http://example.com

# Увидишь SYN, SYN-ACK, ACK — в реальности

11. Чек-лист «понимаю это»

12. Плейбук: «сервис не отвечает» — первый рабочий алгоритм

Это твой первый настоящий плейбук диагностики — алгоритм, который инженеры гоняют по десять раз на дню. Ситуация: приложение должно работать на сервере на порту 8080, но клиент говорит «не открывается». Действуй по шагам, не перескакивай:

Программа вообще слушает порт?
На сервере: ss -tlnp | grep 8080. Есть строка со state LISTEN — слушает, иди дальше. Нет строки — программа не запущена или упала: смотри её логи, это не сетевая проблема.
Слушает на правильном адресе?
Смотри колонку адреса: 0.0.0.0:8080 — слушает всех, хорошо. 127.0.0.1:8080 — слушает только себя: снаружи никто не подключится, хотя «у меня локально работает»! Классика — чинится конфигом приложения (bind 0.0.0.0).
Порт доступен с машины клиента?
С клиента: nc -zv адрес-сервера 8080 (или Test-NetConnection адрес -Port 8080 в PowerShell). succeeded — сеть в порядке, проблема выше (в самом приложении). refused — до сервера дошли, но порт закрыт (см. шаг 1–2). timeout — пакеты не доходят вовсе: дальше.
Timeout? Ищи, кто молча съедает пакеты
Обычно это файрвол — на сервере (ufw status / iptables -L), в облаке (Security Group!) или по пути. Проверь и базовую связность: ping адрес-сервера — если и пинг не идёт, проблема ещё ниже (IP, маршруты — урок 8).
Сформулируй вывод фактами
«Приложение слушает 0.0.0.0:8080, локально отвечает, с клиента timeout, в Security Group порт 8080 не открыт — добавляю правило». Вот так звучит инженер, а не «что-то с сетью».

13. Задачи — реши сам (ответы спрятаны)

Задача 1. В браузере открыт сайт. Какой порт у сервера? А какой у твоего браузера?

У сервера — 443 (HTTPS, well-known). У браузера — случайный эфемерный порт (обычно 49152–65535), выданный ОС на время соединения. Поэтому сервер всегда «известно где», а клиентов на одном компьютере может быть сколько угодно.

Задача 2. ss -tlnp показывает: 127.0.0.1:5432 LISTEN postgres. Коллега с соседнего сервера не может подключиться к базе. Почему?

PostgreSQL слушает только loopback (127.0.0.1) — доступен исключительно с этой же машины. Чтобы пускать снаружи, он должен слушать 0.0.0.0 (или конкретный внешний адрес) — параметр listen_addresses в конфиге. И не забыть про файрвол.

Задача 3. Почему DNS-запрос едет по UDP, а загрузка сайта — по TCP?

DNS-запрос — крошечный (один пакет туда, один обратно): гарантии TCP не нужны, а его handshake утроил бы время. Потерялся ответ — клиент просто переспросит. Сайт же — тысячи пакетов, где важен порядок и полнота: без TCP страница приехала бы «дырявой».

Задача 4. После перезапуска сервиса ты видишь кучу соединений в TIME_WAIT. Это авария?

Нет, это норма: TIME_WAIT — «вежливая пауза» после закрытия соединения (ОС ждёт, чтобы опоздавшие пакеты старого соединения не попали в новое). Через минуту-две они рассосутся сами. А вот сотни CLOSE_WAIT — плохой знак: приложение не закрывает соединения (утечка).

Задача 5. Можно ли запустить два веб-сервера на одном компьютере?

Да — на разных портах: один на 80, второй на 8080. Один порт может занимать только одна программа. Попытка второй сесть на занятый порт — ошибка Address already in use (увидишь её ещё много раз!).

Задача 6. Видеозвонок подтормаживает, и часть кадров «рассыпается», но звонок не рвётся. Какой транспорт использует приложение и почему это разумно?

UDP. Для живого видео перепосылка потерянного кадра бессмысленна — он уже устарел; лучше показать следующий. TCP бы «застревал» на каждой потере, и звонок бы дёргался ещё сильнее.

Порт — это «номер квартиры» программы. IP+порт = сокет. TCP — надёжная доставка с handshake (SYN/SYN-ACK/ACK), для большинства задач. UDP — быстро и без гарантий, для DNS, видео, игр. Состояния ss -tan расскажут, что происходит с твоими соединениями.
Мост к следующему уроку

Теперь ты знаешь полный адрес: IP + порт. Но постой — ты же никогда не набираешь 142.250.74.14:443. Ты набираешь google.com. Кто и как превращает удобное имя в IP-адрес? Это работа DNS — «телефонной книги интернета», одной из самых недооценённых и самых ломающихся систем. Следующий урок — про неё.

← Назад
Урок 3: Маски и CIDR