Сети в Linux — команды и локализация проблем

Две части: сначала готовые алгоритмы «если это — то это» для четырёх самых частых ситуаций (учись ориентироваться, а не гадать), потом — команды по задачам с пояснениями. Все команды безопасны для чтения состояния, если не сказано иное.

Главный принцип диагностики

Иди слоями снизу вверх (вспомни OSI): линк → IP → шлюз → интернет → DNS → приложение. На каждом шаге один вопрос с ответом да/нет. Нашёл первый «нет» — проблема на этом слое, глубже копать не нужно. Это быстрее, чем перебирать команды наугад.

🚨 Алгоритм №1: «Нет интернета»

Шаг 1. Есть ли у машины IP-адрес? → ip -br a
❌ нет
интерфейс DOWN или нет адреса: кабель/Wi-Fi, ip link set eth0 up, DHCP не выдал (sudo dhclient -v eth0). Адрес вида 169.254.x.x = DHCP-сервер недоступен — проблема между тобой и роутером.
✅ есть
слой L1–L2 в порядке, иди к шагу 2.
Шаг 2. Пингуется ли шлюз? → ip r | grep default, затем ping -c 3 <шлюз>
❌ нет
default-маршрута нет вообще → чинить DHCP/статическую настройку. Маршрут есть, но шлюз молчит → проверь ARP: ip n | grep <шлюз>. FAILED/INCOMPLETE = роутер недоступен на L2: перезагрузи роутер, проверь Wi-Fi/кабель, не тот VLAN.
✅ да
до роутера добираемся, иди к шагу 3.
Шаг 3. Есть ли интернет по IP? → ping -c 3 8.8.8.8
❌ нет
твоя сеть в порядке, дальше роутера пути нет: проблема у провайдера или в роутере. traceroute 8.8.8.8 покажет, где обрыв: умерло на первом хопе — роутер, дальше — звони провайдеру (и скажи им, на каком хопе умирает — зауважают).
✅ да
интернет физически есть! Если «не работает» — это не интернет, а DNS или конкретный сервис. Шаг 4.
Шаг 4. Работает ли DNS? → dig +short ya.ru (или nslookup ya.ru)
❌ нет
виноват DNS — классика «интернет есть, сайты не открываются». Проверь резолвер: cat /etc/resolv.conf. Быстрый обход — спроси другой сервер: dig @1.1.1.1 ya.ru. Ответил → замени резолвер / чини свой.
✅ да
сеть и DNS в порядке. «Не работает» один сайт/сервис → алгоритм №2. Всё лежит в браузере, а ping/dig живут → прокси/файрвол/VPN на самой машине.
Запомни лесенку: ip -br aping шлюзping 8.8.8.8dig ya.ru. Четыре команды локализуют 90% «нет интернета» за две минуты — и ты точно знаешь, кому звонить.

🚨 Алгоритм №2: «Конкретный сайт/сервис не открывается» (интернет есть)

Шаг 1. Имя резолвится? → dig +short site.com
❌ нет
DNS-проблема этого имени: опечатка, домен умер, твой резолвер врёт. Сравни с другим: dig @1.1.1.1 site.com. Ответы разные → резолвер/кэш: sudo resolvectl flush-caches.
✅ да
запиши полученный IP — он нужен дальше.
Шаг 2. Порт отвечает? → nc -zvw 3 site.com 443
❌ нет
до сервиса не достучаться: сервис лежит, файрвол режет, или путь битый. ping IP живой, а порт нет → именно порт закрыт (файрвол/сервис). Из другой сети (телефон через LTE) порт открыт → блокировка на твоей стороне/у провайдера.
✅ да
TCP-связность есть, иди на уровень приложения. Шаг 3.
Шаг 3. Что говорит HTTP? → curl -v https://site.com
❌ ошибка
читай, где оборвалось: ошибка на SSL/TLS handshake → сертификат/версии TLS (проверь: openssl s_client -connect site.com:443, смотри даты). Connection reset → DPI/файрвол/сервер сбрасывает. Ответ 5xx → сервер жив, но приложение болеет (не твоя сеть!). 301/302 бесконечные → редиректы, добавь -L.
✅ 200
по сети всё работает — проблема в браузере/клиенте: кэш, прокси, расширения, время на машине (кривое время ломает TLS!).
Лесенка: dignc портcurl -v. Каждый шаг отсекает слой: имя → транспорт → приложение.

