Почему TCP-порт 443 - это не обязательно один TCP-порт?
Когда говорят «сервер слушает 443 порт», легко представить один socket, который принимает все HTTPS-соединения.
Но TCP идентифицирует соединение не только по порту назначения.
Для него важна комбинация:
Например, сервер слушает:
А клиенты создают:
Все три соединения приходят на один
И именно поэтому веб-сервер может одновременно обслуживать тысячи клиентов через один порт.
Но есть ещё интереснее.
Один и тот же порт 443 могут одновременно слушать несколько процессов, если используется
Например:
несколько worker-процессов могут иметь собственные listening sockets на одном
Ядро само распределяет новые соединения между ними.
Поэтому фраза «порт 443 занят веб-сервером» на практике скрывает сразу несколько уровней:
Именно поэтому один
N.A.
Когда говорят «сервер слушает 443 порт», легко представить один socket, который принимает все HTTPS-соединения.
Но TCP идентифицирует соединение не только по порту назначения.
Для него важна комбинация:
src IP + src port + dst IP + dst port
Например, сервер слушает:
10.0.0.10:443
А клиенты создают:
10.0.1.20:49152 → 10.0.0.10:443 10.0.1.21:49153 → 10.0.0.10:443 10.0.1.22:49154 → 10.0.0.10:443
Все три соединения приходят на один
:443, но TCP воспринимает их как разные соединения.И именно поэтому веб-сервер может одновременно обслуживать тысячи клиентов через один порт.
Но есть ещё интереснее.
Один и тот же порт 443 могут одновременно слушать несколько процессов, если используется
SO_REUSEPORT.Например:
ss -lntp | grep :443
несколько worker-процессов могут иметь собственные listening sockets на одном
IP:443.Ядро само распределяет новые соединения между ними.
При этом уже установленное соединение не прыгает между процессами: выбранный socket становится владельцем конкретного TCP-потока.
Поэтому фраза «порт 443 занят веб-сервером» на практике скрывает сразу несколько уровней:
443 - номер портаIP:443 - endpoint4-tuple - конкретное TCP-соединениеsocket - объект, через который процесс работает с этим соединениемИменно поэтому один
:443 способен обслуживать огромное количество независимых TCP-соединений одновременно.N.A.
👍6
Ping 1 мс не всегда означает, что сеть работает быстро (но почему?)
Можно получить RTT в 1–2 мс и при этом иметь очень плохую передачу данных.
Например, при потере даже небольшого процента TCP-пакетов скорость может резко просесть.
Потерянный сегмент приходится передавать заново, а TCP дополнительно уменьшает congestion window.
В итоге:
может оказаться намного хуже для TCP, чем:
Проверять нужно не только задержку:
но и реальные потери при передаче:
А на Linux посмотреть retransmissions:
Если в выводе растёт
Низкий RTT показывает, насколько быстро пакет возвращается. Он не показывает, насколько хорошо сеть передаёт поток данных.
N.A.
Можно получить RTT в 1–2 мс и при этом иметь очень плохую передачу данных.
ping проверяет только время прохождения ICMP-пакета туда и обратно. Он почти ничего не говорит о том, сколько пакетов реально теряется, насколько забит канал и что происходит с TCP при передаче.
Например, при потере даже небольшого процента TCP-пакетов скорость может резко просесть.
Потерянный сегмент приходится передавать заново, а TCP дополнительно уменьшает congestion window.
В итоге:
RTT = 2 ms
packet loss = 1%
может оказаться намного хуже для TCP, чем:
RTT = 50 ms
packet loss = 0%
Проверять нужно не только задержку:
ping -c 100 <server-ip>
но и реальные потери при передаче:
iperf3 -c <server-ip> -t 30
А на Linux посмотреть retransmissions:
ss -ti
Если в выводе растёт
retrans, проблема уже не в том, что «ping маленький».Низкий RTT показывает, насколько быстро пакет возвращается. Он не показывает, насколько хорошо сеть передаёт поток данных.
N.A.
👍8❤4
Один VLAN может проходить через несколько коммутаторов без единого L3-интерфейса
VLAN не привязан к конкретному коммутатору.
Если между устройствами настроен trunk, один и тот же broadcast domain может растянуться через несколько физических узлов.
Например:
На trunk-портах кадр VLAN 30 идёт с тегом
Проверка на Linux:
На Cisco:
При этом шлюз VLAN может находиться вообще на другом устройстве:
Коммутаторы между ними работают только на L2 и не принимают решение о маршрутизации.
Но есть важный нюанс: чем дальше растянут L2-домен, тем больше устройств получают его broadcast и unknown-unicast traffic.
Поэтому проблема иногда выглядит как «сеть внезапно стала шумной», хотя IP-маршрутизация при этом вообще не менялась.
N.A.
VLAN не привязан к конкретному коммутатору.
Если между устройствами настроен trunk, один и тот же broadcast domain может растянуться через несколько физических узлов.
Например:
PC ── SW1 ══ SW2 ══ SW3 ── Server
VLAN 30 VLAN 30 VLAN 30
На trunk-портах кадр VLAN 30 идёт с тегом
802.1Q.Проверка на Linux:
ip -d link show eth0.30
На Cisco:
show interfaces trunk
show vlan id 30
При этом шлюз VLAN может находиться вообще на другом устройстве:
PC → SW1 → SW2 → SW3 → Router
VLAN 30
Коммутаторы между ними работают только на L2 и не принимают решение о маршрутизации.
Но есть важный нюанс: чем дальше растянут L2-домен, тем больше устройств получают его broadcast и unknown-unicast traffic.
Поэтому проблема иногда выглядит как «сеть внезапно стала шумной», хотя IP-маршрутизация при этом вообще не менялась.
N.A.
❤6
Почему
На одном сервере можно запустить:
и получить тысячи TCP-соединений, а затем:
и увидеть совсем другое количество.
Это не обязательно означает, что один из инструментов врёт.
Особенно заметна разница на серверах с большим количеством ephemeral connections и быстро меняющимся состоянием TCP.
Для диагностики лучше смотреть не просто количество строк:
а разбивку состояний:
Например:
И отдельно проверить конкретный listener:
Важный момент:
N.A.
ss показывает тысячи соединений, а netstat - другую картинуНа одном сервере можно запустить:
ss -ant
и получить тысячи TCP-соединений, а затем:
netstat -antи увидеть совсем другое количество.
Это не обязательно означает, что один из инструментов врёт.
ss работает через современный интерфейс ядра Linux - NETLINK_INET_DIAG. Ядро отдаёт ему информацию о сокетах напрямую, поэтому ss может получать состояние соединений без перебора /proc и без старого механизма netstat.
netstat из пакета net-tools - устаревший инструмент. Его возможности и способ получения данных отличаются, а часть информации может отображаться иначе.Особенно заметна разница на серверах с большим количеством ephemeral connections и быстро меняющимся состоянием TCP.
Для диагностики лучше смотреть не просто количество строк:
ss -s
а разбивку состояний:
ss -ant | awk 'NR>1 {print $1}' | sort | uniq -cНапример:
ESTAB 18420
TIME-WAIT 7312
SYN-RECV 428
И отдельно проверить конкретный listener:
ss -lntpВажный момент:
TIME-WAIT, SYN-RECV, ESTAB и listening sockets - это разные состояния kernel socket state. Поэтому простое сравнение «сколько строк показывает утилита» может давать совершенно разные выводы.ss сегодня является основным инструментом для анализа TCP/UDP-сокетов в Linux, а netstat в новых системах обычно оставляют только ради совместимости со старыми привычками и скриптами.N.A.
👍6
Пакет можно отбросить до создания
Обычно сетевой пакет проходит довольно длинный путь внутри Linux:
Но
XDP может выполнить программу прямо на раннем этапе обработки пакета, когда драйвер уже получил его из NIC, но обычный
Поэтому решение можно принять буквально на входе:
Например, простой XDP-программе достаточно проверить destination IP и сразу отбросить пакет:
При
Это важно под большой нагрузкой: если отбросить ненужный трафик после создания
Проверить, загружена ли XDP-программа:
И посмотреть статистику:
Поэтому «firewall на сервере» - не всегда означает, что пакет сначала проходит весь сетевой стек, а потом его фильтруют. В Linux точка принятия решения может находиться практически сразу после получения кадра сетевой картой.
N.A.
skbОбычно сетевой пакет проходит довольно длинный путь внутри Linux:
NIC → driver → skb → network stack → socket → application
Но
skb создаётся не в самом начале.XDP может выполнить программу прямо на раннем этапе обработки пакета, когда драйвер уже получил его из NIC, но обычный
sk_buff ещё не создан.Поэтому решение можно принять буквально на входе:
NIC
↓
driver
↓
XDP
├── DROP
├── PASS → обычный network stack
├── TX
└── REDIRECT
Например, простой XDP-программе достаточно проверить destination IP и сразу отбросить пакет:
SEC("xdp")
int drop_packet(struct xdp_md *ctx)
{
return XDP_DROP;
}При
XDP_DROP пакет вообще не доходит до обычного kernel networking stack.Это важно под большой нагрузкой: если отбросить ненужный трафик после создания
skb, часть работы ядро уже успело выполнить. XDP позволяет перенести фильтрацию значительно раньше.Проверить, загружена ли XDP-программа:
ip -details link show dev eth0
И посмотреть статистику:
ip -s link show dev eth0
Поэтому «firewall на сервере» - не всегда означает, что пакет сначала проходит весь сетевой стек, а потом его фильтруют. В Linux точка принятия решения может находиться практически сразу после получения кадра сетевой картой.
N.A.
👍3❤2
Когда Linux работает как bridge, он не просто механически пересылает Ethernet-кадры между интерфейсами.
У него есть собственная forwarding database - FDB.
Когда кадр приходит на bridge, ядро смотрит на его source MAC и запоминает, откуда он пришёл:
aa:bb:cc:dd:ee:01 → eth0
aa:bb:cc:dd:ee:02 → eth1
Посмотреть таблицу можно:
bridge fdb show
После этого кадр для
aa:bb:cc:dd:ee:02 уже не нужно отправлять на все порты - bridge знает, что destination находится за eth1.Если destination MAC неизвестен, кадр будет flood’иться по подходящим портам. После получения ответа bridge снова обновит FDB.
У записей есть timeout, поэтому старый MAC постепенно исчезает:
bridge fdb show br br0
Особенно интересно это проявляется при миграции VM.
Было:
VM → eth0
После миграции:
VM → eth1
MAC тот же, но source frames начинают приходить с другого интерфейса. Bridge переучивает запись:
old MAC → eth0
↓
new MAC → eth1
Если MAC начинает постоянно перемещаться между портами, можно получить MAC flapping - и тогда проблема уже не в IP-маршрутизации.
Linux bridge в таком режиме фактически выполняет ту же базовую функцию, что и физический L2-коммутатор: строит таблицу MAC → порт на основании уже увиденного трафика.
N.A.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Сетевой пакет может потеряться ещё внутри NIC
В
Но между физическим портом и
У NIC есть собственные RX ring buffers. Драйвер забирает из них дескрипторы и передаёт полученные данные ядру.
При перегрузке очередь может не успеть обработать входящие пакеты:
Если проблема возникает на уровне NIC/driver, пакет может исчезнуть до того, как станет виден обычному packet capture.
Поэтому при странных потерях полезно смотреть не только:
но и аппаратную статистику:
А размеры RX/TX ring:
Можно увидеть отдельные counters вроде
Это важный момент при диагностике: если пакет не попал в
N.A.
В
tcpdump нет пакета - легко сделать вывод, что он не пришёл на сервер.Но между физическим портом и
tcpdump находится сама сетевой карта.У NIC есть собственные RX ring buffers. Драйвер забирает из них дескрипторы и передаёт полученные данные ядру.
При перегрузке очередь может не успеть обработать входящие пакеты:
NIC
↓
RX ring
↓
driver
↓
kernel
↓
tcpdump
Если проблема возникает на уровне NIC/driver, пакет может исчезнуть до того, как станет виден обычному packet capture.
Поэтому при странных потерях полезно смотреть не только:
ip -s link show eth0
но и аппаратную статистику:
ethtool -S eth0
А размеры RX/TX ring:
ethtool -g eth0
Можно увидеть отдельные counters вроде
rx_missed_errors, rx_no_buffer или специфичные для конкретного драйвера drops.Это важный момент при диагностике: если пакет не попал в
tcpdump, это ещё не доказывает, что его не получила сетевая карта.N.A.
👍5❤2
Большой RX ring не всегда делает сеть быстрее
У сетевой карты есть очереди, куда складываются входящие пакеты, пока драйвер не успел их обработать.
При burst-трафике большой ring действительно может помочь пережить кратковременный всплеск:
Но бесконечной очереди не бывает.
Если CPU стабильно обрабатывает, например, 500 тыс. пакетов/с, а приходит 700 тыс.:
ring постепенно заполняется, после чего начинаются drops.
Увеличение ring позволяет накопить больше пакетов:
Но если скорость обработки не изменилась, это только отодвинет момент переполнения.
Более того, слишком глубокая очередь может увеличить latency: пакет уже не теряется, но дольше ждёт своей очереди на обработку.
Поэтому при проблемах с сетью важно различать:
Первое означает, что пакет исчез. Второе, что пакет всё ещё жив, но уже слишком долго ждёт обработки.
N.A.
У сетевой карты есть очереди, куда складываются входящие пакеты, пока драйвер не успел их обработать.
При burst-трафике большой ring действительно может помочь пережить кратковременный всплеск:
NIC → RX ring → driver → kernel
Но бесконечной очереди не бывает.
Если CPU стабильно обрабатывает, например, 500 тыс. пакетов/с, а приходит 700 тыс.:
500k → 700k → 900k → ...
ring постепенно заполняется, после чего начинаются drops.
Увеличение ring позволяет накопить больше пакетов:
ethtool -g eth0
ethtool -G eth0 rx 4096
Но если скорость обработки не изменилась, это только отодвинет момент переполнения.
Более того, слишком глубокая очередь может увеличить latency: пакет уже не теряется, но дольше ждёт своей очереди на обработку.
Поэтому при проблемах с сетью важно различать:
packet loss
и
packet queueing
Первое означает, что пакет исчез. Второе, что пакет всё ещё жив, но уже слишком долго ждёт обработки.
N.A.
👍4
Обычно ARP работает так:
Host A → Who has 10.0.0.10?
Host B → 10.0.0.10 is aa:bb:cc:dd:ee:ff
Но устройство может само отправить ARP-пакет, не дожидаясь никакого запроса.
Это и есть Gratuitous ARP.
Например, виртуальный IP переезжает:
до:10.0.0.10 → aa:aa:aa:aa:aa:aa
после:10.0.0.10 → bb:bb:bb:bb:bb:bb
Новое устройство отправляет объявление:
10.0.0.10 is-at bb:bb:bb:bb:bb:bb
Соседи получают его и обновляют ARP-кэш.
В результате трафик начинает идти на новый MAC практически сразу - без того, чтобы каждый клиент самостоятельно выполнял ARP lookup.
Посмотреть такие объявления:
tcpdump -ni eth0 arp
А текущую таблицу соседей:
ip neigh show
Это особенно важно при:
Поэтому после переноса сервиса между хостами может измениться не DNS, не маршрут и не IP-адрес - меняется только MAC, связанный с уже известным IP, и сеть быстро узнаёт об этом через gratuitous ARP.
N.A.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍1
Как локальный трафик может вообще не попадать на физический интерфейс
Если приложение обращается к IP, который Linux считает своим локальным адресом, пакет не отправляется на физический интерфейс.
Например, на сервере:
Приложение выполняет:
Интуитивно кажется, что будет:
Но Linux сначала проверяет destination и видит, что 10.0.0.10 принадлежит самому хосту.
Маршрут будет иметь тип local:
Например:
Поэтому физический eth0 в этом обмене вообще не участвует:
Это важно при диагностике.
Можно поставить:
и не увидеть вообще ничего, хотя curl успешно устанавливает соединение.
А вот:
покажет этот трафик.
Причём это не означает, что
Поэтому проверка «пакет дошёл до сервера через его сетевую карту?» иногда вообще поставлена неправильно: если источник и destination находятся на одном хосте, пакет мог никогда не попасть на wire.
N.A.
Если приложение обращается к IP, который Linux считает своим локальным адресом, пакет не отправляется на физический интерфейс.
Например, на сервере:
eth0 → 10.0.0.10/24
Приложение выполняет:
curl http://10.0.0.10:8080
Интуитивно кажется, что будет:
application
↓
eth0
↓
switch
↓
eth0
↓
server
Но Linux сначала проверяет destination и видит, что 10.0.0.10 принадлежит самому хосту.
Маршрут будет иметь тип local:
ip route get 10.0.0.10
Например:
local 10.0.0.10 dev lo src 10.0.0.10
Поэтому физический eth0 в этом обмене вообще не участвует:
application
↓
local routing
↓
lo
↓
local socket
Это важно при диагностике.
Можно поставить:
tcpdump -ni eth0 port 8080
и не увидеть вообще ничего, хотя curl успешно устанавливает соединение.
А вот:
tcpdump -ni lo port 8080
покажет этот трафик.
Причём это не означает, что
lo - какой-то физический интерфейс. Это отдельный путь local delivery внутри сетевого стека Linux.Поэтому проверка «пакет дошёл до сервера через его сетевую карту?» иногда вообще поставлена неправильно: если источник и destination находятся на одном хосте, пакет мог никогда не попасть на wire.
N.A.
🔥4
Почему BGP может выбрать более длинный путь
В BGP легко представить выбор маршрута как простое правило: меньше AS в пути - лучше.
Но AS-path length - только один из атрибутов, которые участвуют в best-path selection.
Например, маршрутизатор получил:
На первый взгляд BGP должен выбрать A.
Но если у маршрута от B выше
Условно:
Это важный момент: BGP ищет не «самый короткий маршрут», а лучший маршрут по последовательности атрибутов.
На выбор могут влиять:
Поэтому добавление ещё одного AS в путь не обязательно заставит трафик пойти через другого провайдера.
Посмотреть, почему конкретный маршрут победил:
А в FRRouting удобно смотреть ещё и выбранный best path:
Именно поэтому при разборе BGP-проблемы вопрос «у какого peer меньше AS_PATH?» часто оказывается слишком ранним.
Сначала нужно понять, какой атрибут сделал маршрут предпочтительнее.
N.A.
В BGP легко представить выбор маршрута как простое правило: меньше AS в пути - лучше.
Но AS-path length - только один из атрибутов, которые участвуют в best-path selection.
Например, маршрутизатор получил:
10.10.10.0/24
peer A: AS_PATH 64501 64502
peer B: AS_PATH 64503 64504 64505
На первый взгляд BGP должен выбрать A.
Но если у маршрута от B выше
LOCAL_PREF, он может стать предпочтительным ещё до того, как длина AS_PATH вообще сыграет роль.Условно:
A → LOCAL_PREF 100 → AS_PATH 2
B → LOCAL_PREF 200 → AS_PATH 3
BGP выберет B.
Это важный момент: BGP ищет не «самый короткий маршрут», а лучший маршрут по последовательности атрибутов.
На выбор могут влиять:
LOCAL_PREF
↓
AS_PATH
↓
ORIGIN
↓
MED
↓
eBGP / iBGP
↓
IGP metric
↓
router ID / другие tie-breaker
Поэтому добавление ещё одного AS в путь не обязательно заставит трафик пойти через другого провайдера.
Посмотреть, почему конкретный маршрут победил:
show bgp ipv4 unicast 10.10.10.0/24
А в FRRouting удобно смотреть ещё и выбранный best path:
vtysh -c "show bgp ipv4 unicast 10.10.10.0/24"
Именно поэтому при разборе BGP-проблемы вопрос «у какого peer меньше AS_PATH?» часто оказывается слишком ранним.
Сначала нужно понять, какой атрибут сделал маршрут предпочтительнее.
N.A.
👍2
5 команд для поиска проблем с ARP после замены сервера
Заменили сервер, оставили тот же IP, интерфейс поднялся, gateway пингуется - но часть устройств всё ещё пытается отправлять трафик на старый MAC.
Проверяем по порядку.
1️⃣ Смотрим текущий neighbor state
Например:
Важно не только наличие MAC, но и состояние записи: REACHABLE, STALE, DELAY, PROBE, FAILED.
2️⃣ Проверяем ARP непосредственно до gateway
Если ответы приходят с неожиданного MAC, проблема уже не в маршрутизации.
3️⃣ Смотрим ARP на интерфейсе
Можно увидеть, кто спрашивает:
и кто отвечает:
Если разные устройства получают разные MAC для одного IP - это уже серьёзный признак конфликта или некорректного failover.
4️⃣ Наблюдаем изменения neighbor table в реальном времени
Полезно, когда проблема появляется не постоянно: можно увидеть, как запись меняется между состояниями или удаляется.
5️⃣ Проверяем доступность после обновления ARP
Но
Типичный сценарий после замены:
Если где-то ещё осталась старая ARP-запись, трафик может продолжать уходить на
Поэтому после замены сервера полезно проверять не только:
но и связку:
Именно она часто объясняет ситуацию, когда сервер уже заменили, а сеть ещё живёт по старой записи.
N.A.
Заменили сервер, оставили тот же IP, интерфейс поднялся, gateway пингуется - но часть устройств всё ещё пытается отправлять трафик на старый MAC.
Проверяем по порядку.
ip neigh show
Например:
10.0.0.1 dev eth0 lladdr aa:bb:cc:dd:ee:ff STALE
Важно не только наличие MAC, но и состояние записи: REACHABLE, STALE, DELAY, PROBE, FAILED.
arping -I eth0 10.0.0.1
Если ответы приходят с неожиданного MAC, проблема уже не в маршрутизации.
tcpdump -ni eth0 arp
Можно увидеть, кто спрашивает:
Who-has 10.0.0.10?
и кто отвечает:
10.0.0.10 is-at 11:22:33:44:55:66
Если разные устройства получают разные MAC для одного IP - это уже серьёзный признак конфликта или некорректного failover.
ip monitor neigh
Полезно, когда проблема появляется не постоянно: можно увидеть, как запись меняется между состояниями или удаляется.
ping -c 5 10.0.0.1
Но
ping здесь - только финальная проверка. Успешный ICMP сам по себе не говорит, что ARP работает корректно.Типичный сценарий после замены:
старый сервер
10.0.0.10 → AA:AA:AA:AA:AA:AA
↓ замена
новый сервер
10.0.0.10 → BB:BB:BB:BB:BB:BB
Если где-то ещё осталась старая ARP-запись, трафик может продолжать уходить на
AA:AA:AA:AA:AA:AA.Поэтому после замены сервера полезно проверять не только:
ip addr
ip route
но и связку:
IP → ARP/neighbor → MAC → реальный интерфейсИменно она часто объясняет ситуацию, когда сервер уже заменили, а сеть ещё живёт по старой записи.
N.A.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Почему нельзя смешивать management и user traffic «потом разделим»
Пока всё спокойно, смешанный трафик кажется нормальным решением.
Как только сеть ловит перегрузку или шторм, management-трафик оказывается в той же очереди, что и пользовательский.
В момент инцидента устройство может быть доступно по IP, но управлять им невозможно.
Самый простой вариант - отдельный management VLAN.
Пример на Cisco:
vlan 99
name MANAGEMENT
interface Vlan99
ip address 10.99.0.10 255.255.255.0
no shutdown
Access-порты для управления:
interface GigabitEthernet1/0/1
switchport mode access
switchport access vlan 99
Транки - только с нужными VLAN:
interface GigabitEthernet1/0/24
switchport mode trunk
switchport trunk allowed vlan 10,20,99
Если нужно жёстко отделить управление — VRF:
vrf definition MGMT
rd 65000:99
interface Vlan99
vrf forwarding MGMT
ip address 10.99.0.10 255.255.255.0
N.A.
Пока всё спокойно, смешанный трафик кажется нормальным решением.
Как только сеть ловит перегрузку или шторм, management-трафик оказывается в той же очереди, что и пользовательский.
В момент инцидента устройство может быть доступно по IP, но управлять им невозможно.
Самый простой вариант - отдельный management VLAN.
Пример на Cisco:
vlan 99
name MANAGEMENT
interface Vlan99
ip address 10.99.0.10 255.255.255.0
no shutdown
Access-порты для управления:
interface GigabitEthernet1/0/1
switchport mode access
switchport access vlan 99
Транки - только с нужными VLAN:
interface GigabitEthernet1/0/24
switchport mode trunk
switchport trunk allowed vlan 10,20,99
Если нужно жёстко отделить управление — VRF:
vrf definition MGMT
rd 65000:99
interface Vlan99
vrf forwarding MGMT
ip address 10.99.0.10 255.255.255.0
N.A.
👍4