Net ipv4 tcp syncookies

Net ipv4 tcp syncookies

В сети много разных примеров конфигурации ядра Linux для обеспечения большого количества tcp соединений, для высоко-нагруженных веб проектов и противостояния DDoS-атакам. ниже еще один из примеров, реально использующийся на не которых из серверов, которыми я занимаюсь. Стоит отметить, что — это спасение от всего, а лишь часть настройки о которой стоит помнить.

Правим sysctl.conf

Обычно файл /etc/sysctl.conf — пустой, а если нет. Необходимо добавить в конец файла следующие строки.

Не принимать и не отправлять ICMP-пакеты перенаправления. ICMP-перенаправления могут быть использованы злоумышленником для изменения таблиц маршрутизации. Целесообразно установить значение (нуль). Единица имеет смысл только для хостов, использующихся в качестве маршрутизаторов.

Целочисленное значение параметра tcp_max_orphans определяет максимальное число допустимых в системе TCP сокетов, не связанных каким-либо идентификатором пользовательского файла (user file handle). При достижении порогового значения "осиротевшие" (orphan) соединения незамедлительно сбрасываются с выдачей предупреждения. Этот порог помогает предотвращать только простые атаки DDoS. Не следует уменьшать пороговое значение (скорее увеличить его в соответствии с требованиями системы — например, после добавления памяти. Каждое orphan-соединение поглощает около 64 Кбайт не сбрасываемой на диск (unswappable) памяти>.

Параметр tcp_fin_timeout определяет время сохранения сокета в состоянии FIN-WAIT-2 после его закрытия локальной стороной. Партнер может не закрыть это соединение никогда, поэтому следует закрыть его по своей инициативе по истечении тайм-аута. По умолчанию тайм-аут составляет 60 секунд. В ядрах серии 2.2 обычно использовалось значение 180 секунд и вы можете сохранить это значение, но не следует забывать, что на загруженных WEB-серверах вы рискуете израсходовать много памяти на сохранение полуразорванных мертвых соединений. Сокеты в состоянии FIN-WAIT-2 менее опасны, нежели FIN-WAIT-1, поскольку поглощают не более 1.5 Кбайт памяти, но они могут существовать дольше.

tcp_keepalive_time — переменная определяет как часто следует проверять соединение, если оно давно не используется. Значение переменной имеет смысл только для тех сокетов, которые были созданы с флагом SO_KEEPALIVE. Целочисленная переменная tcp_keepalive_intvl определяет интервал передачи проб. Произведение tcp_keepalive_probes * tcp_keepalive_intvl определяет время, по истечении которого соединение будет разорвано при отсутствии откликов. По умолчанию установлен интервал 75 секунд, т.е., время разрыва соединения при отсутствии откликов составит приблизительно 11 минут.

Целочисленное значение в файле tcp_max_syn_backlog определяет максимальное число запоминаемых запросов на соединение, для которых не было получено подтверждения от подключающегося клиента. Если на сервере возникают перегрузки, можно попытаться увеличить это значение.

Целочисленное значение (1 байт) tcp_synack_retries определяет число попыток повтора передачи пакетов SYNACK для пассивных соединений TCP. Число попыток не должно превышать 255. Значение 5 соответствует приблизительно 180 секундам на выполнение попыток организации соединения.

Векторная переменная net.ipv4.tcp_mem определяется тремя значениями (минимум, режим нагрузки, максимум) cодержит общие настройки потребления памяти для протокола TCP. Эта переменная измеряется в страницах (обычно 4Кб), а не байтах.

  1. Минимум: пока общий размер памяти для структур протокола TCP менее этого количества страниц, операционная система ничего не делает.
  2. Режим нагрузки: как только количество страниц памяти, выделенное для работы протокола TCP, достигает этого значения, активируется режим работы под нагрузкой, при котором операционная система старается ограничивать выделение памяти. Этот режим сохраняется до тех пор, пока потребление памяти опять не достигнет минимального уровня.
  3. Максимум: максимальное количество страниц памяти, разрешенное для всех TCP сокетов.

Векторная переменная net.ipv4.tcp_wmem содержит 3 целых числа (минимум, по умолчанию, максимум), определяющих размер приемного буфера сокетов TCP.

  1. Минимум: каждый сокет TCP имеет право использовать эту память по факту своего создания. Возможность использования такого буфера гарантируется даже при достижении порога ограничения (moderate memory pressure). Размер минимального буфера по умолчанию составляет 8 Кбайт (8192).
  2. Значение по умолчанию: количество памяти, допустимое для буфера передачи сокета TCP по умолчанию. Это значение применяется взамен параметра /proc/sys/net/core/rmem_default, используемого другими протоколами. Значение используемого по умолчанию буфера обычно (по умолчанию) составляет 87830 байт. Это определяет размер окна 65535 с заданным по умолчанию значением tcp_adv_win_scale и tcp_app_win = 0, несколько меньший, нежели определяет принятое по умолчанию значение tcp_app_win.
  3. Максимум: максимальный размер буфера, который может быть автоматически выделен для приема сокету TCP. Это значение не отменяет максимума, заданного в файле /proc/sys/net/core/rmem_max. При "статическом" выделении памяти с помощью SO_RCVBUF этот параметр не имеет значения.

Целочисленной значение tcp_orphan_retries определяет число неудачных попыток, после которого уничтожается соединение TCP, закрытое на локальной стороне. По умолчанию используется значение 7, соответствующее приблизительно периоду от 50 секунд до 16 минут в зависимости от RTO. На сильно загруженных веб-серверах имеет смысл уменьшить значение этого параметра, поскольку закрытые соединения могут поглощать достаточно много ресурсов.

Параметр — tcp_syncookies по рекомендациям разработчиков ядра, лучше отключить значение (нуль).

Максимальное количество соединений для работы механизма connection tracking (используется, например, iptables). При слишком маленьких значениях ядро начинает отвергать входящие подключения с соответствующей записью в системном логе.

Разрешает временные метки протокола TCP. Их наличие позволяет управлять работой протокола в условиях серьезных нагрузок.

Разрешить выборочные подтверждения протокола TCP. Опция необходима для эффективного использования всей доступной пропускной способности некоторых сетей.

Протокол, используемый для управления нагрузкой в сетях TCP. bic и cubic реализации, используемые по умолчанию, содержат баги в большинстве версий ядра RedHat и ее клонов. Рекомендуется использовать параметр htcp.

Не сохранять результаты измерений TCP соединения в кеше при его закрытии. В некоторых случаях помогает повысить производительность.

Актуально для ядер 2.4. По странной причине в ядрах 2.4, если в рамках TCP сессии произошел повтор передачи с уменьшенным размером окна, все соединения с данным хостом в следующие 10 минут будут иметь именно этот уменьшенный размер окна. Данная настройка позволяет этого избежать.

Активируем защиту от IP-спуфинга.

Запрещаем маршрутизацию от источника.

Увеличиваем диапазон локальных портов, доступных для установки исходящих подключений.

Разрешаем повторное использование TIME-WAIT сокетов в случаях, если протокол считает это безопасным.

Разрешаем динамическое изменение размера окна TCP стека.

Защищаемся от TIME_WAIT атак.

Запрещаем переадресацию пакетов, т.к. это не роутер.

Не отвечаем на ICMP ECHO запросы, переданные широковещательными пакетами.

Можно вообще не отвечать на ICMP ECHO запросы (сервер не будет пинговаться)

Не отвечаем на ошибочно сформированные сообщения

Максимальное число открытых сокетов, ждущих соединения. Имеет смысл увеличить значение по умолчанию.

Параметр определяет максимальное количество пакетов в очереди на обработку, если интерфейс получает пакеты быстрее, чем ядро может их обработать.

Размер буфера приема данных по умолчанию для всех соединений.

Размер буфера передачи данных по умолчанию для всех соединений.

Максимальный размер буфера приема данных для всех соединений.

Максимальный размер буфера передачи данных для всех соединений.

Очень часто администраторы выполняют настройку системы просто настройкой базовых вещей — ip,dns,hostname, поставить софт, а все остальное уже настройки приложений. В большинстве случаев так оно и есть, поскольку в linux’е очень разумные умолчания и, в большинстве случаев, этих умолчаний хватает и все живут счастливо. Среди совсем начинающих ходят легенды о неких sysctl’ях, а те, кто поопытнее видели и даже чего-то правили.

Но приходит момент, когда админ в своих походах по системе встречает этого зверя — sysctl. Вероятнее всего он встречает кого-то из семейства net.ipv4 или vm, даже вероятнее всего net.ipv4.ip_forward, если поход за роутером или vm.swappinness, если он обеспокоен подросшим swap’ом своего пингвина. Первый зверь разрешает пингвину принимать пакеты одним крылом и отдавать другим (разрешает маршрутизацию), а второй помогает справиться с использованием swap’а в спокойной системе и регулировать его использование — в нагруженной.

Читайте также:  0X8024001e ошибка обновления windows 10

Встреча с любым из этих “зверей” открывает ворота в целый мир настроек системы и компонентов ядра, существует несколько семейств, названия большинства которых говорят сами за себя: net — сеть; kern — ядро; vm — память и кэши. Но это всё “сказка”, реальность гораздо интереснее.

Познакомившись с этим сонмом настроек неопытный администратор, как мотылек на свет, летит и хочет скорее-скорее их все настроить, сделать систему лучше и оптимальнее. О, да! Соблазн его велик и цель хороша, но выбранный путь, подчас, приводит в совсем другую сторону. Имя тому пути “гуглотюнинг”.

Ведь каков соблазн быстренько загуглить “оптимальные настройки sysctl” и применить какой-нибудь рецепт из начала статьи не особо вдаваясь в то, что написано ниже — там же TL;DR. Системе в большинстве случаев и хуже то не становится, потому что нагрузка или конфигурация не та, чтобы проблемы всплыли. Это потом уже, с опытом, копаясь в настройках системы по какому-то конкретному случаю, поймешь, что это какой-то бред был написан.

Вот, к примеру, параметры net.ipv4.tcp_mem,rmem,wmem — выглядят очень похоже, три числа типа “4096 87380 6291456”, только, вот незадача, для [rw]mem это байты, а для mem — страницы и, если задать всем трём параметрам, одинаковое значение, то будет “взрывоопасная” конфигурация, т.к. tcp_mem отвечает за управление памятью потребляемой tcp, а [rw]mem за буфера сокета.

А бывают sysctl’и которые, пока не встретишь и не огребёшь — не задумаешься о чем этот sysctl, как, к примеру, net.ipv4.conf.all.rp_filter. Злейшая штука, которая стреляет только тогда, когда у вас возникает необходимость делать ассиметричные маршруты, то есть, у вашего маршрутизатора 2+ интерфейса и трафик может прийти с одного интерфейса, а вернуться через другой, то есть достаточно редко. Называется Reverse Path Filtering, блокирует пакеты которые приходят с адреса, который не маршрутизируется через интерфейс откуда они приходят.
Бывают параметры очень полезные, но требующие вдумчивого изучения документации и расчетов, чтобы выяснить, как они вам могут помочь в вашей конкретной ситуации. Повторюсь, что умолчания в linux’е, достаточно хорошие. В особенности это касается настроек tcp и сети в целом.

Параметры же которыми приходится играться достаточно часто это:

vm.swappiness — настройка агрессивности “высвапливания” памяти. Это нужно для того, чтобы поддерживать как можно больший объем оперативной памяти доступным для приложений и работы. В значении по умолчанию — 60 система переводит в swap те страницы памяти, которые не использовались в течении какого-то продолжительного времени, в значении 0 или 1 — система старается использовать своп только когда не может аллоцировать физическую память или когда объем доступной памяти подходит к указанному в vm.min_free_kbytes. Нельзя сказать, что использование свопа однозначно хорошо или плохо. Все зависит от ситуации и профиля использования памяти, а эта ручка позволяет нам управлять отношением системы к свопу от 0 — совсем не нравится, до 100 — о да, своооп!

vm.min_free_kbytes — (раз уж упомянут в vm.swappiness) Определяет минимальный размер свободной памяти который необходимо поддерживать. Если установить слишком маленьким — система сломается, если слишком большим — будет часто приходить OOM(Out Of Memory) killer.

vm.overcommit_memory — разрешает/запрещает “аллоцировать” памяти больше чем есть: 0 — система каждый раз проверяет есть ли достаточное количество свободной памяти; 1 — система всегда полагает, что память есть и разрешает аллокацию пока память действительно есть; 2 — запретить просить памяти больше чем есть — аллоцировать можно не больше чем RAM + SWAP. Это может выстрелить когда у вас есть приложение, например redis, которое потребляет > ½ памяти и решает записать на диск данные, для чего форкается и копирует все данные, но т.к доступной памяти может не хватить — может либо сломаться запись на диск, либо прийти OOM и убить что-то нужное.

net.ipv4.ip_forward — разрешение или запрет на маршрутизацию пакетов. С необходимостью покрутить эту ручку мы сталкиваемся когда настраиваем маршрутизатор. Тут все более-менее понятно: 0 — выключить; 1 — включить.

net.ipv4..rp_filter — контролирует опцию Reverse Path Filtering: 0 — не проводить проверку, отключить; 1 — “строгий” режим, когда отбрасываются пакеты ответы которым не уходили бы через тот интерфейс с которого пришел пакет; 2 — “расслабленный” режим — отбрасываются только те пакеты, маршрут до которых неизвестен (при наличии маршрута по умолчанию, по-моему, должно приводить к тому же эффекту, что и 0).

net.ipv4.ip_local_port_range — определяет минимальный и максимальный порты, который используется для создания локального клиентского сокета. Если у вас система совершает большое количество обращений к сетевым ресурсам, то у вас может возникнуть проблема нехватки локальных портов для установки соединений. Этот параметр позволяет регулировать диапазон портов, который используется для установки клиентских соединений. Так же это может быть полезно для того, чтобы обезопасить ваши сервисы которые “слушают” высокие порты.

net.ipv4.ip_default_ttl — время жизни пакета (TTL) по умолчанию. Может понадобиться когда надо ввести в заблуждение оператора СС пользуясь телефоном как модемом, либо когда надо убедиться, что пакеты от этого хоста не уходят за периметр сети.

net.core.netdev_max_backlog — регулирует размер очереди пакетов между сетевой картой и ядром. Если ядро не успевает обрабатывать пакеты и очередь переполняется, то новые пакеты отбрасываются. может потребоваться подкрутить в определенных ситуациях, чтобы справиться с пиковыми нагрузками и не испытывать сетевых проблем.

Ниже два параметра отвечающие за очереди соединений, то есть TCP. Эти два параметра в первую очередь подвергаются тюнингу на нагруженных web-сервисах, в случае когда возникают проблемы.

Для понимания надо знать как работают соединения в tcp:

  1. Программа открывает слушающий сокет: socket() -> listen(). В итоге получает, например *:80 (80-й порт на всех интерфейсах).
  2. Клиент устанавливает соединение: a) посылает серверу syn-пакет (вот в этом месте и работает tcp_max_syn_backlog); b) получает от сервера syn-ack; c) посылает серверу ack (а вот тут уже работает somaxconn)
  3. Через вызов accept соединение обрабатывается и передается процессу для работы с конкретным клиентом.