🚨 Алгоритм №3: «Сеть тормозит»

Шаг 1. Где теряется/копится? → mtr --report --report-cycles 50 host
Loss% > 0
на последнем хопе и растёт с хопа N — смотри хоп N: там перегруз/битый линк. Потери только на промежуточном хопе, а дальше 0% — это роутер просто не любит отвечать на ping (rate-limit), НЕ проблема. Смотри последний хоп!
Avg скачет
задержка стабильно растёт с хопа N → узкое место там (например, переход на спутник/другую страну — норма; внутри города 100 мс — не норма).
Шаг 2. Ретрансмиссии TCP? → ss -ti dst <host> (смотри retrans, rtt)
retrans растут
пакеты теряются под нагрузкой (а ping мог быть чистым!): перегруз канала, duplex mismatch, Wi-Fi помехи. Сравни rtt в покое и под нагрузкой.
чисто
сеть не виновата → тормозит сервер/приложение/диск. Проверь тайминги: curl -w "%{time_starttransfer}\n" -o /dev/null -s https://host — большой time_starttransfer при быстром connect = думает сервер.
Шаг 3. Сколько канал реально тянет? → iperf3 -c сервер (нужен свой iperf3-сервер на том конце)
меньше тарифа
если сильно меньше и стабильно — измерь по кабелю (исключи Wi-Fi), проверь скорость порта: ethtool eth0 | grep Speed (вдруг 100Mb/s вместо 1000 — кабель/порт).
норм
канал в порядке — «тормозит» конкретный сервис, а не сеть.
Не забудь MTU: «мелкие страницы открываются, большие висят» = классика битого MTU (PPPoE/VPN): ping -M do -s 1472 8.8.8.8 — если «message too long» на меньших размерах, уменьшай MTU интерфейса.

🚨 Алгоритм №4: «Мой сервер недоступен снаружи» (взгляд со стороны сервера)

Шаг 1. Сервис вообще слушает? → ss -tlnp | grep :80
❌ нет
сервис не запущен или упал: systemctl status nginx, смотри логи. Сеть ни при чём.
✅ да
смотри на каком адресе слушает: 127.0.0.1:80 — только localhost, снаружи не достучаться никогда! Нужно 0.0.0.0:80 (или конкретный внешний IP). Это ловушка №1 всех новичков.
Шаг 2. Локально отвечает? → curl -s localhost:80
❌ нет
сервис слушает, но не отвечает → болеет само приложение (логи, перезапуск).
✅ да
приложение живо. Дальше — файрвол. Шаг 3.
Шаг 3. Файрвол пропускает? → sudo iptables -L -n | grep 80 / sudo ufw status / sudo nft list ruleset
❌ нет
порт не разрешён: sudo ufw allow 80/tcp. В облаке файрволов ДВА: на машине и снаружи (Security Group / NSG) — проверь оба!
✅ да
проверь с самого «снаружи»: nc -zv <внешний IP> 80 с другой машины. Работает из соседней сети, но не из интернета → NAT/проброс порта на роутере, серый IP у провайдера.
Лесенка сервера: слушает? (ss -tlnp) → на 0.0.0.0? → локально отвечает? (curl localhost) → файрвол машины? → файрвол облака/NAT? Ровно в этом порядке — изнутри наружу.

Адреса, интерфейсы, маршруты

ip -br a                       # ★ все интерфейсы кратко: имя, состояние, адреса
ip a                           # то же подробно (MAC, MTU, флаги)
ip r                           # таблица маршрутов; строка default = шлюз
ip r get 8.8.8.8               # ★ каким маршрутом/интерфейсом уйдёт пакет — отвечает роутер за тебя
ip n                           # ARP-таблица (соседи): REACHABLE хорошо, FAILED плохо
ip -s link show eth0           # счётчики интерфейса: errors/dropped растут = ищи физику
ip link set eth0 up            # поднять интерфейс (down — погасить)
hostname -I                    # все IP машины одной строкой
ethtool eth0 | grep -E "Speed|Duplex"   # скорость/дуплекс порта (100Mb = подозрение на кабель)

