12610
Обучающий канал по сетевому и системному администрированию. Сотрудничество: @dad_admin Биржа: https://telega.in/c/networkadm РКН: https://bit.ly/4ioc61C
Скрипт массовой проверки SSL-сертификатов на пуле серверов
Сертификат истёк в 3 ночи, сервис недоступен, клиенты видят страшное предупреждение в браузере. Самая частая причина downtime который легко предотвратить заранее, просто проверяя сроки по расписанию.
Проверка одного сертификата вручную:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
-servername важен если на сервере несколько сертификатов через SNI, без него можешь получить не тот сертификат.#!/bin/bash
THRESHOLD_DAYS=14
BOT_TOKEN="ваш_токен"
CHAT_ID="ваш_chat_id"
while read -r host port; do
expiry=$(echo | timeout 5 openssl s_client -connect "${host}:${port}" -servername "$host" 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "$expiry" ]; then
echo "$host:$port -> не удалось получить сертификат"
continue
fi
expiry_epoch=$(date -d "$expiry" +%s)
now_epoch=$(date +%s)
days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
echo "$host:$port -> $days_left дней до истечения"
if [ "$days_left" -lt "$THRESHOLD_DAYS" ]; then
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="⚠️ SSL на ${host}:${port} истекает через ${days_left} дней"
fi
done < hosts.txt
hosts.txt построчно:example.com 443
api.example.com 443
mail.example.com 465
В cron раз в сутки:0 9 * * * /usr/local/bin/check_ssl_pool.sh >> /var/log/ssl_check.log
⚡️timeout 5 в команде критичен. Если хост недоступен или порт фильтруется, openssl s_client может висеть бесконечно и весь скрипт встанет на первом проблемном сервере, не дойдя до остальных.
ARP на роутере с несколькими интерфейсами
Когда на роутере несколько интерфейсов в разных подсетях, ARP-запрос приходит на конкретный интерфейс. Роутер отвечает только если запрашиваемый IP принадлежит этому интерфейсу. Простой случай, работает предсказуемо.
Интереснее когда включён Proxy ARP или несколько интерфейсов в одной подсети.
sysctl net.ipv4.conf.all.arp_filter
sysctl net.ipv4.conf.all.arp_announce
sysctl net.ipv4.conf.all.arp_ignore
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
show ip interface Gi0/0 | include proxy|Helper
Почему jumbo frames включили, а производительность не выросла
Jumbo frames это MTU 9000 вместо стандартных 1500. Меньше заголовков на байт данных, меньше прерываний CPU. В теории быстрее, на практике часто никакого эффекта.
ping -M do -s 8972 <IP>
mpstat -I ALL 1
ethtool -S eth0 | grep rx_packets
Как поймать внезапный ARP-resolve timeout
Когда «всё работает… но периодически что-то замирает», очень часто виноват ARP.
Хост просто не может быстро получить MAC адрес - и весь трафик встаёт на паузу. Особенно больно это бьёт по VoIP, SSH и интерактивным сервисам.
tcpdump -ni eth0 arp
debug arp
show arp
tcpdump -ni eth0 "arp or icmp"
ip -s neigh
show mac address-table dynamic | include <MAC>
Почему 10G линк работает на 1G и как это поймать
Линк поднялся, всё зелёное, но скорость как на старом железе. Первая мысль: проблема в приложении или сети. На деле часто линк просто не договорился о скорости.
Смотрим на какой скорости реально работает интерфейс:
ethtool eth0 | grep -E "Speed|Duplex|Auto"
ip -s link show eth0
ethtool -S eth0 | grep -E "error|drop|miss|fail"
lldpctl eth0
ethtool -s eth0 speed 10000 duplex full autoneg off
ethtool -m eth0
Почему роутер не всегда выбирает маршрут с наименьшей метрикой
Метрика это не единственный критерий выбора маршрута. Сначала роутер смотрит на длину префикса: более специфичный маршрут всегда побеждает независимо от метрики.
Маршрут 192.168.1.0/24 с метрикой 100 выиграет у 192.168.0.0/16 с метрикой 1. Longest prefix match, основа IP-маршрутизации.
show ip route 10.0.0.0
show ip route 10.0.0.0 255.255.255.0 longer-prefixes
O 10.0.0.0/24 [110/20] via 192.168.1.1
show ip route summary
show ip bgp 10.0.0.0
show ip ospf database
Почему mmap быстрее read() для больших файлов и когда это не так
read() работает так: ядро копирует данные из page cache в буфер в user space.
На больших файлах с последовательным чтением разница заметна: меньше syscall-ов, меньше копирований, меньше переключений контекста.
На NUMA-системах mmap может давать неожиданные результаты: страницы аллоцируются на одном узле, процесс работает на другом, латентность растёт.
/usr/bin/time -v ./myprogram 2>&1 | grep "Page faults"
perf stat -e page-faults ./myprogram
Почему ICMP redirect считается дырой в безопасности
ICMP redirect это сообщение которое роутер отправляет хосту: “для этого назначения есть путь лучше, используй вот этот шлюз”. Хост получает сообщение и обновляет свою таблицу маршрутизации на лету, без какого-либо подтверждения.
Проблема в том что никакой аутентификации нет. Любой хост в сегменте может отправить ICMP redirect от имени шлюза и перенаправить трафик жертвы через себя.
Классический MITM без особых усилий: жертва продолжает думать что общается напрямую, трафик идёт через атакующего.
⏺Проверяем включены ли redirects на Linux:
sysctl net.ipv4.conf.all.accept_redirects
sysctl net.ipv4.conf.all.send_redirects
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.all.send_redirects=0
echo "net.ipv4.conf.all.accept_redirects=0" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects=0" >> /etc/sysctl.conf
interface Gi0/0
no ip redirects
sysctl net.ipv4.conf.all.secure_redirects
Почему traceroute показывает асимметричный путь и когда это нормально
Запускаешь traceroute до хоста и видишь что хопы идут через один город, а ответы приходят явно другим путём.
Или часть хопов показывает латентность выше чем финальный хост. Выглядит как проблема, но чаще всего это просто нормальная работа интернета.
traceroute 8.8.8.8
mtr --report 8.8.8.8
mtr --report --report-cycles 20 <IP>
Почему после замены коммутатора половина сети перестала работать
Заменили коммутатор, всё подключили, часть хостов работает, часть нет. Физически всё поднято, линки горят. Начинается час диагностики.
Обычно проблема в одном из трёх
Новый коммутатор пришёл с дефолтной конфигурацией. Все порты в VLAN 1, транки не настроены. Хосты которые работают находятся в VLAN 1 и просто повезло. Остальные VLANы не существуют на новом железе.
show vlan brief
show interfaces trunk
show spanning-tree
show spanning-tree detail | include root
spanning-tree vlan 1 priority 4096
show interfaces Gi0/1 | include duplex
interface Gi0/1
duplex full
speed 1000
Что происходит когда два DHCP-сервера отвечают на один запрос
Подключил кто-то в офисе домашний роутер к корпоративной сети, или подняли новый DHCP и старый не выключили. Оба слышат broadcast, оба отвечают.
sudo tcpdump -i eth0 port 67 or port 68 -n
nmap --script broadcast-dhcp-discover
ip dhcp snooping
ip dhcp snooping vlan 10
interface Gi0/1
ip dhcp snooping trust
interface range Gi0/2 - 24
no ip dhcp snooping trust
Что такое IX и как трафик идёт внутри него
IX (Internet Exchange) это физическая точка где провайдеры, CDN и крупные сети подключаются друг к другу напрямую. Вместо того чтобы гонять трафик через транзитного провайдера и платить за каждый гигабит, участники обмениваются трафиком напрямую и бесплатно между собой.
Крупнейшие точки обмена: DE-CIX во Франкфурте, AMS-IX в Амстердаме, MSK-IX в Москве. Через DE-CIX проходит больше 10 Тбит/с в пике.
router bgp 65001
neighbor 193.178.185.1 remote-as 65000
neighbor 193.178.185.1 description MSK-IX Route Server
Как работает TCAM и почему правила ACL влияют на производительность железа
Обычная RAM ищет данные по адресу: дай адрес, получи значение. TCAM работает наоборот: дай значение, получи результат за один такт. Content Addressable Memory, и T означает Ternary: каждый бит может быть 0, 1 или X (don’t care). Именно X позволяет матчить префиксы и маски.
Благодаря этому коммутатор находит совпадение для любого пакета за одну операцию, независимо от размера таблицы. Именно поэтому железо форвардит трафик на линейной скорости.
show platform tcam utilization
show sdm prefer
show ip access-lists
show platform hardware capacity
sdm prefer acl
reload
Как коммутатор строит CAM-таблицу и что происходит при переполнении
CAM-таблица это то, за счёт чего коммутатор работает как коммутатор, а не как хаб. Без неё каждый фрейм уходил бы на все порты.
Как строится таблица
Коммутатор учится пассивно: когда фрейм приходит на порт, смотрит на source MAC и записывает на каком порту он находится.
Когда нужно отправить фрейм, ищет destination MAC. Нашёл, отправил на конкретный порт. Не нашёл, flooding на все порты кроме входящего. Записи живут 300 секунд по умолчанию, потом удаляются.
show mac address-table
show mac address-table aging-time
interface Gi0/1
switchport port-security
switchport port-security maximum 2
switchport port-security violation restrict
show port-security interface Gi0/1
Anycast: как это работает за пределами DNS
Anycast это когда один и тот же IP-адрес анонсируется из нескольких точек одновременно. Клиент отправляет пакет, сеть сама выбирает ближайший узел по метрикам BGP.
Никакого DNS, никакого балансировщика между клиентом и сервером.
DDoS-mitigation строится на том же принципе. Атака распределяется между всеми точками присутствия, ни одна не получает весь объём трафика.
pool.ntp.org тоже anycast, клиент всегда попадает на географически близкий узел без какой-либо логики на своей стороне.router bgp 65001
network 192.0.2.0 mask 255.255.255.0
ip route 192.0.2.0 255.255.255.0 Null0
ICMP типы, которые нельзя блокировать
Блокировать весь ICMP это распространённая ошибка которую делают из соображений безопасности.
Часть типов действительно можно заблокировать, но несколько критически важны для работы сети.
⏺Type 3: Destination Unreachable
Самый важный. Код 4 (Fragmentation Needed) используется в Path MTU Discovery: промежуточный узел сообщает отправителю что пакет слишком большой и нужно уменьшить размер. Без него крупные пакеты молча дропаются, мелкие проходят. Симптом: SSH работает, scp зависает, большие страницы не грузятся.
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT
iptables -A INPUT -p icmp --icmp-type 12 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 3 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 11 -j ACCEPT
А ваши данные в S3 надежно защищены?
Проверьте вашу инфраструктуру и узнайте несколько лайфхаков на вебинаре
30 июня эксперты Selectel расскажут об эффективных механизмах защиты данных в S3 под разные задачи: например, для защиты от случайного удаления или кибератак и для соответствия регуляторным требованиям. В практическом блоке покажут реальные примеры настройки S3 через API и CLI.
📍 Онлайн
⏰ 30 июня в 12:00
👥 Для DevOps-специалистов, системных администраторов, специалистов по информационной безопасности и всех, кто не хочет столкнуться с утечкой и удалением данных.
Регистрируйтесь ➡️ https://slc.tl/6lnjx
Больше мероприятий для ИТ-специалистов в канале @selectel_events. Подписывайтесь!
Реклама. АО "Селектел". erid:2W5zFGd7S57
Почему сессия рвётся ровно через N минут
Если сессия рвётся не случайно а по таймеру, где-то на пути есть устройство которое принудительно закрывает idle или долгие соединения. Регулярность это ключ к диагностике.
Первым делом замеряем точное время разрыва в нескольких сессиях. Если цифра одинаковая или кратная, это таймаут а не флуктуация сети.
sysctl net.netfilter.nf_conntrack_tcp_timeout_established
sysctl net.netfilter.nf_conntrack_udp_timeout
cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait
grep -E "timeout|keepalive" /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf
tcpdump -i eth0 -w /tmp/capture.pcap host <IP> and port <PORT>
ssh -o ServerAliveInterval=30 user@host
Многоуровневая фильтрация трафика с iptables и nftables
iptables и nftables — два подхода к фильтрации трафика в Linux.
⏺iptables — классика, знакомая большинству системных администраторов, работает через цепочки INPUT, OUTPUT, FORWARD.
⏺nftables — современный инструмент, который объединяет IPv4, IPv6 и L2 фильтрацию в единой структуре, с более компактным синтаксисом и улучшенной производительностью.
С помощью них можно: ограничивать доступ по IP, блокировать конкретные порты, фильтровать трафик между VLAN, логировать подозрительные соединения и создавать сложные правила с условием источника, назначения и интерфейса.
Создадим простое ограничение трафика через nftables:
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0; }
sudo nft add rule inet filter input ip saddr 192.168.1.0/24 accept
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input drop
sudo nft add rule inet filter input tcp dport 22 log prefix "SSH DROP: " counter drop
sudo nft list ruleset
Почему autonegotiation ломается и когда его лучше отключить
Autonegotiation это протокол согласования скорости и duplex между двумя портами. Работает через обмен FLP (Fast Link Pulse) сигналами до установки линка. Когда всё работает, трогать не надо. Когда ломается, диагностировать неочевидно.
Чаще всего ломается на стыке старого и нового оборудования: одна сторона анонсирует одно, другая понимает иначе.
ethtool eth0 | grep -E "Speed|Duplex|Link"
ethtool -S eth0 | grep -E "collision|late_collision|deferred"
ethtool -s eth0 speed 1000 duplex full autoneg off
interface Gi0/1
speed 1000
duplex full
no negotiation auto
Как работает TCP window scaling и почему его отключение убивает скорость
TCP window это сколько данных можно отправить не дожидаясь подтверждения.
Без window scaling максимум 65535 байт, это ограничение 16-битного поля в заголовке. На канале с большой задержкой этого катастрофически мало.
⏺Считается просто: пропускная способность = window size / RTT. Канал 1 Гбит, RTT 100мс, без scaling максимум 65535 / 0.1 = 655 Кбит/с. Гигабитный канал работает как мегабитный.
Window scaling добавляет множитель до 1073741824 байт. Согласовывается при TCP handshake через опцию WS.
Проверяем включён ли:
sysctl net.ipv4.tcp_window_scaling
ss -tin dst <IP> | grep wscale
sysctl -w net.ipv4.tcp_window_scaling=1
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
Настройка VLAN на Linux через systemd-networkd
systemd-networkd это не только для серверов без GUI, на практике удобнее nmcli для воспроизводимых конфигураций: файлы в /etc/systemd/network/, всё декларативно, легко версионировать в git.
Типичный сценарий: сервер подключён к trunk-порту коммутатора, нужно поднять несколько VLAN-интерфейсов с разными адресами.
Создаём VLAN-интерфейсы
Для каждого VLAN нужно два файла: .netdev описывает интерфейс, .network настраивает его.
VLAN 10:
# /etc/systemd/network/vlan10.netdev
[NetDev]
Name=eth0.10
Kind=vlan
[VLAN]
Id=10
# /etc/systemd/network/vlan10.network
[Match]
Name=eth0.10
[Network]
Address=192.168.10.1/24
Gateway=192.168.10.254
# /etc/systemd/network/eth0.network
[Match]
Name=eth0
[Network]
VLAN=eth0.10
VLAN=eth0.20
systemctl restart systemd-networkd
ip -d link show eth0.10
ip addr show eth0.10
networkctl status eth0.10
Настройка WireGuard: сервер, клиент, роутинг
WireGuard проще IPsec и OpenVPN по конфигурации, быстрее поднимается и меньше точек где можно ошибиться. Вот минимальная рабочая конфигурация.
Сервер
Генерируем ключи:
wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
[Interface]
PrivateKey = <server_private_key>
Address = 10.0.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = <client_public_key>
AllowedIPs = 10.0.0.2/32
sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
wg-quick up wg0
systemctl enable wg-quick@wg0
wg genkey | tee /etc/wireguard/client_private.key | wg pubkey > /etc/wireguard/client_public.key
[Interface]
PrivateKey = <client_private_key>
Address = 10.0.0.2/24
DNS = 1.1.1.1
[Peer]
PublicKey = <server_public_key>
Endpoint = <server_ip>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
wg-quick up wg0
wg show
ping 10.0.0.1
curl ifconfig.me
Что происходит когда OSPF area 0 теряет связность
Area 0 это backbone. Все остальные area обязаны быть физически или логически подключены к ней.
Если area 0 разваливается на части, OSPF не пересчитывает маршруты в обход, он просто перестаёт видеть часть сети.
show ip ospf neighbor
show ip ospf database
show ip ospf database summary
show ip route ospf
router ospf 1
area 1 virtual-link <router-id соседнего ABR>
Как ведёт себя сеть при split-brain в HSRP
Два роутера в HSRP обмениваются hello-пакетами каждые 3 секунды. Если связь между ними пропадает, каждый решает что сосед умер и становится Active.
Оба держат один виртуальный IP, оба отвечают на ARP-запросы своим MAC.
show standby brief
show standby
ping <IP соседнего роутера> source <интерфейс HSRP>
show interfaces trunk
show spanning-tree vlan <ID>
Ethernet OAM (802.1ag) с Linux и FRRouting
Ethernet OAM (Operations, Administration and Maintenance) по стандарту 802.1ag позволяет контролировать доступность и состояние линков на уровне L2.
На Linux можно использовать утилиты eth-oam для генерации OAM-сообщений (Continuity Check Messages, Loopback, Link Trace).
Пример проверки линка:
# Проверка доступности линка между хостами через CFM Continuity Check
eth-oam-ccm -i eth0 -m 1 -t 10
# Loopback запрос к соседнему устройству
eth-oam-lb -i eth0 -m 1
# Trace путь до узла через L2
eth-oam-lt -i eth0 -m 1 -d <MAC-адрес-соседа>
Почему MTU 1500 в реальности никогда не 1500. Часть 2
Почему фрагментация не всегда спасает: Когда пакет не влезает в MTU промежуточного узла, тот должен отправить отправителю ICMP Fragmentation Needed.
Отправитель получает сообщение, уменьшает размер сегмента и пробует снова. Это называется Path MTU Discovery и работает хорошо в теории.
tracepath 8.8.8.8
ping -M do -s 1400 8.8.8.8
ip link set dev tun0 mtu 1420
interface Dialer0
ip tcp adjust-mss 1452
Почему MTU 1500 в реальности никогда не 1500?
MTU 1500 это максимальный размер payload в Ethernet-фрейме. Цифра знакомая, но в реальной сети между твоим приложением и получателем почти всегда есть что-то, что откусывает от этого значения.
Иногда немного, иногда достаточно чтобы сломать крупные передачи.
PPPoE используют большинство провайдеров на последней миле. Протокол добавляет 8 байт заголовка к каждому фрейму, реальный MTU на интерфейсе становится 1492.
Proxy ARP: когда роутер отвечает на чужие ARP-запросы
Обычно на ARP-запрос “кто такой 192.168.1.50?” отвечает сам хост с этим IP. Proxy ARP меняет это поведение: роутер перехватывает запрос и отвечает своим MAC-адресом, как будто этот IP находится на нём. Хост отправляет трафик на роутер, роутер форвардит дальше.
Изначально это придумали для соединения подсетей без настройки маршрутов на конечных устройствах. Актуально было в эпоху когда маски подсетей на хостах не совпадали с реальной топологией.
show ip interface Gi0/0 | include proxy
interface Gi0/0
no ip proxy-arp
cat /proc/sys/net/ipv4/conf/eth0/proxy_arp
echo 0 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
BGP Blackholing: как быстро дропать DDoS-трафик на уровне сети
Когда на сервер идёт DDoS, стандартный ответ: заблокировать на фаерволе.
Сложность в том, что трафик всё равно доходит до твоего канала и забивает его. Blackholing решает это на уровень выше, трафик дропается ещё у провайдера или на границе сети.
Идея простая: анонсируешь BGP-соседу маршрут до атакуемого IP с community-тегом, который говорит “дропай этот трафик”. Провайдер получает анонс и перенаправляет трафик в null на своей стороне до того как он дошёл до тебя.
Как это выглядит на практике
Создаём статический маршрут в null и анонсируем его через BGP с нужным community (значение уточняется у провайдера, обычно это RTBH community):
ip route 203.0.113.5 255.255.255.255 Null0
route-map BLACKHOLE permit 10
set community 65535:666 additive
set local-preference 200
router bgp 65001
neighbor 198.51.100.1 route-map BLACKHOLE out
network 203.0.113.5 mask 255.255.255.255
show bgp ipv4 unicast 203.0.113.5
show bgp neighbors 198.51.100.1 advertised-routes
no ip route 203.0.113.5 255.255.255.255 Null0
clear ip bgp 198.51.100.1 soft out