Сети в Linux: от основ до продвинутой диагностики
ip и iproute2: современная работа с сетью
Команда ifconfig устарела. Всё что нужно — в пакете iproute2:
# Интерфейсы и адреса
ip addr show
ip addr show eth0
ip -4 addr # только IPv4
ip -6 addr # только IPv6
# Добавить/удалить IP
ip addr add 192.168.1.100/24 dev eth0
ip addr del 192.168.1.100/24 dev eth0
# Маршруты
ip route show
ip route add default via 192.168.1.1
ip route add 10.0.0.0/8 via 10.100.0.1 dev eth1
ip route del 10.0.0.0/8
# ARP таблица
ip neigh show
ip neigh flush all
# Статистика интерфейсов
ip -s link show eth0
# Состояние соединений
ss -tnp # TCP с процессами
ss -tlnp # только слушающие
ss -u # UDP
ss -x # Unix sockets
ss -tnp state established # установленные
ss -tnp state time-wait # TIME_WAIT
ss -s # сводная статистика
Диагностика сетевых проблем
# Трассировка маршрута
traceroute -n google.com # числовые адреса, быстрее
mtr --report google.com # интерактивный traceroute
# DNS диагностика
dig google.com
dig @8.8.8.8 google.com # конкретный DNS
dig google.com MX # MX записи
dig -x 8.8.8.8 # reverse lookup
nslookup google.com
host google.com
# Захват трафика
tcpdump -i eth0 port 80
tcpdump -i eth0 host 10.0.0.1
tcpdump -i eth0 -w capture.pcap # запись в файл
tcpdump -r capture.pcap # чтение из файла
# Тест пропускной способности
iperf3 -s # сервер
iperf3 -c server-ip # клиент
iperf3 -c server-ip -P 4 # 4 параллельных потока
# Latency
ping -c 10 -i 0.2 server-ip
hping3 -S -p 80 -c 10 server-ip # TCP ping
Виртуальные сети: bridge, vlan, veth
# VLAN
ip link add link eth0 name eth0.100 type vlan id 100
ip addr add 192.168.100.1/24 dev eth0.100
ip link set dev eth0.100 up
# Bridge (для виртуальных машин)
ip link add br0 type bridge
ip link set eth0 master br0
ip link set br0 up
ip addr add 192.168.1.10/24 dev br0
# veth пара (для контейнеров)
ip link add veth0 type veth peer name veth1
ip link set veth1 netns container-ns
# Bonding (агрегация каналов)
ip link add bond0 type bond mode active-backup
ip link set eth0 master bond0
ip link set eth1 master bond0
ip link set bond0 up
nftables: полный конфиг для веб-сервера
#!/usr/sbin/nft -f
flush ruleset
define WEB_PORTS = { 80, 443 }
define SSH_PORT = 2222
define TRUSTED_IPS = { 10.0.0.0/8, 192.168.0.0/16 }
table inet filter {
# Счётчики для статистики
counter ssh_allowed {}
counter web_traffic {}
counter dropped {}
set banned_ips {
type ipv4_addr
flags timeout
timeout 1d
}
chain input {
type filter hook input priority 0; policy drop;
# Заблокированные IP
ip saddr @banned_ips drop
# Established/related
ct state established,related accept
ct state invalid drop
# Loopback
iif "lo" accept
# ICMP (ограниченно)
ip protocol icmp icmp type { echo-request, echo-reply, destination-unreachable, time-exceeded } limit rate 10/second accept
ip6 nexthdr icmpv6 accept
# SSH с ограничением скорости (защита от brute-force)
tcp dport $SSH_PORT ct state new limit rate 3/minute counter name ssh_allowed accept
tcp dport $SSH_PORT ct state new counter name dropped drop
# HTTP/HTTPS
tcp dport $WEB_PORTS counter name web_traffic accept
# Внутренние сервисы только с доверенных IP
ip saddr $TRUSTED_IPS tcp dport { 3306, 6379, 9100 } accept
log prefix "nft-drop: " flags all
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
# Rate limiting для защиты от DDoS
table inet mangle {
chain prerouting {
type filter hook prerouting priority -150;
# SYN flood protection
tcp flags syn tcp option maxseg size 1-500 drop
# Новые TCP соединения: не более 100 в секунду с одного IP
tcp flags syn ct state new \
meter syn_flood { ip saddr limit rate 100/second } \
accept
tcp flags syn ct state new drop
}
}
Файловые системы Linux: выбор, настройка, оптимизация
Обзор файловых систем
ФС | Сильные стороны | Слабые стороны | Применение |
|---|---|---|---|
ext4 | Стабильность, скорость | Нет встроенного RAID | Общее назначение |
XFS | Большие файлы, параллелизм | Нельзя уменьшить | Медиа, базы данных |
Btrfs | Снэпшоты, сжатие, RAID | Сложность | Разработка, NAS |
ZFS | Надёжность, снэпшоты | Память, лицензия | Продакшн NAS |
tmpfs | Скорость (RAM) | Нет персистентности | /tmp, кэш |
Монтирование и /etc/fstab
# Посмотреть текущие точки монтирования
df -hT
mount | column -t
findmnt # дерево монтирований
# Временное монтирование
mount -t ext4 /dev/sdb1 /mnt/data
mount -o remount,ro / # перемонтировать только для чтения
# /etc/fstab — правильный формат:
# UUID=xxx /data ext4 defaults,noatime,nodiratime 0 2
#
# Важные опции:
# noatime — не обновлять время доступа (производительность!)
# nodiratime — то же для директорий
# relatime — компромисс: обновляем только если mtime новее atime
# nodev — нет устройств (безопасность для /home)
# nosuid — нет suid бит (безопасность)
# noexec — нет выполнения (для /var/tmp)
# Получить UUID
blkid /dev/sdb1
# Монтирование tmpfs (RAM-диск)
# tmpfs /tmp tmpfs defaults,noatime,nosuid,size=2G 0 0
Производительность ext4
# Опции при создании (важно для SSD!)
mkfs.ext4 -b 4096 -E stride=128,stripe-width=128 /dev/sdb1
# stride = chunk_size / block_size (для RAID)
# Настройка журналирования
# data=writeback — самый быстрый, менее безопасный
# data=ordered — дефолт, баланс
# data=journal — самый безопасный, самый медленный
tune2fs -o journal_data_writeback /dev/sdb1
# Отключение fsck при загрузке (для SSD)
tune2fs -i 0 -c 0 /dev/sdb1
# Дефрагментация ext4 (редко нужно)
e4defrag -c /dev/sdb1 # только анализ
e4defrag /dev/sdb1 # дефрагментация
# Resize2fs — изменение размера
resize2fs /dev/sdb1 20G # уменьшить (только для ext2/3/4)
resize2fs /dev/sdb1 # расширить до максимума
Btrfs: продвинутые функции
# Создание с несколькими устройствами
mkfs.btrfs -d raid1 /dev/sdb /dev/sdc # RAID1 для данных
# Создание снэпшота
btrfs subvolume create /data/subvol
btrfs subvolume snapshot /data/subvol /data/subvol-snap-$(date +%Y%m%d)
# Только для чтения (для бэкапов)
btrfs subvolume snapshot -r /data/subvol /data/backups/snap-$(date +%Y%m%d)
# Отправка снэпшота на другой сервер
btrfs send /data/backups/snap-20240101 | ssh backup-server "btrfs receive /backups/"
# Инкрементальный бэкап
btrfs send -p /data/backups/snap-20240101 /data/backups/snap-20240102 | \
ssh backup-server "btrfs receive /backups/"
# Сжатие
btrfs filesystem defragment -r -czstd /data # сжать существующее
# В fstab: compress=zstd:3
# Статистика
btrfs filesystem show
btrfs filesystem df /data
btrfs scrub start /data # проверка целостности
LVM: гибкое управление томами
# Структура: Physical Volumes → Volume Groups → Logical Volumes
# Создание PV
pvcreate /dev/sdb /dev/sdc
pvdisplay
pvs
# Volume Group
vgcreate vg_data /dev/sdb /dev/sdc
vgdisplay
vgs
# Logical Volume
lvcreate -L 50G -n lv_mysql vg_data
lvcreate -l 100%FREE -n lv_data vg_data # всё свободное место
lvdisplay
lvs
# Форматирование и монтирование
mkfs.ext4 /dev/vg_data/lv_mysql
# Расширение онлайн!
lvextend -L +20G /dev/vg_data/lv_mysql
resize2fs /dev/vg_data/lv_mysql # для ext4
# Снэпшоты LVM (для backup без даунтайма)
lvcreate -L 5G -s -n lv_mysql_snap /dev/vg_data/lv_mysql
mount /dev/vg_data/lv_mysql_snap /mnt/backup
# Делаем бэкап из /mnt/backup
lvremove /dev/vg_data/lv_mysql_snap
# Добавить новый диск в VG
pvcreate /dev/sdd
vgextend vg_data /dev/sdd
Docker и контейнеризация в Linux
Пространства имён: основа изоляции
Контейнеры — это не виртуальные машины, это изоляция через Linux namespaces:
# Типы namespaces
# pid — изоляция процессов
# net — изоляция сети
# mnt — изоляция точек монтирования
# uts — hostname и domainname
# ipc — IPC (очереди сообщений, семафоры)
# user — пользователи и группы
# cgroup — изоляция cgroups
# Создать отдельное сетевое пространство (вручную, как делает Docker)
ip netns add myns
ip netns exec myns ip link list
ip netns exec myns bash # shell внутри namespace
Docker: производительность и безопасность
# Просмотр ресурсов контейнеров
docker stats --no-stream
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
# Ограничение ресурсов
docker run -d \
--name myapp \
--memory="512m" \
--memory-swap="1g" \
--cpus="0.5" \
--pids-limit=100 \
myapp:latest
# Security options
docker run -d \
--security-opt no-new-privileges:true \
--security-opt seccomp=/etc/docker/seccomp.json \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--read-only \
--tmpfs /tmp:size=100m \
myapp:latest
Docker daemon оптимизация
/etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "5"
},
"storage-driver": "overlay2",
"storage-opts": ["overlay2.override_kernel_check=true"],
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 65536,
"Soft": 65536
}
},
"live-restore": true,
"userland-proxy": false,
"experimental": false,
"metrics-addr": "127.0.0.1:9323",
"max-concurrent-downloads": 5
}
Многоэтапные Dockerfile для PHP
# Stage 1: Зависимости
FROM composer:2 AS deps
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts
# Stage 2: Production image
FROM php:8.2-fpm-alpine
# Устанавливаем только нужные расширения
RUN apk add --no-cache \
libpng-dev \
libjpeg-turbo-dev \
libwebp-dev \
&& docker-php-ext-configure gd --with-jpeg --with-webp \
&& docker-php-ext-install -j$(nproc) \
pdo_mysql \
redis \
gd \
opcache \
intl \
&& rm -rf /var/cache/apk/*
# Копируем зависимости из предыдущего этапа
COPY --from=deps /app/vendor /var/www/html/vendor
# Копируем только нужные файлы
COPY --chown=www-data:www-data app/ /var/www/html/app/
COPY --chown=www-data:www-data public/ /var/www/html/public/
# PHP конфиг для продакшна
COPY docker/php.ini /usr/local/etc/php/conf.d/99-production.ini
COPY docker/www.conf /usr/local/etc/php-fpm.d/www.conf
# Непривилегированный пользователь
USER www-data
EXPOSE 9000
CMD ["php-fpm"]
Docker Compose для dev-среды
version: '3.9'
services:
app:
build:
context: .
dockerfile: Dockerfile
target: deps # используем только dev зависимости
volumes:
- .:/var/www/html:cached # cached ускоряет macOS
- /var/www/html/vendor # исключаем vendor из маппинга
environment:
APP_ENV: local
DB_HOST: db
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- .:/var/www/html:cached
depends_on:
- app
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 3s
retries: 10
redis:
image: redis:7-alpine
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
mysql_data:
SSH: продвинутые возможности
SSH туннели: три типа
Local forwarding — пробрасываем удалённый порт локально
# Доступ к MySQL на сервере через локальный порт
ssh -L 3307:localhost:3306 user@remote-server
# Теперь подключаемся локально
mysql -h 127.0.0.1 -P 3307 -u myapp -p
# В фоне, без терминала
ssh -fNL 3307:localhost:3306 user@remote-server
Remote forwarding — пробрасываем локальный порт на сервер
# Даём серверу доступ к нашему локальному сервису (для демо, CI/CD)
ssh -R 8080:localhost:3000 user@remote-server
# На сервере: curl http://localhost:8080 → ваш локальный порт 3000
Dynamic forwarding — SOCKS5 прокси
# Весь трафик через сервер
ssh -D 1080 user@remote-server
# Настраиваем браузер на SOCKS5 proxy: localhost:1080
# В автоматическом режиме
ssh -fND 1080 user@remote-server
~/.ssh/config: удобная конфигурация
# Глобальные настройки
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 10m # переиспользовать соединение 10 минут
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
# Продакшн
Host prod-web01
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519_prod
Host prod-db01
HostName 10.0.0.5 # внутренний IP
User dbadmin
ProxyJump prod-web01 # прыгаем через web01
# Staging
Host staging
HostName staging.example.com
User deploy
LocalForward 3307 localhost:3306 # автоматический туннель к MySQL
# Wildcard для dev-серверов
Host dev-*
User vagrant
StrictHostKeyChecking no
UserKnownHostsFile /dev/null # не сохраняем fingerprint для dev
# Мультиплексирование — одно TCP соединение для нескольких сессий
mkdir -p ~/.ssh/sockets
# Теперь второй ssh к тому же хосту использует уже открытое соединение
ssh prod-web01 # открывает новое соединение
ssh prod-web01 # переиспользует существующее (мгновенно!)
ssh prod-web01 ls /var/log # команда через существующее соединение
SSH-агент и управление ключами
# Запуск агента
eval $(ssh-agent -s)
# Добавляем ключ с таймаутом
ssh-add -t 3600 ~/.ssh/id_ed25519 # 1 час
# Просмотр ключей в агенте
ssh-add -l
# Переброска агента на удалённый сервер
ssh -A user@server # ForwardAgent yes в конфиге
# Или через конфиг:
# Host prod-*
# ForwardAgent yes
# Hardware token (YubiKey)
# ssh-keygen -t ecdsa-sk # создать ключ на YubiKey
Копирование файлов: rsync через SSH
# Основной синтаксис
rsync -avz --progress source/ user@server:/destination/
# Полезные опции
rsync -avz \
--delete \ # удалять на приёмнике то, чего нет в источнике
--exclude='*.log' \
--exclude='.git' \
--exclude='node_modules' \
--checksum \ # сравнивать по контрольной сумме, не по времени
--backup \ # бэкап изменённых файлов
--backup-dir=/backup/$(date +%Y%m%d) \
/var/www/myapp/ user@backup-server:/backups/myapp/
# Синхронизация через нестандартный порт
rsync -avz -e "ssh -p 2222" source/ user@server:/dest/
# Dry run — что будет сделано без фактических изменений
rsync -avzn source/ user@server:/dest/
Ядро Linux: мониторинг и тюнинг
/proc и /sys: окна в ядро
# Информация о системе
cat /proc/version
cat /proc/cpuinfo | grep -E "processor|model name|cpu MHz" | head -20
cat /proc/meminfo
cat /proc/loadavg
cat /proc/uptime
# Текущие сетевые соединения ядра
cat /proc/net/tcp # hex, неудобно, лучше ss
# Статистика прерываний
cat /proc/interrupts
watch -n1 cat /proc/interrupts
# I/O статистика
cat /proc/diskstats
# Параметры ядра (sysctl)
sysctl -a | grep vm
sysctl -a | grep net.ipv4.tcp
# /sys — дерево устройств
ls /sys/class/net/ # сетевые интерфейсы
ls /sys/block/ # блочные устройства
cat /sys/block/sda/queue/scheduler
echo 512 > /sys/block/sda/queue/nr_requests # изменяем параметр
Настройка планировщика задач CPU
# Текущий планировщик
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# Доступные governors
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
# conservative ondemand userspace powersave performance schedutil
# Для сервера: performance или schedutil
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
# Закрепляем через /etc/default/grub:
# GRUB_CMDLINE_LINUX="cpufreq.default_governor=performance"
# NUMA балансировка
cat /proc/sys/kernel/numa_balancing
echo 1 > /proc/sys/kernel/numa_balancing
# Transparent Huge Pages
cat /sys/kernel/mm/transparent_hugepage/enabled
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
# Watchdog (отключаем на виртуалках для экономии)
echo 0 > /proc/sys/kernel/nmi_watchdog
Параметры ядра для highload (полный sysctl)
# /etc/sysctl.d/99-highload.conf
##########################
# VM
##########################
vm.swappiness = 10
vm.dirty_ratio = 20
vm.dirty_background_ratio = 5
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.overcommit_memory = 1 # для Redis: разрешаем overcommit
vm.max_map_count = 262144 # для Elasticsearch
##########################
# NET: буферы
##########################
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.netdev_max_backlog = 65535
net.core.somaxconn = 65535
##########################
# NET: TCP
##########################
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_mem = 786432 1048576 26777216
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.ip_local_port_range = 1024 65535
# ECN — явное уведомление о перегрузке
net.ipv4.tcp_ecn = 1
# Fast Open (повторное использование рукопожатия)
net.ipv4.tcp_fastopen = 3
##########################
# Безопасность
##########################
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.log_martians = 1
kernel.randomize_va_space = 2
sysctl -p /etc/sysctl.d/99-highload.conf
# Проверяем что применилось
sysctl net.ipv4.tcp_congestion_control
sysctl vm.swappiness
Анализ паник и OOM
# Последняя паника ядра
journalctl -k -b -1 | grep -A 50 "Oops:"
# OOM killer
journalctl -k | grep -i "oom\|out of memory"
dmesg | grep -i oom
# Kernel panic dump (kdump)
apt install kdump-tools
# После паники дамп будет в /var/crash/
# Анализ crash dump
apt install crash
crash /usr/lib/debug/boot/vmlinux-$(uname -r) /var/crash/vmcore
# Команды внутри crash:
# bt — backtrace
# log — kernel log buffer
# ps — процессы в момент паники
Linux — это айсберг. Большинство из нас видит только надводную часть: файлы, процессы, сеть. Но под водой — целый мир механизмов, которые делают его надёжной основой для миллиардов устройств. Понимание этих механизмов — отличие хорошего администратора от великого.
Create an account or sign in to leave a review
There are no reviews to display.