Соединения и порты (у себя на машине)

ss -tlnp                       # ★ кто слушает TCP-порты (и каким процессом) — команда №1 на сервере
ss -ulnp                       # то же UDP
ss -tan state established      # активные соединения
ss -tan | awk '{print $1}' | sort | uniq -c    # сводка по состояниям (много TIME-WAIT/SYN-RECV?)
ss -ti dst 1.2.3.4             # детали TCP до хоста: rtt, retrans (ретрансмиссии = потери!)
ss -s                          # общая статистика сокетов

Запомни чтение ss -tlnp: 127.0.0.1:5432 — доступен только с этой машины; 0.0.0.0:80 — доступен всем; [::]:80 — то же для IPv6.

Достижимость: ping / traceroute / mtr

ping -c 4 host                 # 4 пакета и статистика; смотри loss и время
ping -c 100 -i 0.2 host        # плотный тест — ловить редкие потери
ping -M do -s 1472 host        # тест MTU: 1472+28=1500; "too long" на меньших = MTU меньше
traceroute host                # путь по хопам (UDP по умолчанию)
traceroute -T -p 443 host      # ★ через TCP 443 — проходит файрволы, где UDP-trace молчит
traceroute -I host             # через ICMP (как Windows tracert)
mtr host                       # ★ живой traceroute+ping: смотри Loss% ПОСЛЕДНЕГО хопа
mtr --report --report-cycles 100 host   # то же в виде отчёта (для тикета/коллеги)

Проверка чужого порта

nc -zvw 3 host 443             # ★ порт открыт? (z — не слать данные, v — говори, w 3 — таймаут)
nc -l 9999                     # слушать порт (на том конце) — самодельный тест пары
telnet host 25                 # интерактивно постучаться (SMTP/POP руками)
echo > /dev/tcp/host/443 && echo open   # bash-встроенный тест, когда nc нет
nmap -p 22,80,443 host         # скан нескольких портов (только свои хосты!)
nmap -sn 192.168.1.0/24        # кто живой в сети (ping sweep)

DNS

dig site.com                   # A-запись, полный ответ (смотри секцию ANSWER и SERVER внизу)
dig +short site.com            # ★ только IP — для скриптов и быстрых проверок
dig site.com MX / AAAA / TXT / NS      # другие типы записей
dig @1.1.1.1 site.com          # ★ спросить КОНКРЕТНЫЙ сервер — сравнить со своим резолвером
dig +trace site.com            # весь путь от корня — где именно ломается цепочка
dig -x 8.8.8.8                 # обратная запись (IP → имя)
resolvectl status              # каким резолвером пользуется systemd-resolved
sudo resolvectl flush-caches   # сбросить DNS-кэш
cat /etc/resolv.conf           # классический конфиг резолвера
getent hosts site.com          # как имя видит СИСТЕМА (учитывает /etc/hosts!)

Ловушка: dig ходит напрямую в DNS и не смотрит /etc/hosts. Если браузер открывает «не то» — проверь getent hosts и сам /etc/hosts.

HTTP / curl

curl -v https://api.com                # ★ verbose: видно DNS, TCP, TLS, заголовки — главный отладчик
curl -I https://api.com                # только заголовки ответа (HEAD)
curl -L https://api.com                # идти по редиректам
curl -o out.html https://api.com       # сохранить в файл (-O — с именем как на сервере)
curl -u user:pass https://api.com      # basic-auth
curl -H "Authorization: Bearer eyJ..." https://api.com     # токен
curl -X POST -H "Content-Type: application/json" -d '{"k":"v"}' https://api.com/users
curl --resolve site.com:443:1.2.3.4 https://site.com   # ★ подставить IP минуя DNS (тест нового сервера!)
curl -w "dns %{time_namelookup} connect %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer} total %{time_total}\n" -o /dev/null -s https://site.com   # ★ тайминги: кто съел время

Чтение таймингов: большой dns — резолвер; большой connect — сеть/дистанция; большой ttfb при быстром connect — думает сервер, сеть не виновата.

