sysctl — это интерфейс к параметрам ядра Linux, доступным через псевдо-ФС /proc/sys. Для админа это быстрый способ повлиять на сетевое поведение хоста: маршрутизацию, фильтрацию, очереди, таймауты и лимиты. Обычно проблема не в том, как выставить значение командой sysctl -w, а в том, как сделать это предсказуемо: чтобы настройки переживали перезагрузку, не конфликтовали с systemd и не превращались в «магические твики».
Ниже разберём, чем отличаются /etc/sysctl.conf и каталоги sysctl.d, что делает systemd-sysctl, как работает sysctl --system, и как оформлять переопределения (override) на примерах ip_forward, net.ipv4.conf.all.rp_filter и net.ipv4.tcp_tw_reuse.
Как устроен sysctl: runtime против persist
У любого sysctl-параметра есть два режима жизни:
- Временное (runtime) изменение — меняете значение в текущей системе, эффект сразу, но после перезагрузки пропадает.
- Постоянная (persist) настройка — храните значение в конфиге, оно применяется при старте (обычно через
systemd-sysctl).
Runtime: быстро проверить гипотезу
Удобно для диагностики и коротких экспериментов:
sysctl net.ipv4.ip_forward
sysctl -w net.ipv4.ip_forward=1
sysctl net.ipv4.ip_forward
Альтернатива через /proc работает, но обычно менее удобна в эксплуатации:
cat /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/ip_forward
Persist: фиксируем в файлах и применяем корректно
Чтобы настройка переживала перезагрузку, задавайте её в конфигурационных файлах sysctl. В systemd-дистрибутивах применением на старте управляет сервис systemd-sysctl: он читает набор файлов и записывает значения в /proc/sys.
systemd-sysctl: кто применяет параметры при старте
systemd-sysctl запускается на раннем этапе загрузки и применяет sysctl-значения из конфигов. Практически важны две вещи:
- Если вы меняете параметры только через
sysctl -w, то при следующей загрузке они вернутся к значениям из конфигов. - Если «sysctl не применяются», чаще всего виноваты порядок файлов, конфликт значений, неверный ключ или ограничение окружения (контейнер, namespace, отсутствие модуля).
Где systemd-sysctl ищет конфиги
В типичной системе участвуют:
/etc/sysctl.conf— исторический основной файл./etc/sysctl.d/*.conf— локальные настройки администратора (самое правильное место для override)./run/sysctl.d/*.conf— временные конфиги (их могут создавать пакеты/юниты на время рантайма)./usr/lib/sysctl.d/*.conf— дефолты пакетов и дистрибутива.
Файлы в /usr/lib/sysctl.d могут быть перезаписаны обновлением пакета, поэтому свои изменения держите в /etc/sysctl.d.
Порядок приоритета: «побеждает последний»
Если один и тот же параметр задан в нескольких местах, значение, прочитанное позже, перезапишет предыдущее. Порядок зависит и от каталога, и от имени файла (лексикографически).
Типовой приём: чтобы переопределить дефолт из /usr/lib/sysctl.d/50-default.conf, создайте /etc/sysctl.d/99-local.conf и задайте нужные ключи там.

sysctl --system: применить всё как при загрузке
sysctl --system применяет настройки из всех стандартных мест, фактически имитируя загрузочный сценарий. Это удобнее, чем перезагружаться после правки файла.
sysctl --system
Чтобы применить конкретный файл, используйте -p:
sysctl -p /etc/sysctl.conf
На практике удобнее держать свои параметры в отдельном файле и применять его явно:
sysctl -p /etc/sysctl.d/99-local.conf
Эксплуатационный совет: храните «боевые» sysctl-изменения в одном-двух файлах в
/etc/sysctl.d(например,99-network.conf,99-security.conf). Так проще аудировать, откатывать и объяснять коллегам.
Практика: включаем ip_forward (маршрутизация) правильно
ip_forward — это net.ipv4.ip_forward. Он разрешает ядру маршрутизировать IPv4-пакеты между интерфейсами. Типовые случаи: NAT, VPN-шлюз, роутер между подсетями.
Проверить текущее значение
sysctl net.ipv4.ip_forward
Включить временно
sysctl -w net.ipv4.ip_forward=1
Включить постоянно через sysctl.d override
Создайте файл, например /etc/sysctl.d/99-routing.conf:
net.ipv4.ip_forward = 1
Примените:
sysctl --system
Что часто забывают при ip_forward
- Маршрутизация ≠ NAT. Для «раздачи интернета» нужны правила firewall (nftables/iptables) и маскарадинг.
- Безопасность. Хост становится маршрутизатором, и ошибки в фильтрации трафика становятся критичнее. Проверьте политики FORWARD/INPUT/OUTPUT и межсегментный доступ.
Если это пограничный сервер, держите изменения инфраструктуры (sysctl, firewall, маршруты) в конфигурационном менеджменте и тестируйте на отдельном стенде. Для таких задач обычно удобнее использовать VDS, чтобы не мешать прикладным сервисам и иметь предсказуемую сетевую роль узла.
rp_filter: что делает и почему «ломает» асимметричные схемы
net.ipv4.conf.all.rp_filter — Reverse Path Filtering (проверка обратного пути). Ядро пытается убедиться, что адрес источника пакета «легитимен» с точки зрения маршрутизации: существует ли маршрут обратно к источнику.
Это полезно против спуфинга, но на серверах с несколькими интерфейсами, policy routing, асимметричными маршрутами, VRRP, некоторыми VPN-схемами и несколькими uplink’ами строгий режим часто приводит к «тихим» дропам входящих пакетов.
Режимы rp_filter (обычно 0/1/2)
0— выключено.1— strict: обратный маршрут должен идти через тот же интерфейс.2— loose: обратный маршрут должен существовать «где-то» в таблицах маршрутизации (мягче и часто практичнее).
Проверить значения
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.rp_filter
Есть и per-interface ключи: net.ipv4.conf.eth0.rp_filter и т.д. На практике важно понимать, как default влияет на новые интерфейсы, а также нет ли точечных override на конкретных NIC.
Компромиссный вариант для «нетривиальной» маршрутизации
Часто выбирают режим 2 (или отключают rp_filter на конкретных интерфейсах). Пример файла /etc/sysctl.d/99-rpfilter.conf:
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
Примените:
sysctl --system
Если после появления второго uplink/VPN «в одну сторону всё работает, а ответы пропадают» — проверяйте
rp_filterодним из первых.
tcp_tw_reuse: почему вокруг него столько мифов
net.ipv4.tcp_tw_reuse исторически использовали, когда на сервере много исходящих коротких TCP-соединений и копятся сокеты TIME_WAIT. Идея — разрешить более раннее переиспользование локальных портов для новых исходящих подключений.
Однако в современных ядрах и сетевых сценариях это не «универсальный ускоритель»:
- Эффект зависит от того, кто инициирует соединение, от NAT, TCP timestamps и поведения удалённой стороны.
- Неправильное применение может дать плавающие проблемы: неожиданные RST, редкие ошибки на пике, нестабильность через NAT.
- Часто правильнее устранить причину: расширить диапазон ephemeral-портов, включить пул соединений на уровне приложения, настроить keepalive, уменьшить лишние ретраи.
Сначала соберите фактуру
ss -s
ss -tan state time-wait | wc -l
cat /proc/sys/net/ipv4/ip_local_port_range
Более безопасный первый шаг: ip_local_port_range
Проверьте текущий диапазон:
sysctl net.ipv4.ip_local_port_range
Пример persist-настройки (подбирайте значения под свою систему) в /etc/sysctl.d/99-ephemeral-ports.conf:
net.ipv4.ip_local_port_range = 20000 60999
И только если проблема подтверждается метриками и воспроизводится, тестируйте tcp_tw_reuse на стенде под нагрузкой.
Если всё же включаете tcp_tw_reuse
Делайте это как управляемый эксперимент: отдельный файл, короткий комментарий и понятный план отката.
Файл /etc/sysctl.d/99-tcp-tw.conf:
net.ipv4.tcp_tw_reuse = 1
Применение:
sysctl --system
Откат (временно):
sysctl -w net.ipv4.tcp_tw_reuse=0
Откат (постоянно): удалите или измените файл и снова выполните sysctl --system.
Как диагностировать «почему sysctl не применился»
Симптом: вы прописали значение в конфиге, но после перезагрузки оно «не то». Проверки, которые обычно быстрее всего находят причину:
1) Убедиться, что параметр существует и доступен
sysctl -a 2>/dev/null | grep -F net.ipv4.ip_forward
Если ключа нет, он может быть недоступен в контейнере, находиться в другом namespace, быть устаревшим или зависеть от загрузки модуля.
2) Найти конфликты: кто задаёт параметр ещё
grep -R --line-number --fixed-strings "net.ipv4.ip_forward" /etc/sysctl.conf /etc/sysctl.d /usr/lib/sysctl.d /run/sysctl.d 2>/dev/null
Если ключ встречается несколько раз, определитесь с «истиной»: оставьте значение в одном месте (обычно /etc/sysctl.d/99-*.conf), дубли удалите.
3) Применить заново и посмотреть ошибки
sysctl --system
Ошибки чтения/записи укажут направление: недоступный ключ, права, ограничения namespace, неверный порядок появления интерфейсов.
4) Проверить systemd-sysctl
systemctl status systemd-sysctl
Если в логах есть ошибки, разберите их: «шум» от старых ключей и конфликтов почти всегда сигнализирует о техдолге в sysctl-конфигах.
Рекомендованный шаблон организации sysctl на сервере
- Не правьте файлы в
/usr/lib/sysctl.d. - Держите локальные изменения в
/etc/sysctl.dс понятными именами:99-routing.conf,99-security.conf,99-tcp.conf. - Оставляйте короткие комментарии: зачем параметр, какой сервис затрагивает и как проверять регрессию.
- Применяйте изменения через
sysctl --systemи фиксируйте результат (значения и метрики).
Если вы делаете комплексную сетевую настройку, полезно иметь отдельную памятку по «сетевым твикам» и их проверке. Смотрите также практические приёмы sysctl для сетевой оптимизации.
Мини-набор примеров: один файл для типового шлюза
Если сервер выполняет роль шлюза и вы хотите разумно настроить rp_filter, можно собрать настройки в один конфиг /etc/sysctl.d/99-gateway.conf:
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
Применение:
sysctl --system
На практике ip_forward часто идёт рядом с IPv6-настройками и проверкой AAAA-записей/фаервола. Если у вас смешанная IPv4/IPv6-сеть, полезно сверить типовые ошибки в статье как связаны IPv6, AAAA и правила firewall на сервере.

Частые ошибки и как их избегать
Править /etc/sysctl.conf как «единственный источник истины»
Технически можно, но в systemd-окружении с пакетными дефолтами быстро появляется смесь источников: часть параметров задаётся в /usr/lib/sysctl.d, часть — в /etc/sysctl.conf, часть — в /etc/sysctl.d. Обычно проще сопровождать явно выделенный файл (например, /etc/sysctl.d/99-local.conf).
Включить ip_forward и забыть про фильтрацию
Маршрутизация без политики firewall — риск. Даже если «у нас закрыты порты», FORWARD-цепочка может стать неожиданным маршрутом между сегментами.
Включить tcp_tw_reuse без измерений
Если проблема — нехватка исходящих портов, сначала смотрят на ip_local_port_range, поведение приложений (keepalive/pool), и на то, нет ли агрессивных таймаутов/ретраев. tcp_tw_reuse — не универсальная таблетка.
Итог
sysctl — мощный инструмент, а systemd-sysctl делает его изменения воспроизводимыми после перезагрузок. Здоровая практика: тестируйте изменения runtime, оформляйте их в /etc/sysctl.d как override, применяйте через sysctl --system, и привязывайте каждый параметр к измеримому эффекту и понятному сценарию.
Для маршрутизации начинайте с ip_forward и аккуратного rp_filter. А к tcp_tw_reuse относитесь как к опции для редких случаев, где проблема подтверждена метриками и воспроизводится под нагрузкой.