net.core.somaxconn — размер очереди установленных соединений ожидающих обработки accept(). Если у нас возникают небольшие пики нагрузки на приложение — возможно вам поможет увеличение этого параметра.

net.ipv4.tcp_max_syn_backlog — размер очереди не установленных соединений.

Для большинства настроек TCP, да как, собственно, и всех остальных — требуется понимание работы механизмов, которые эти настройки регулируют.
Например как tcp передает данные. Поскольку этот протокол “гарантирует доставку”, то ему требуются подтверждения о доставке от второй стороны соединения. Эти подтверждения называются ACKnoweledgement. Подтверждается полученный диапазон байт. Так же мы знаем, что данные в сеть мы можем передавать блоками равными размеру MTU (пусть, для простоты, 1500 байт), а передать нам надо больше, допустим 1500000 байт, то есть 1000 фреймов, данные будут фрагментированы. Если у нас сервера в одной сети на расстоянии одного патч-корда друг от друга — проблем то мы и не заметим, а вот если у нас идет обмен с удаленной системой, то дожидаться подтверждения каждого пакета — очень долго, ведь нам надо дождаться пока ТУДА дойдет наш пакет и оттуда вернется подтверждение о получении это будет очень сильно сказываться на скорости передачи данных. Чтобы решить этот вопрос было введено tcp_window, под размер которого выделено 16 бит в заголовке tcp. Грубо говоря, это количество байт, которые мы можем отправить без подтверждения. В 16ти битах мы можем хранить значение максимум 2^16=65536 (65Kb), что в наш век многогигабитных сетей вообще не много.