TLS / сертификаты

# срок действия сертификата — причина №1 внезапных падений по расписанию
echo | openssl s_client -connect site.com:443 -servername site.com 2>/dev/null \
  | openssl x509 -noout -dates            # ★ notBefore / notAfter

# кто выдал, на какие имена (SAN)
echo | openssl s_client -connect site.com:443 -servername site.com 2>/dev/null \
  | openssl x509 -noout -subject -issuer -ext subjectAltName

openssl s_client -connect site.com:443 -showcerts    # вся цепочка (обрыв цепочки = ошибка в некоторых клиентах)
openssl s_client -connect site.com:443 -tls1_2       # проверить конкретную версию TLS
curl -vk https://site.com                            # k = игнорировать ошибки серта (только для ДИАГНОСТИКИ)

Всегда добавляй -servername (SNI): без него сервер с несколькими сайтами покажет не тот сертификат — и ты будешь чинить не то.

Захват трафика — когда глазами уже не видно

sudo tcpdump -i eth0 -nn port 443              # ★ живой поток (nn — без DNS/имен портов, быстрее и честнее)
sudo tcpdump -i eth0 -nn host 1.2.3.4 and port 443   # трафик с конкретным хостом
sudo tcpdump -i eth0 -nn -c 100 'tcp[tcpflags] & tcp-syn != 0'   # только SYN: кто открывает соединения
sudo tcpdump -i any -nn icmp                   # все ping'и на всех интерфейсах — «доходит ли до меня»
sudo tcpdump -i eth0 -w dump.pcap port 80      # писать в файл → открыть в Wireshark
sudo tcpdump -r dump.pcap -nn | head -50       # прочитать файл
tshark -i eth0 -f "port 443" -c 20             # Wireshark в консоли

Приём: смотри на SYN без ответа. SYN → тишина = не доходит или дропают; SYN → RST = доходит, но порт закрыт/запрещён. Это разные диагнозы!

Файрвол на машине

# ufw (Ubuntu, человеческий интерфейс)
sudo ufw status numbered               # правила с номерами
sudo ufw allow 22/tcp                  # открыть порт
sudo ufw allow from 10.0.0.0/24 to any port 5432   # порт только для подсети
sudo ufw delete 3                      # удалить правило №3

# nftables (современный бекенд)
sudo nft list ruleset                  # всё, что реально действует

# iptables (legacy, но встречается везде)
sudo iptables -L -n -v --line-numbers  # ★ v: счётчики pkts — по ним видно, КАКОЕ правило ест твой трафик
sudo iptables -t nat -L -n -v          # NAT-таблица (проброс портов, маскарадинг)

Диагностический приём: iptables -L -n -v дважды с интервалом — у какого DROP-правила растёт счётчик, то и режет.

Скорость и статистика

iperf3 -s                      # сервер (на одном конце)
iperf3 -c host                 # клиент: честная скорость канала между двумя точками
iperf3 -c host -R              # в обратную сторону (download vs upload!)
iperf3 -c host -u -b 100M      # UDP-тест: смотри Lost/Total — потери под нагрузкой
ip -s link show eth0           # счётчики: RX/TX errors, dropped, overruns
sar -n DEV 1                   # загрузка интерфейсов раз в секунду (пакет sysstat)
vnstat -l                      # живой трафик (если установлен)

VPN — WireGuard

sudo wg show                   # статус: peers, handshake, счётчики
sudo wg-quick up wg0           # поднять туннель (down — погасить)
wg genkey | tee private.key | wg pubkey > public.key   # пара ключей
# нет связи через туннель? смотри latest handshake в wg show:
#   нет handshake → ключи/endpoint/UDP-порт закрыт; handshake есть, трафика нет → AllowedIPs/маршруты

Полезные онлайн-инструменты

Куда дальше

Не хватает теории, почему эти команды работают именно так — пройди «Сети с нуля» (там каждая из этих команд объяснена с нуля). Работаешь с железом (Cisco/Juniper/Huawei) — твоя шпаргалка vendor-cli. Полный справочник команд инженера — большая шпаргалка трека.