# Порт - как несколько сервисов делят один IP _Сеть: L4 и выше · LinuxLab Knowledge Base_ **TL;DR:** 16-битное число (0-65535), идентифицирует **процесс-получатель** на хосте. IP говорит куда (хост), порт - кому (процессу). 80 - HTTP, 443 - HTTPS, 22 - SSH. ## Зачем нужен порт IP-адрес адресует **машину**. Но на машине крутится десяток процессов: web, SSH, база, мониторинг. Когда пакет прилетает на `192.168.1.50` - кому его отдавать? Решает **порт** - 16-битное число (от 0 до 65535) в TCP/UDP-заголовке. Каждый «слушающий» процесс **привязан** к конкретному порту через `bind() + listen()`. Когда пакет приходит на этот порт - ядро отдаёт его тому процессу. Пара **(IP, port)** = **socket address** - глобально уникальный адрес endpoint'а в интернете. ## Категории портов | Диапазон | Имя | Кто использует | | --- | --- | --- | | **0-1023** | well-known | Стандартные сервисы (root-only на Linux) | | **1024-49151** | registered | Зарегистрированные у IANA сервисы | | **49152-65535** | dynamic / ephemeral | Клиентские исходящие соединения | Известные well-known: - **22** SSH - **53** DNS - **67/68** DHCP server / client - **80** HTTP - **123** NTP - **443** HTTPS - **3306** MySQL - **5432** PostgreSQL - **6379** Redis Полный список - `/etc/services`. ## Ephemeral ports - почему ты увидишь 54321 в curl'е Когда **клиент** делает соединение - он не выбирает свой порт явно. ОС берёт случайный из **ephemeral**-диапазона (на Linux дефолт `32768-60999`, проверить можно `cat /proc/sys/net/ipv4/ip_local_port_range`). Эти порты живут на время соединения. После закрытия - освобождаются (с лагом TIME_WAIT, см. [tcp-states](/kb/tcp-states.md)). Это значит: если ты делаешь много исходящих соединений - порты могут кончиться. На облачном NAT-gateway'е с тысячами клиентов это реальная проблема. ## Один порт - один процесс? По сути - да. Только один процесс может `bind()` на конкретный `(IP, port)`. Иначе **EADDRINUSE**. Исключения: - **SO_REUSEPORT** - несколько процессов могут слушать один порт, ядро балансирует входящие коннекты между ними (как nginx/haproxy делают) - **0.0.0.0 vs специфический IP** - `bind 0.0.0.0:80` и `bind 1.2.3.4:80` могут конфликтовать или нет, зависит от порядка bind'а ## Посмотреть кто что слушает ```bash ss -tlnp # все TCP listening сокеты + процессы ss -ulnp # UDP lsof -i :443 # кто на 443 netstat -tulnp # старая школа, тоже работает ``` Расшифровка флагов `ss`: - `-t` TCP, `-u` UDP - `-l` только listening - `-n` без DNS-резолва - `-p` показать процесс (нужен root для чужих) ## Команды ```bash ss -tlnp ``` Все TCP-сокеты в LISTEN с привязанным процессом ```bash ss -tn state established ``` Активные TCP-соединения - оба порта (свой и удалённый) видны ```bash lsof -i :443 ``` Кто использует порт 443 (входящие или исходящие) ```bash cat /proc/sys/net/ipv4/ip_local_port_range ``` Диапазон ephemeral-портов на этом хосте ```bash sudo nc -l 8080 ``` Открыть слушающий порт 8080 для эксперимента (TCP) ## См. также - [TCP three-way handshake](/kb/tcp-handshake.md) - [UDP - User Datagram Protocol](/kb/udp-basics.md) - [TLS handshake](/kb/tls-handshake.md) - [HTTP/1.1, HTTP/2, HTTP/3](/kb/http-protocol.md) - [nmap - сканирование портов и хостов](/kb/cmd-nmap.md)