Читайте также:  Windows 10 для сенсорного планшета

Чтобы понять, как мы можем передавать данные, допустим, из Москвы в Новосибирск (RTT (Round Trip Time) = 50ms) через 1Gbit канал давайте сделаем несколько расчетов (ниже ОЧЕНЬ грубые расчеты).

    Без tcp_window. Получается, что мы можем отправлять только 1500 байт в .05s, 1500/0.05 = 30000 байт/секунду. Маловато, при том, что канальная скорость у нас 1Gbit/s, что грубо примерно равно 100Mb/s.

100Mb/s — есть проблема, мы не утилизируем доступную полосу.
С tcp_window равным 65536 (максимум который можно указать в заголовке). Т.е. мы сразу можем отправить все наши 65К. 65536/0.05 = 1310720 = 1.25Mb/s. 1.25Mb/s vs

100Mb/s — все равно маловато, разница примерно в 80 раз.
Так сколько же нам надо для того, чтобы утилизировать хотя бы 900Mbit? проведем обратные вычисления. (900000000/8)b/s*0.05s=5625000b

= 5.36 Mb. Это размер окна, который нам нужен, чтобы эффективно передавать данные. Но поскольку у нас очень длинный линк, то у нас там могут возникать проблемы => потери. Это тоже будет влиять на пропускную способность. Для того, чтобы через 16 битное поле получить возможность уведомлять о размере окна большем 65К была введена опция tcp_window_scaling.

net.ipv4.tcp_window_scaling — 0 — выключает масштабирование окна; 1 — включает масштабирование окна. Это должно поддерживаться с обеих сторон и служит для оптимизации использования полосы канала.

Но мало иметь возможность указать окно больше 65К, нужно еще иметь возможность держать все необходимые данные в памяти выделенной для сокета, в нашем случае в tcp_buffer’ах:

net.ipv4.tcp_wmem,net.ipv4.tcp_rmem — настройки Read и Write буферов выглядят одинаково. Это три числа в БАЙТАХ, “min default max” — минимальный гарантированный размер буфера, размер по умолчанию и максимальный размер, больше которого буферу система не даст вырасти. К настройке этих параметров стоит подходить с пониманием того, сколько у вас ожидается соединений, сколько данных вы собираетесь передавать и на сколько “медленные” ваши клиенты/сервера.

net.ipv4.tcp_mem — настройки управления памятью tcp-стека. 3 числа в СТРАНИЦАХ “min pressure max”, которые описывают: min — порог использования памяти буферами ниже которого система не будет заботиться о вытеснении буферов; pressure — порог при достижении которого система будет заботиться о сокращении потребления памяти буферами, покуда это возможно; max — порог при достижении которого память выделяться не будет и буфера не смогут расти.

Иногда приложения падают, так сказать, “в корку”. Эту корку (“дамп памяти”) можно использовать для отладки проблемы с помощью gdb. Вещь безусловно полезная, когда настроена. По умолчанию, coredump сохраняется в безликий файл core в рабочем каталоге приложения, возможно он будет еще сопровожден pid приложения, но можно сделать все гораздо удобнее:

kernel.core_pattern — позволяет задавать формат имени (и пути), которое будет использоваться для сохранения core dump. Например, “/var/core/%E.%t.%p” сохранит “корку” в директорию /var/core/ использовав в имени полный путь до программы, которая упала (заменив / на !) и добавив timestamp события и pid приложения. Можно даже перенаправить core во внешнюю программу для анализа. Подробнее можно узнать в man 5 core.

Это все только верхушечки айсберга, если описывать более подробно все — можно написать целую книгу.

Удачи в консоли.

Вот такая небольшая заметочка, которую мы подготовили в рамках нашего курса "Администратор Linux". Тематику выбирали наши слушатели голосовалкой, так что надеемся, что заметка вам будет интересна и полезна.

Процесс пошел, подумал я, и выйдя из «анабиозного» состояния раздолбая, я понял что нужно работать дальше…

Сейчас речь пойдет о том, как можно настроить ядро Linux сервера, чтобы он смог переваривать большое количество запросов, а так же DDos. Все будет кратко с небольшим описанием.

Много материалов я вычитал, для того чтобы понять какие значения оптимальны, так же прилично всего перепробовал, и некоторые решения помогли мне уйти от той высокой нагрузки на сервере. Так же грамотная настройка ядра сервера позволит вам защититься от SYN flood. Ладно, начнем..

Каждый параметр подробненько…

rp_filter

— параметр который включает фильтр обратного пути, проще говоря активируется защита от подмены адресов (спуфинга).

По умолчанию он отключен:

Рекомендуется включить в «строгий режим» проверки (значение 2 включает «свободный режим» проверки), причем включить его можно на всех интерфейсах:

Так проверку можно включить на определенном интерфейсе:

accept_source_route

— запрет маршрутизации от источников.

По умолчанию эта опция отключена:

Но если она у вас почему-то включена — отключите, желательно на всех интерфейсах:

accept_redirects, secure_redirects, send_redirects

— этими тремя параметрами мы запрещаем принимать и отправлять ICMP пакеты перенаправления. ICMP-перенаправления могут быть использованы злоумышленником для изменения таблиц маршрутизации.

secure_redirects — BOOLEAN
Accept ICMP redirect messages only to gateways listed in the
interface’s current gateway list. Even if disabled, RFC1122 redirect
rules still apply.
Overridden by shared_media.
secure_redirects for the interface will be enabled if at least one of
conf//secure_redirects is set to TRUE,
it will be disabled otherwise
default TRUE

send_redirects — BOOLEAN
Send redirects, if router.
send_redirects for the interface will be enabled if at least one of
conf//send_redirects is set to TRUE,
it will be disabled otherwise
Default: TRUE

По умолчанию все эти параметры включены:

Но, так как наш сервер не маршрутизатор, в них нет необходимости:

icmp_echo_ignore_broadcasts

— отключаем ответ на ICMP ECHO запросы, переданные широковещательными пакетами.

По умолчанию включено, т.е. broadcast icmp запросы приходить не будут:

Так и рекомендуется отставить:

icmp_ignore_bogus_error_responses

— игнорируем ошибочные ICMP запросы.

Так и рекомендуется отставить:

icmp_echo_ignore_all

— отключаем ответ на ICMP запросы (сервер не будет пинговаться)

На ваше усмотрение, можно отключить:

tcp_syncookies

— по умолчанию данный параметр обычно включен. Если количество SYN пакетов забивает всю очередь, включается механизм Syn cookies.

Как проверить, включен ли он у нас:

Если выдает 1, то включен, 0 — значит отключен. Для отключения «на лету» достаточно воспользоваться следующей командой:

Естественно поставив в конце «1» — механизм будет снова включен.

Если параметр tcp_syncookies установлен (доступен только когда ядро собрано с CONFIG_SYNCOOKIES), тогда ядро обрабатывает SYN пакеты TCP в обычном режиме до тех пор, пока очередь не заполнится. После заполнения очереди включается механизм SYN cookies.

SYN cookies вообще не использует очередь SYN. Вместо этого ядро отвечает на каждый SYN пакет, как обычно SYN|ACK, но туда будет включено специально сгенерированное число на основе IP адресов и портов источника и получателя, а также времени посылки пакета. Атакующий никогда не получит эти пакеты, а поэтому и не ответит на них. При нормальном соединении, будет послан третий пакет, содержащий число, а сервер проверит был ли это ответ на SYN cookie и, если да, то разрешит соединение даже в том случае, если в очереди SYN нет соответствующей записи.

Включение механизма SYN cookies является очень простым способом борьбы против атаки SYN флудом. При этом немного больше загружается процессор из-за необходимости создавать и сверять cookie. Так как альтернативным решением является отклонять все запросы на соединение, SYN cookies являются хорошим выбором.

Таким образом, как описано выше, мы получаем неплохую защиту от syn флуда и терпим небольшую нагрузку на ЦП..

Читайте также:  Linux mint ярлыки на рабочем столе

Но согласно описанию, включать генерацию syncookies на высоконагруженных серверах, для которых этот механизм срабатывает, при большом количестве легальных соединений, не следует. Если в логах есть предупреждения о SYN-флуде, при этом это вполне нормальные соединения, нужно настраивать другие параметры: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.

tcp_max_syn_backlog

— параметр который определяет максимальное число запоминаемых запросов на соединение, для которых не было получено подтверждения от подключающегося клиента (полуоткрытых соединений). По умолчанию:

Если на сервере возникают перегрузки, можно попытаться увеличить это значение, например до 4096:

tcp_synack_retries

— время удержания «полуоткрытых» соединений.

Это значение имеет смысл уменьшить, например до 1 (это будет 9 секунд):

tcp_max_orphans

— определяет максимальное число «осиротевших» TCP пакетов.

Рекомендуется установить 65536, а далее увеличивать, по мере необходимости:

tcp_fin_timeout

— время ожидания приема FIN до полного закрытия сокета.

Рекомендуется поменять на 10 секунд:

tcp_keepalive_time

— проверять TCP-соединения, с помощью которой можно убедиться в том что на той стороне легальная машина, так как она сразу ответит.

По умолчанию 2 часа:

Рекомендуется каждую минуту:

tcp_keepalive_intvl

— интервал подачи проб…

tcp_keepalive_probes

— Количество проверок перед закрытием соединения.

netdev_max_backlog

— Параметр определяет максимальное количество пакетов в очереди на обработку, если интерфейс получает пакеты быстрее, чем ядро может их обработать.

Рекомендуется так и оставить:

somaxconn

— Максимальное число открытых сокетов, ждущих соединения.

Рекомендуется установить значения в районе 15000-20000:

tcp_mem

— векторная (минимум, режим нагрузки, максимум) переменная которая cодержит общие настройки потребления памяти для протокола TCP

Можно поставить эти же значения.увеличивать имеет смысл в случае увеличения нагрузки.

tcp_rmem

— векторная (минимум, режим нагрузки, максимум) переменная которая cодержит 3 целых числа, определяющих размер приемного буфера сокетов TCP.

Можно поставить эти же значения.увеличивать имеет смысл в случае увеличения нагрузки. В одном из источнике рекомендовали следующие значения:

tcp_wmem

— векторная (минимум, режим нагрузки, максимум) переменная которая cодержит 3 целых числа, минимальное, принятое по умолчанию и максимальное количество памяти, резервируемой для буферов передачи сокета TCP.

Можно оставить эти же значения. Увеличивать их имеет смысл в случае увеличения нагрузки. В одном из источнике рекомендовали следующие значения:

rmem_default, wmem_default

Так же есть «глобальные» параметры размеров буфера, и они не перекрывают значения переменных tcp_rmem и tcp_wmem (читай описание выше)

  • rmem_default — размер буфера приема данных по умолчанию для всех соединений.
  • wmem_default — Размер буфера передачи данных по умолчанию для всех соединений.

Их значения по умолчанию:

Можно оставить эти же значения. Увеличивать их имеет смысл в случае увеличения нагрузки. Например, в одном из источнике рекомендовали следующие значения:

rmem_max, wmem_max

а эти «глобальные» параметры перекрывают «максимумы» переменных tcp_rmem и tcp_wmem (опять же, читай описание выше)

  • rmem_max — максимальный размер буфера приема данных для всех соединений.
  • wmem_max — максимальный размер буфера передачи данных для всех соединений.

Их значения по умолчанию:

Можно оставить эти же значения. Увеличивать их имеет смысл в случае увеличения нагрузки. Например, в одном из источнике рекомендовали следующие значения:

tcp_orphan_retries

— параметр который определяет число неудачных попыток, после которого уничтожается соединение TCP, закрытое на локальной стороне.

Рекомендуется уменьшить значение этого параметра, поскольку закрытые соединения могут поглощать достаточно много ресурсов (т.е. оставляем 0):

ip_conntrack_max

— Максимальное количество соединений для работы механизма connection tracking (используется, например, iptables).

При слишком маленьких значениях ядро начинает отвергать входящие подключения с соответствующей записью в системном логе:

tcp_timestamps

— включает временные метки протокола TCP, которые позволяют управлять работой протокола в условиях высоких нагрузок (с помощью tcp_congestion_control)

По умолчанию метки включены:

Кстати, лучше отставить его включенным, иначе не будет работать опция tcp_tw_reuse.

tcp_sack

— разрешаем выборочные подтверждения протокола TCP. Опция необходима для эффективного использования всей доступной пропускной способности некоторых сетей.

По умолчанию опция включена:

Рекомендуется включать эту опцию, если вы имеете неустойчивые соединения. Однако, если вы соединены 1.5-метровым кабелем с другой машиной, то в таком случае, для достижения наивысшей скорости обмена, следует эту опцию отключить:

tcp_congestion_control

— протокол, используемый для управления нагрузкой в сетях TCP. bic и cubic реализации, используемые по умолчанию, содержат баги в большинстве версий ядра RedHat и ее клонов. Рекомендуется использовать htcp.

Для сервера рекомендуется использовать htcp:

tcp_no_metrics_save

— данная опция запрещает сохранять результаты изменений TCP соединения в кеше при его закрытии.

По умолчанию опция ничего не запрещает:

Так как это помогает повысить производительность, рекомендуется включить:

net.ipv4.route.flush

— актуально для ядер 2.4. По странной причине в ядрах 2.4, если в рамках TCP сессии произошел повтор передачи с уменьшенным размером окна, все соединения с данным хостом в следующие 10 минут будут иметь именно этот уменьшенный размер окна. Данная настройка позволяет этого избежать.

Так как в ядре 3.2 она даже не читается, менять ничего не стал.

ip_local_port_range

— опция, которая содержит диапазон локальных портов, доступных для установки исходящих подключений.

По умолчанию там такой диапазон:

Для тяжелых проектов диапазон рекомендуется увеличить:

tcp_tw_reuse

— опция позволяющая повторное использование TIME-WAIT сокетов в случаях, если протокол считает это безопасным.

По умолчанию отключена:

tcp_window_scaling

— опция позволяет динамически изменять размер окна TCP стека

По умолчанию она включена:

Лучше так и оставить:

tcp_rfc1337

— с помощью этой опции мы можем защитить себя от TIME_WAIT атак.

По умолчанию опция отключена:

На сервере она точно не помешает:

ip_forward

— данная опция управляет переадресацией пакетов. Если этот параметр выключен, ОС считает себя узлом IP сети и дропает все пакеты, предназначенные не ей. Если параметр включен, то ОС считает себя маршрутизатором и действует в соответствии с RFC1812, в том числе пытается переслать адресованные не ей пакеты в соответствии с таблицей маршрутизации.

По умолчанию переадресация включена:

Если сервер не является маршрутизатором, то включать эту опцию нет необходимости:

tcp_abort_on_overflow

— Эта переменная заставляет ядро отвергать новые соединения, если их поступает количество, с которым система не в состоянии справиться. Эту переменную следует использовать как крайнюю меру! По умолчанию она отключена:

Если ситуация требует, то ее можно включить:

Как все это применить?

Я намеренно для изменения параметров использовал утилиту sysctl, а значения этих параметров просто читал с помощью cat. Сделано это было все для того, чтобы вам было ясно что способов изменения параметров ядра много.

Например, внести изменения мы так же можем с помощью echo:

А прочитать значения мы так же можем с помощью команды sysctl:

Кому какой способ больше нравится — решайте сами.

Как применить все эти значения разом, не сохраняя их?

Можно прочитать все описание выше и каждую переменную применять руками, с помощью «sysctl -w», и все эти значения будут работать до тех пор, пока вы не перезагрузите систему. Это полезно, пока ваше ядро находится в режиме «вашей отладки».

Для удобства ниже приведены все параметры разом, если решение вам нужно здесь и сейчас:

Как сохранить эти значения?

Если сервер работает корректно со всеми настройками указанными выше, то для их сохранения достаточно добавить все эти переменные в конец файла /etc/sysctl.conf:

Заключение

На этом вроде все. В процессе написания статьи я изучал всевозможные настройки ядра, поэтому если есть где-то неточности или вам есть чем дополнить данный материал — пишите, буду очень рад.

Ссылка на основную публикацию
Adblock detector