Для нормальной работы сайта необходимо разрешить JavaScript, включая скрипты с доменов googlesyndication.com и doubleclick.net для отображения системы поиска по сайту и прочих сервисов Google.

Как защитить Linux сервер от DDOS атак

logo

Как защитить Linux сервер от DDOS атак Что такое DDOS атака на сервер мы рассказывать не станем ибо раз читателя заинтересовала тема защиты сервера, веб или VPS/VDS сервера, от DDOS атак, то скорее всего с базовыми понятиями про DDOS атаки он уже знаком.

Сразу нужно сказать, что в некоторых случаях мнимые DDOS (distributed denial of service attack) атаки могут исходить из самого движка сайта (т.е. вебсайта:) - например когда на сайте слишком много интерактивных Ajax элементом которые обновляют данные каждую секунду, но это уже другая тема по имени "оптимизация вебсайта".

Когда к кривому движку присоединяются с десяток или сотня чёрных ботов и всяких какеров тренирующихся на твоём сайте, злобных гоблинов шлющих пакеты от имени нашего хоста, то бывает, что возникают проблемы с доступом к серверу по SSH, а иногда даже многократные перезагрузки сервера не помогают;(

Ну, не будем томить и сразу же перейдём к методам защиты веб или VPS/VDS сервера от DDOS атак.

  • Основные методы защиты сервера от DDOS атак
  • Защита сервера от DDOS атак с помощью iptables
  • Защита сервера от DDOS атак на уровне ядра
  • Выбираем подходящий I/O Scheduler
  • Выбираем политику выделения памяти (overcommit)
  • Оптимизируем использование файла подкачки (swap)
  • Пакет Kernel Tune (ktune)

Основные методы защиты сервера от DDOS атак

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


  1. Активно использовать фаервол - закрыть все порты кроме используемых повседневно, остановить лишние сервисы, запретить пинг для скрытия машины от различных злонамеренных роботов пингующих и сканирующих диапазоны ИП, проверять входящие пакеты на их соответствие стандартам стека протоколов TCP;
  2. Сменить стандартные номера портов для FTP и SSH;
  3. Регулярно анализировать критические сообщения из .лог файлов сервера, например при помощи Logwatch и делать адекватные выводы;
  4. Своевременное обновление всего системного и прикладного ПО;
  5. Снять с автоматической загрузки все сервисы находящиеся в публичном доступе, включая веб сервера nginx и httpd: chkconfig httpd off and chkconfig nginx off, что поможет получить доступ к серверу в случае непрерывной ДДОС атаки на эти сервисы;
  6. Использовать PHP ака Fast CGI + акселераторы типа eAccelerator или APC;
  7. Выполнить тонкую настройку сетевых параметров ядра через sysctl;
  8. Возможно использовать дополнительное ПО вроде mod_evasive или анти ддос шел-скрипты на базе tcpdump или netstat;
  9. Выбрать правильный диспетчер ввода/вывода и оптимизировать использование оперативной и виртуальной памяти.

Кроме основных методов защиты сервера от DDOS атак есть ещё один последний способ - это выдернуть шнур питания сервера и выдавить стекло монитора:))

Защита сервера от DDOS атак с помощью iptables

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

# устанавливаем политику полного доступа для цепочки INPUT
iptables -P INPUT ACCEPT
# сбрасываем все правила, для всех цепочек
iptables -F
# добавляем разрешающее правило для локального интерфейса
iptables -A INPUT -i lo -j ACCEPT
# Разрешаем пакеты по уже установленным соединениям
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешаем доступ только к веб и SSH
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
# Разрешаем проброс пакетов для локального интерфейса
# Не имеет смысла для рабочих станций и серверов
iptables -A FORWARD -i lo -j ACCEPT
# Ставим политики по умолчанию применяемые для цепочек 
# если для соединений в них нет подходящего правила
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# сохраняем правила
service iptables save

Создадим дополнительную цепочку LIMIT для правил устанавливающих лимиты и с кажем что проходящие по цепочке INPUT соединения должны сначала быть обработаны правилами в цепочке LIMIT

iptables -N LIMIT
iptables -I INPUT -j LIMIT

Главное в цепочку LIMIT НЕ добавить "iptables -A LIMIT -j DROP" ибо закроем всё, для всех и для себя включительно!:) Добавим соответствующее правило ограничивающее количество одновременных соединений с одного и того же ИП адреса:

# Ограничиваем максимальное число «полуоткрытых» TCP-соединений 
# с одного и того же IP-адреса
# В браузерах количество подключений к серверу ограничивается 16 соединениями,
# желательно вспомнить и про тех, кто может висеть за NAT-ом.
# Значение параметра --connlimit-above нужно подбираеть оптимально
iptables -A LIMIT -p tcp --syn -m multiport --dports 80,443 -m connlimit \
    --connlimit-above 32 -j LOG --log-level 4 --log-prefix "[FW SYN DROP]: "
iptables -A LIMIT -p tcp --syn -m multiport --dports 80,443 -m connlimit \
    --connlimit-above 32 -j DROP
# то же только для DNS
iptables -A LIMIT -p udp --dport 53 -m connlimit --connlimit-above 8 -j LOG \
    --log-level 4 --log-prefix "[FW DNS DROP]: "
iptables -A LIMIT -p udp --dport 53 -m connlimit --connlimit-above 8 -j DROP

При обнаружении ИП с которого будет попытка установить более 32 соединений, событие будет записано в журнал с пометкой "[FW SYN DROP]:", а сам пакет будет сброшен (DROP). Тем, у кого старая версия ядра и фаервола где нет возможности юзать connlimit, поможет анти ддос шел-скрипт на базе tcpdump или netstat.

Теперь оправдание тому, почему используется дополнительная цепочка LIMIT... Принимая входящие из цепочки INPUT в цепочку LIMIT мы можем более гибко шаманить правилами - т.е. приняв пакет нам нужно с ним что-то сделать - ACCEPT, DROP, REJECT, NFQUEUE, QUEUE или RETURN. С действиями ACCEPT, DROP, REJECT, RETURN думаю всё ясно, а вот по поводу NFQUEUE и QUEUE поясню как я их понял из доков - действие NFQUEUE ставит пакет в очередь на обработку пользовательским демоном (процессом), например "-j NFQUEUE --queue-num ?", где знак вопроса является номером очереди, действие же QUEUE является устаревшей версией NFQUEUE.

Если RETURN применяется к правилу в пользовательской цепочке, то обработка прекращается с возвратом пакета в центральную для дальнейшей обработки, а если RETURN применяется к правилу в центральной цепочке, то применяется политика цепочки по умолчанию, в нашем случае DROP.

Если нужно сделать исключения например для гугля робота, т.е. не применять к нему вовсе никаких лимитов и проверок, то мы можем добавить в начало (-I) цепочки LIMIT правило возвращающее соединение на обработку в центральную цепочку INPUT, а не создавать в INPUT разрешающее с указанием портов доступа, хотя - это дело личного предпочтения каждого:

iptables -I LIMIT -s 173.194.0.0/16 -m comment --comment \
    "Return google SE ip range" -j RETURN
iptables -I LIMIT -s 74.125.0.0/16 -m comment --comment \
    "Return google SE ip range" -j RETURN
iptables -I LIMIT -s 66.249.64.0/19 -m comment --comment \
    "Return google SE ip range" -j RETURN
iptables -I LIMIT -s 213.180.204.0/24 -m comment --comment \
    "Return yandex SE ip range" -j RETURN
iptables -I LIMIT -s 77.88.21.0/24 -m comment --comment \
    "Return yandex SE ip range" -j RETURN
iptables -I LIMIT -s 95.108.138.0/24 -m comment --comment \
    "Return yandex SE ip range" -j RETURN

Так мы из цепочки LIMIT с правилами лимита возвращаем в INPUT (центральную цепочку) все пакеты поступившие с ИП диапазонов принадлежащих GOOGLE и YANDEX, а для всех остальных будут применены идущие ниже правила лимита, диапазоны ИП GOOGLE и YANDEX указаны ниже:

GOOGLE:
 
From IP: 173.194.0.0
To IP: 173.194.255.255
CIDR from Netmask: 173.194.0.0/16
 
IP Address: 74.125.17.82
Country: USA - California
Network Name: GOOGLE
Owner Name: Google Inc.
From IP: 74.125.0.0
To IP: 74.125.255.255
CIDR from Netmask: 74.125.0.0/16
 
IP Address: 66.249.81.80
Country: USA - California
Network Name: GOOGLE
Owner Name: Google Inc.
From IP: 66.249.64.0
To IP: 66.249.95.255
CIDR from Netmask: 66.249.64.0/19
 
YANDEX:
 
IP Address: 95.108.138.0
Country: Russian Federation
Network Name: YANDEX-95-108-138
Owner Name: Yandex enterprise network
From IP: 95.108.138.0
To IP: 95.108.138.255
CIDR from Netmask: 95.108.138.0/24
 
IP Address: 213.180.204.11
Country: Russian Federation
Network Name: YANDEX-213-180-204
Owner Name: Yandex enterprise network
From IP: 213.180.204.0
To IP: 213.180.204.255
CIDR from Netmask: 213.180.204.0/24
 
IP Address: 77.88.21.11
Country: Russian Federation
Network Name: YANDEX-77-88-21
Owner Name: Yandex enterprise network
From IP: 77.88.21.0
To IP: 77.88.21.255
CIDR from Netmask: 77.88.21.0/24

Таким образом все нужные нам боты получают безлимитный доступ к серванту, а все остальные соединения будут лимитироваться. Если добавили ошибочное правило, то удалите его командой iptables -D LIMIT 1, где 1 это порядковый номер правила отсчитываемый сверху цепочки начиная с цифры 1.

Теперь создадим дополнительную цепочку BAN для постоянно заблокированных ИП и с кажем что проходящие по цепочке INPUT должны быть обработаны правилами в цепочке BAN:

iptables -N BAN
iptables -I INPUT -j BAN

Добавляем ИП которые нужно блокировать, например:

iptables -A BAN -s 58.218.199.250 -j DROP

Цепочку BAN нужно поставить первой, её можно будет использовать для связки tcpdump + iptables или netstat + iptables. Например можно написать скрипт, который по крон-у будет анализировать аномалии в соединениях и заносить ИП в цепочку BAN, которую при каждом своем запуске по крон-у, например каждые 10 мин, будет её сбрасывать iptables -F BAN, а потом снова анализировать соединения и банить подозрительных. ИП 58.218.199.250 принадлежит какому-то китайскому роботу, который постоянно щупает один и тот же каталог, не припомню какой - можете смело его банить;)

В конце цикла работы скрипта, ему можно подсовывать список неугодных ИП которые заблокированы на постоянной основе, хотя для этого можно оставить цепочку BAN, а для скрипта работающего с tcpdump + iptables или netstat + iptables создать отдельную цепочку ANTIDDOS

Главное в дочерние цепочки НЕ добавить правило типа "iptables -A BAN -j DROP" ибо закроем всё, для всех и для себя включительно!:) Также для установки правил лучше использовать команду iptables, а не редактировать файл /etc/sysconfig/iptables вручную!

В нашу цепочку LIMIT можно добавить ещё одно полезное правило, которое поможет отсекать спуферастов с записью в сисьлог:) Когда по еще не открытому соединению, приходит пакет, на котором установлены флаги SYN и ACK, а такая комбинация флагов свойственна только для ответа на SYN-пакет, то это значит, что кто-то послал SYN-пакет другому хосту от нашего имени, и ответ пришел к нам. Согласно этому правилу, наш хост должен ответит RST-пакетом, после чего атакуемый хост должен закрыть соединение.

iptables -A LIMIT -m conntrack --ctstate NEW,INVALID -p tcp \
    --tcp-flags SYN,ACK SYN,ACK -j LOG --log-level 4 --log-prefix "[FW SPUF REJECT]: "
iptables -A LIMIT -m conntrack --ctstate NEW,INVALID -p tcp \
    --tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset

Можно рассмотреть ещё одно полезное правило ограничивающее создание новых соединений в определённый промежуток времени:

# Если с одного адреса за последние 300 секунд (5 минут) 
# было 5 или более новых соединений — сбрасываем пакет
iptables -A LIMIT -m conntrack --ctstate NEW -m recent --update \
    --seconds 300 --hitcount 5 -j LOG --log-level 4 --log-prefix "[FW NEW DROP]: "
iptables -A LIMIT -m conntrack --ctstate NEW -m recent --update \
    --seconds 300 --hitcount 5 -j DROP

Если всё работает как нужно, тогда сохраняем правила service iptables save.

Защита сервера от DDOS атак на уровне ядра

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

В /etc/sysctl.conf рекомендуется добавить следующие строки:

vi /etc/sysctl.conf
 
# Защита от спуфинга
# Значение по умолчанию 1
net.ipv4.conf.default.rp_filter = 1
 
# Позволяет осуществлять фильтрацию пакетов по адресу назначения 
# (проверка адреса получателя). Рекомендуется включить данную проверку (1).
# Значение по умолчанию 0
net.ipv4.conf.all.rp_filter = 1
 
# Проверка TCP-соединения каждую минуту.
# Если на другой стороне легальная машина, то она сразу ответит.
# Значение по умолчанию 2 часа (7200 сек).
net.ipv4.tcp_keepalive_time = 60
 
# Повторять проверку каждые десять секунд
# Значение по умолчанию 75 сек. Это достаточно высокое значение, 
# чтобы рассматривать его как нормальное. Значения переменных 
# tcp_keepalive_probes и tcp_keepalive_intvl могут использоваться 
# для определения времени, через которое соединение будет разорвано. 
# Со значениями по-умолчанию (9 попыток с интервалом 75 секунд) 
# это займет примерно 11 минут. Попытки определения жизнеспособности, 
# в свою очередь, начнутся через net.ipv4.tcp_keepalive_time 
# 2 часа (по умолчанию) после того, 
# как через данное соединение проследовал последний пакет.
net.ipv4.tcp_keepalive_intvl = 10
 
# Количество проверок перед закрытием соединения
# Значение по умолчанию 9
net.ipv4.tcp_keepalive_probes = 3
 
# Увеличение очереди «полуоткрытых» TCP-соединений:
# Значение по умолчанию 128
net.ipv4.tcp_max_syn_backlog = 512
 
# Количество попыток передачи SYN-пакета при установлении нового соединения.
# Значение по умолчанию 5
net.ipv4.tcp_syn_retries = 3
 
# Уменьшение времени удержания «полуоткрытых» соединений:
# Количество попыток передачи SYN,ACK-пакета в ответ на SYN-запрос.
# Значение по умолчанию 5
net.ipv4.tcp_synack_retries = 3
 
# Включение механизма TCP syncookies:
# Значение по умолчанию 1
net.ipv4.tcp_syncookies = 1
 
# Сколько секунд ожидать приема FIN до полного закрытия сокета.
# Значение по умолчанию 60
net.ipv4.tcp_fin_timeout = 15
 
# Запрещаем TCP window scaling (динамическое изменение размера окна TCP стека)
# http://en.wikipedia.org/wiki/TCP_window_scale_option
# Значение по умолчанию 1
net.ipv4.tcp_window_scaling = 0
 
# Максимальное количество попыток повторной передачи пакетов по установленному 
# соединению прежде, чем сообщение об ошибке будет передано сетевому уровню, 
# в результате чего может быть выбран другой маршрут для отправки последующих 
пакетов.
# Значение по умолчанию 3
net.ipv4.tcp_retries1 = 3
 
# Максимальное количество попыток повторной передачи пакетов, 
# до того как соединение будет считаться разорванным.
# Значение по умолчанию 15
net.ipv4.tcp_retries2 = 5
 
# Эта переменная заставляет ядро отвергать новые соединения, 
# если их поступает такое количество, что система не в состоянии 
# справиться с таким потоком. Рекомендую выставить данную переменную 
# в 1 для защиты от DDoS, как крайнюю меру.
# Значение по умолчанию 0
net.ipv4.tcp_abort_on_overflow = 1
 
# Log spoofed, source routed and redirects
# Значение по умолчанию 0
net.ipv4.conf.all.log_martians = 1
 
# Don't relay bootp
net.ipv4.conf.all.bootp_relay = 0
 
# Don't proxy arp for anyone
net.ipv4.conf.all.proxy_arp = 0
net.ipv4.conf.all.proxy_arp_pvlan = 0
 
# Don't accept source route packets
net.ipv4.conf.all.accept_source_route = 0
 
# Don't send redirects
# Значение по умолчанию 1
net.ipv4.conf.all.send_redirects = 0
 
# Disable Explicit Congestion Notification in TCP
# Don't use ECN because too many sites have wacky routers that can't handle it
# Значение по умолчанию 2
net.ipv4.tcp_ecn = 0
 
# Загружаем настройки из /etc/sysctl.conf
sysctl -p

Для просмотра всех параметров конфигурации ядра «на ходу» для ipv4 выполняем sysctl -a | grep net.ipv4. Перед тем как записывать указанные выше параметры в /etc/sysctl.conf рекомендуется сначала применить их так sysctl -w net.ipv4.tcp_abort_on_overflow=1 или же вот так echo 1 > /proc/sys/net/ipv4/tcp_abort_on_overflow, а уже после этого если система работает нормально, то уже тогда заносить все настройки в /etc/sysctl.conf

Выбираем подходящий I/O Scheduler

Для того чтобы наш сервант выдерживал больший натиск и выдерживал всё более сильные ДДОС атаки, мы должны выбрать самый эффективный планировщик ввода/вывода (I/O Scheduler). Посмотреть текущий планировщик ввода/вывода (I/O Scheduler) и возможные его варианты можно выполнив команду:

cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

В нашем случае текущим планировщиком вводы/вывода (I/O Scheduler) является [cfq] (Completely Fair Queuing). Протестировать какой из I/O Scheduler-ов будет более эффективным в нашем случае можно с помощью приведённого ниже скрипта:

vi sheduler
 
DISC="sda";
cat /sys/block/$DISC/queue/scheduler;
for T in noop anticipatory deadline cfq; do
    echo $T > /sys/block/$DISC/queue/scheduler;
    cat /sys/block/$DISC/queue/scheduler;
    sync && /sbin/hdparm -tT /dev/$DISC && echo "----";
    sleep 15;
done
 
chmod +x sheduler

Для получения средних значений и выбора более оптимального I/O Scheduler-а нужно запустить наш ./scheduler 4-5 раз и проанализировать полученные значения:

./scheduler
noop anticipatory deadline [cfq]
[noop] anticipatory deadline cfq
/dev/sda:
Timing cached reads: 10874 MB in 2.00 seconds = 5440.47 MB/sec
Timing buffered disk reads: 170 MB in 3.00 seconds = 56.65 MB/sec
----
noop [anticipatory] deadline cfq
/dev/sda:
Timing cached reads: 10428 MB in 2.00 seconds = 5217.32 MB/sec
Timing buffered disk reads: 148 MB in 3.11 seconds = 47.61 MB/sec
----
noop anticipatory [deadline] cfq
/dev/sda:
Timing cached reads: 10700 MB in 2.00 seconds = 5353.37 MB/sec
Timing buffered disk reads: 282 MB in 3.74 seconds = 75.38 MB/sec
----
noop anticipatory deadline [cfq]
/dev/sda:
Timing cached reads: 10246 MB in 2.00 seconds = 5126.44 MB/sec
Timing buffered disk reads: 90 MB in 3.24 seconds = 27.76 MB/sec
----./scheduler
noop anticipatory deadline [cfq]
[noop] anticipatory deadline cfq
/dev/sda:
Timing cached reads: 10602 MB in 2.00 seconds = 5304.49 MB/sec
Timing buffered disk reads: 166 MB in 3.33 seconds = 49.80 MB/sec
----
noop [anticipatory] deadline cfq
/dev/sda:
Timing cached reads: 10792 MB in 2.00 seconds = 5399.49 MB/sec
Timing buffered disk reads: 58 MB in 3.57 seconds = 16.25 MB/sec
----
noop anticipatory [deadline] cfq
/dev/sda:
Timing cached reads: 10576 MB in 2.00 seconds = 5291.96 MB/sec
Timing buffered disk reads: 224 MB in 3.01 seconds = 74.52 MB/sec
----
noop anticipatory deadline [cfq]
/dev/sda:
Timing cached reads: 10310 MB in 2.00 seconds = 5157.79 MB/sec
Timing buffered disk reads: 142 MB in 3.01 seconds = 47.12 MB/sec
----./scheduler
noop anticipatory deadline [cfq]
[noop] anticipatory deadline cfq
/dev/sda:
Timing cached reads: 10616 MB in 2.00 seconds = 5310.89 MB/sec
Timing buffered disk reads: 62 MB in 3.07 seconds = 20.19 MB/sec
----
noop [anticipatory] deadline cfq
/dev/sda:
Timing cached reads: 10792 MB in 2.00 seconds = 5399.04 MB/sec
Timing buffered disk reads: 134 MB in 3.00 seconds = 44.64 MB/sec
----
noop anticipatory [deadline] cfq
/dev/sda:
Timing cached reads: 10840 MB in 2.00 seconds = 5423.04 MB/sec
Timing buffered disk reads: 262 MB in 3.16 seconds = 82.96 MB/sec
----
noop anticipatory deadline [cfq]
/dev/sda:
Timing cached reads: 10790 MB in 2.00 seconds = 5398.32 MB/sec
Timing buffered disk reads: 46 MB in 3.17 seconds = 14.49 MB/sec
----./scheduler
noop anticipatory deadline [cfq]
[noop] anticipatory deadline cfq
/dev/sda:
Timing cached reads: 10418 MB in 2.00 seconds = 5212.57 MB/sec
Timing buffered disk reads: 228 MB in 3.01 seconds = 75.74 MB/sec
----
noop [anticipatory] deadline cfq
/dev/sda:
Timing cached reads: 10650 MB in 2.00 seconds = 5328.55 MB/sec
Timing buffered disk reads: 98 MB in 3.03 seconds = 32.38 MB/sec
----
noop anticipatory [deadline] cfq
/dev/sda:
Timing cached reads: 9262 MB in 2.00 seconds = 4633.53 MB/sec
Timing buffered disk reads: 314 MB in 3.01 seconds = 104.24 MB/sec
----
noop anticipatory deadline [cfq]
/dev/sda:
Timing cached reads: 10850 MB in 2.00 seconds = 5428.47 MB/sec
Timing buffered disk reads: 220 MB in 3.01 seconds = 73.05 MB/sec

Видим, что в большинстве случаев, в режиме [deadline] у нас самая большая скорость чтения дискового буфера (более 200-300 MB) и часто временами самая большая скорость чтения дискового кэша в среднем более 10700-10800 MB.

Для систем виртуализации VMware рекомендует использовать I/O Scheduler типа [noop] или [deadline], которые показывают большую эффективность ввода/вывода для виртуальных машин: Linux 2.6 kernel-based virtual machines experience slow disk I/O performance

Для изменения текущего I/O Scheduler выполняем команду: echo deadline > /sys/block/sda/queue/scheduler

Эта команда изменяет текущий I/O Scheduler, но не на постоянной основе. Для изменения типа I/O Scheduler-а на постоянной основе нужно внести изменения в конфигурацию загрузчика /boot/grub/grub.conf (/etc/grub.conf) или в список меню загрузки /boot/grub/menu.lst, где добавить строку elevator=noop или elevator=deadline следующим образом:

vi /etc/grub.conf
    kernel /vmlinuz-2.6.32-279.19.1.el6.x86_64 ro \
        root=UUID=15bfd01d-92e4-4a9d-86e0-c2fedf206bd9 elevator=deadline ....
    initrd /initramfs-2.6.32-279.19.1.el6.x86_64.img

В случае с загрузчиком lilo правим /etc/lilo.conf, например:

image=/boot/vmlinuz-2.6.9
    label=Linux
    root=/dev/hda1
    append="elevator=as video=vesafb:ywrap,mtrr,1024x768-16@75"

Шаманим с очередью запросов :)

Проверим параметры и скорость чтения:

hdparm /dev/sda
/dev/sda:
HDIO_DRIVE_CMD(identify) failed: Invalid exchange
readonly = 0 (off)
readahead = 256 (on)
geometry = 783/255/63, sectors = 12582912, start = 0
geometry = 783 cylinders, 255 heads, 63 sectors, total 12582912 sectors
 
hdparm -tT /dev/sda
/dev/sda:
Timing cached reads: 10348 MB in 2.00 seconds = 5176.87 MB/sec
Timing buffered disk reads: 146 MB in 3.01 seconds = 48.48 MB/sec
 
hdparm -tT /dev/sda
/dev/sda:
Timing cached reads: 10620 MB in 2.00 seconds = 5313.12 MB/sec
Timing buffered disk reads: 218 MB in 3.00 seconds = 72.63 MB/sec
 
cat /sys/block/sda/queue/read_ahead_kb

/sys/block/sda/queue/read_ahead_kb

Maximum number of kilobytes to read-ahead for filesystems on this block device. По умолчанию 128, установим echo 512 > /sys/block/sda/queue/read_ahead_kb

/sys/block/sda/queue/nr_requests

This controls how many requests may be allocated in the block layer for read or write requests. Note that the total allocated number may be twice this amount, since it applies only to reads or writes (not the accumulated sum). По умолчанию 128, установим echo 256 > /sys/block/sda/queue/nr_requests

/sys/block/sda/device/queue_depth

По умолчанию echo 32 > /sys/block/sda/device/queue_depth. Судя по многочисленным рассылкам и руководствам по оптимизации параметр queue_depth должен быть всегда меньше nr_requests, что обеспечивает лучшее быстродействие.

Снова проверим скорость чтения

hdparm -tT /dev/sda
/dev/sda:
Timing cached reads: 10590 MB in 2.00 seconds = 5298.29 MB/sec
Timing buffered disk reads: 264 MB in 3.07 seconds = 86.05 MB/sec
 
hdparm -tT /dev/sda
/dev/sda:
Timing cached reads: 10860 MB in 2.00 seconds = 5433.80 MB/sec
Timing buffered disk reads: 278 MB in 3.01 seconds = 92.47 MB/sec
 
hdparm -tT /dev/sda
/dev/sda:
Timing cached reads: 10398 MB in 2.00 seconds = 5202.96 MB/sec
Timing buffered disk reads: 288 MB in 3.02 seconds = 95.39 MB/sec

Видим, что показатели чтения слегка улучшились - ура товарищи:) Скорость чтения зависит от текущей загруженности диска операциями чтения/записи и мерить её лучше в относительно спокойном состоянии, когда почти ничто не пишет и не читает с диска!

Тюнинг I/O Scheduler-а Deadline

/sys/block/sda/queue/iosched/fifo_batch

Устанавливает максимальное число запросов в одном пакете, по умолчанию 16. Увеличение этого значения может улучшить пропускную способность, но в тоже время увеличатся и задержки.

/sys/block/sda/queue/iosched/front_merges

Функция сравнения поступающих в очередь запросов и их слияния в случае их дублирования, по умолчанию 1, лучше так и оставить.

/sys/block/sda/queue/iosched/read_expire

Позволяет установить количество миллисекунд, в течении которых запрос на чтение должен быть обслужен. По умолчанию этот параметр установлен на 500 мс (полсекунды). Если есть задержки с чтением, то можно увеличить это значение.

/sys/block/sda/queue/iosched/write_expire

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

/sys/block/sda/queue/iosched/writes_starved

Планировщик отдаёт больше предпочтения для запросов чтения перед запросами записи. По умолчанию значение этого параметра установлено в 2. Если есть задержки с чтением, то можно увеличить это значение.

Все изменения которые мы вносили в устройства через echo ... > /sys/../../ будут действительны только до перезагрузки, для их внесения на постоянной основе, нужные команды стоит добавить в /etc/rc.local, например:

vi /etc/rc.local
 
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
# I/O Scheduler settings...
# default cfq
 
# I/O Scheduler settings...
# default cfq
echo deadline > /sys/block/sda/queue/scheduler
# default 128
echo 512 > /sys/block/sda/queue/read_ahead_kb
# default 128
echo 256 > /sys/block/sda/queue/nr_requests
# default 32
echo 32 > /sys/block/sda/device/queue_depth
# default 16
echo 16 > /sys/block/sda/queue/iosched/fifo_batch
# default 500
echo 600 > /sys/block/sda/queue/iosched/read_expire
# default 2
echo 3 > /sys/block/sda/queue/iosched/writes_starved

Планировщик ввода/вывода мы подшаманили на увеличение пропускной способности потому, что дальше мы планируем перейти на более активное использование файла подкачки, а это связано с повышенным количеством операция чтения/записи на жестком диске.

Выбираем политику выделения памяти (overcommit)

overcommit_memory и overcommit_ratio - параметры overcommit_memory и overcommit_ratio регулируют политику выделения памяти сверх имеющейся в наличии, а именно overcommit_memory отвечает за саму политику (поведение), а overcommit_ratio за процент выделяемой памяти. Ниже оригинальное описание этих параметров

https://www.kernel.org/doc/Documentation/sysctl/vm.txt

==============================================================

overcommit_ratio:

When overcommit_memory is set to 2, the committed address space is not permitted to exceed swap plus this percentage of physical RAM. See above.

==============================================================

overcommit_memory:

This value contains a flag that enables memory overcommitment.

When this flag is 0, the kernel attempts to estimate the amount of free memory left when userspace requests more memory.

When this flag is 1, the kernel pretends there is always enough memory until it actually runs out.

When this flag is 2, the kernel uses a "never overcommit" policy that attempts to prevent any overcommit of memory. Note that user_reserve_kbytes affects this policy.

This feature can be very useful because there are a lot of programs that malloc() huge amounts of memory "just-in-case" and don't use much of it.

The default value is 0.

See Documentation/vm/overcommit-accounting and
security/commoncap.c::cap_vm_enough_memory() for more information.

==============================================================

  • overcommit_ratio - если overcommit_memory=2, тогда разрешено выделить весь размер файла подкачки (swap) + указанный в overcommit_ratio процент оперативной памяти
  • overcommit_memory
    • 0 - выделяется памяти больше чем есть в наличии, но при этом используется эвристический анализ определения выделяемой процессу памяти;
    • 1 - система считает, что в наличии неограниченное количество памяти и выделяет её без ограничений до тех пор пока она вся реально незакончится;
    • 2 - запрещено выделять память больше чем общий размер файла подкачки (swap) + указанный в overcommit_ratio процент оперативной памяти, в таком случае также включется действие параметра user_reserve_kbytes.
  • user_reserve_kbytes - по умолчанию резервируется 3% свободной памяти от текущего размера процесса, если установлено в 0 то процессу будет разрешено выделить всю имеющуюся в наличии свободную память, а любые попытки выполнить команду могут привести к сообщению "Cannot allocate memory".

Рекомендуется overcommit_memory=2 и overcommit_ratio=95 (или overcommit_ratio=100) - это предотвратит полнейшее падение системы в случае глюка какой-то программы, а также полезно при наличии в системе программ которые могут запрашивать для себя больше оперативной памяти чем им реально требуется.

echo 2 > /proc/sys/vm/overcommit_memory
echo 100 > /proc/sys/vm/overcommit_ratio
 
vi /etc/sysctl.conf
vm.overcommit_memory=2
vm.overcommit_ratio=100
 
sysctl -p

Оптимизируем использование файла подкачки (swap)

Ниже пойдёт речь о параметрах влияющих на использование виртуальной памяти (vm - virtual memory), а т.е. файла подкачки. Значение большинства приведённых ниже параметров на многих сайтах/блогах трактуются НЕ верно и противоречит официальной документации ядра Linux - один прогнал беса, а другие продолжают гнать тупо копируя!

/proc/sys/vm/swappiness

В ОС Linux для управления использованием файлом подкачки есть параметр vm.swappiness, значение которого по умолчанию равно 60

sysctl -a | grep vm.swappiness
vm.swappiness = 60

Как это работает? Значение vm.swappiness контролирует процент доступной оперативной памяти, при котором происходит активный сброс данных в файл подкачки (swap). Например при значении vm.swappiness в 60 вычисляем процент занятой оперативной памяти 100-60=40%, т.е. в данном случае если % занятой памяти равен 40%, то начинается активное использование файла подкачки (раздел swap).

Если у нас маловато оперативной памяти, то выбрав на предварительном этапе более производительный I/O Scheduler мы можем увеличить использование дискового кэша установив значение vm.swappiness равным 70-80.

При наличии же большого количества ОЗУ лучше будет установить значение параметра vm.swappiness в 10-30, чем приказать Linux-у не использовать файл подкачки (swap) пока занятая оперативная память не достигнет 70-90%.

Для проверки/тестирования внесите временные изменения sysctl -w vm.swappiness=90, а если система будет работать стабильно, то можно внести изменения на постоянной основе в /etc/sysctl.conf:

vi /etc/sysctl.conf
vm.swappiness = 90

Значение параметра vm.swappiness подбирается экспериментально, в зависимости от количества работающих процессов и активности их использования. Для систем у которых оперативной памяти 128-256 МВ можно попробовать установить vm.swappiness = 100

Справедливости ради отметим, что на оф. странице сказано, что параметр регулирует агрессивность использования файла подкачки, а не процент занятой или свободной оперативной памяти. Короче говоря, меньшее значение снижает агрссивность, а большее соответственно увеличивает агрессивность использования файла подкачки:

https://www.kernel.org/doc/Documentation/sysctl/vm.txt

swappiness

This control is used to define how aggressive the kernel will swap memory pages.  Higher values will increase agressiveness, lower values decrease the amount of swap.  A value of 0 instructs the kernel not to initiate swap until the amount of free and file-backed pages is less than the high water mark in a zone.

The default value is 60.

/proc/sys/vm/vfs_cache_pressure

Ещё один интересный параметр vm.vfs_cache_pressure, который по умолчанию равен = 100. Внятного и адекватного описания этого параметра на могучем нигде не встречается, а просто приводятся рекомендуемые его значения, местами указывается, что повышение этого значения заставляет активнее использовать оперативную память, что в корне не верно:

http://www.kernel.org/doc/Documentation/sysctl/vm.txt
https://github.com/torvalds/linux/blob/master/Documentation/sysctl/vm.txt

vfs_cache_pressure

------------------

Controls the tendency of the kernel to reclaim the memory which is used for caching of directory and inode objects.

At the default value of vfs_cache_pressure=100 the kernel will attempt to reclaim dentries and inodes at a "fair" rate with respect to pagecache and swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer to retain dentry and inode caches. When vfs_cache_pressure=0, the kernel will never reclaim dentries and inodes due to memory pressure and this can easily lead to out-of-memory conditions. Increasing vfs_cache_pressure beyond 100 causes the kernel to prefer to reclaim dentries and inodes

Честно говоря в официальное описание этого параметра я сам не сразу въехал, пока не наткнулся на Maximizing Performance - ArchWiki, из которой следует, то, сколько ядро отдаёт предпочтения/приоритета на использование подкачки в оперативной памяти. Понижение этого значения заставляет ядро использовать больше подкачки в оперативной памяти (cached).

Чтение документации "When vfs_cache_pressure=0, the kernel will never reclaim dentries and inodes due to memory pressure and this can easily lead to out-of-memory conditions." законно наводит на мысль, что значение равное в 0 заставит ядро полностью перейти на использование оперативной памяти, т.е. не освобождать её, что может привести нехватке памяти и полному загибанию системы.

Другими словами значение этого параметра устанавливает приоритет на частоту возврата/освобождение занимаемой под кэш памяти (cached), при увеличении значения этого параметра занимаемая под кэш память (cached) будет освобождена при первом удобном случае, т.е. оперативная память занятая под caching/directory/inode будет освобождаться агрессивнее. Максимальное значение vm.vfs_cache_pressure неизвестно, по этой ссылке максимальное значение vm.vfs_cache_pressure = 100000.

Значение vm.vfs_cache_pressure зависит от размера имеющейся оперативной памяти, если оперативной памяти много, то значение можно снизить до 20-50, ну, а если мало, то соответственно увеличить.

/proc/sys/vm/dirty_ratio

Параметр vm.dirty_ratio содержит значение в процентах от нашей общей оперативной памяти, которая может быть заполнена грязными данными, при превышении этого лимита данные будут активно сброшены на диск, на время записи все процессы блокируются, например можно выполнить команду "dd if=/dev/zero of=hog" и посмотреть, что происходит;) В CentOS 6 (с 256 МВ оперативки) значение vm.dirty_ratio по умолчанию = 20.

/proc/sys/vm/dirty_background_ratio

Параметр vm.dirty_background_ratio содержит значение в процентах от нашей общей оперативной памяти, после забивания грязными данными которой "pdflush background writeback daemon" начинает сбрасывать данные на диск. В CentOS 6 (с 256 МВ оперативки) по умолчанию значение vm.dirty_background_ratio = 10.

/proc/sys/vm/dirty_writeback_centisecs

vm.dirty_writeback_centisecs содержит значение в миллисекундах устанавливает интервал через который будет просыпаться "pdflush writeback daemons" и сбрасывать старые/грязные данные. По умолчанию vm.dirty_writeback_centisecs = 500 (5 сек.)

/proc/sys/vm/dirty_expire_centisecs

vm.dirty_expire_centisecs устанавливает время в миллисекундах, через которое грязные данные закэшированные в оперативке будут помечены как устаревшие. По умолчанию vm.dirty_expire_centisecs = 3000 (30 сек.), 30 секунд это слишком долго, можно уменьшить это значение. Посмотреть сколько у вас собралось грязных данных можно командой cat /proc/meminfo | grep Dirty

/proc/sys/vm/min_free_kbytes

Минимальное количество свободных/зарезервированных килобайт. Это значение используется для вычисленияwatermark[WMARK_MIN] значения для каждойlowmem зоны. Значение менее чем 1024KB может стать причиной краха системы при высоких нагрузках! Значение по умолчанию зависит от общего количества оперативной памяти, например при наличии 256 МБ оперативки, по умолчанию значение vm.min_free_kbytes = 2030, в таком случае можно округлить до 2-х КБ т.е. vm.min_free_kbytes = 2048. Сильно большое значение этого параметра может привести к нехватке памяти!

/proc/sys/vm/page-cluster

vm.page-cluster контролирует сколько страниц памяти будет сброшено в своп (swap) за один раз, 0 = 1, 2 = 4 и т.д.. По умолчанию значение vm.page-cluster = 3, что равно 8-ми страницам которые сбрасываются в своп (swap) за один раз, т.е. нечётные значения округляются, умножаются на два и получается реальное число страниц сбрасываемых за один раз. Если файл подкачки используется интенсивно, то можно попробовать вдвое увеличить значение vm.page-cluster.

/proc/sys/vm/oom_kill_allocating_task

Параметр vm.oom_kill_allocating_task контролирует поведение киллера процессов. Если установлено равным нулю (по умолчанию = 0), то OOM killer будет сканировать весь список задач и на основании эвристики выбирать процесс для убивания, а если установлено значение более нуля (например = 1), OOM killer просто убивает задачу в условиях нехватки памяти. Сканирование списка задач + эвристика выбора дорого обходится системе, а поэтому можно установить vm.oom_kill_allocating_task = 1

Пакет Kernel Tune (ktune)

Пакет Kernel Tune (ktune) предназначен в первую очередь для серверов с интенсивным использованием дискового пространства, с достаточно большим объемом оперативной памяти и высокой сетевой активности.

Пакет Kernel Tune (ktune) содержит в себе большой набор шаблонов с настройками для оптимизации ядра системы. Ktune включает планировщик ввода/вывода deadline, увеличивает размер TCP/IP буферов, а также выполняет другие настройки по оптимизации производительности. Установка на примере CentOS:

yum install ktune
chkconfig ktune on
service ktune start

Настройки ktune расположены в vi /etc/sysctl.ktune

Следует учесть, что настройки внесённые в /etc/sysctl.conf тоже применяются и имеют больший приоритет перед /etc/sysctl.ktune!

Ссылки по теме

Рекомендуемый контент



Комментарии   

АдМинь БагоИскатель
+1 #8 АдМинь БагоИскатель 09.05.2014 17:15
Цитирую Guest:
Мне просто интересно, зачем в техническом слоге защита от копирования правой кнопкой или ctrl+c?
Если кто захочет скорировать контент - его это не остановит, уж поверьте.
А пользователям жизнь серьезно усложняете - нужное правило хрен скопируешь руками, приходится вручную набирать.
В общем - незачет.

Спору нет, от копи-пасты это незащищает! но, насколько я осведомлён, - это сделано лишь с целью напоминания копи-пастерам, что контент уникальный и для его копирования нужно придерживаться наших требований, главное среди которых живой линк на первоисточник (наш либо иной сайт-источник)! иначе..., - "Где хочешь говорит найду, бритвой по горлу и в колодезь!" ;-)

8) а на счёт набора нужного правила ручками, то так и должно быть! Во-первых дабы жизнь мёдом не казалась, а вовторых ради Вашего же блага! имхо в правилах могут быть кириллические символы, применение которых в свою очередь также может вызывать Ваши гневные отзывы.

Настоящий одмин все правила в консоли набирает ручками либо теми же ручками предварительно препарирует их в отдельном файле или скрипте.
Цитировать
Guest
+1 #7 Guest 09.05.2014 14:48
Мне просто интересно, зачем в техническом слоге защита от копирования правой кнопкой или ctrl+c?
Если кто захочет скорировать контент - его это не остановит, уж поверьте.
А пользователям жизнь серьезно усложняете - нужное правило хрен скопируешь руками, приходится вручную набирать.
В общем - незачет.
Цитировать
Иван Шаман
0 #6 Иван Шаман 26.04.2014 02:38
Цитирую Guest:

Для защиты я использую DenyHosts и меня она полностью устраивает, хотя гогда я выбирал что ставить у меня стоял кокраз выбор между fail2ban и DenyHosts выбрал второе и уже не стал пробовать fail2ban за ненадобностью. Если есть стото по DenyHosts рад буду увидеть статью или в кометах.
Сайт Ваш понравился, хотя то сто у вас политика я не приветствую но это лично моё мнение.

Скажем прямо.... DenyHosts - это вчерашний день! Вопервых он не развивался начиная с "2008-10-04", а во вторых ещё и в статусе "бета" по день сегодняшний! fail2ban - жёсткая и многофункционал ьная Штука и + активно развивающаяся!

И, да, если не секрет..., - "у вас политика я не приветствую но это лично моё мнение.", о какой политике идёт речь? Нам важно знать Ваше мнение!
Цитировать
Guest
0 #5 Guest 25.04.2014 22:17
Цитирую АдМинь БагоИскатель:
;-) Полностью никогда и ничего не бывает, - нет полной демократии, полной свободы или полной независимости! Так же и с защитой от ДДОС... Кстати, если для защиты от брута используется fail2ban, то его же можно приспособить и для дополнительной защиты от ДДОС-а.


Для защиты я использую DenyHosts и меня она полностью устраивает, хотя гогда я выбирал что ставить у меня стоял кокраз выбор между fail2ban и DenyHosts выбрал второе и уже не стал пробовать fail2ban за ненадобностью. Если есть стото по DenyHosts рад буду увидеть статью или в кометах.
Сайт Ваш понравился, хотя то сто у вас политика я не приветствую но это лично моё мнение.
Цитировать
АдМинь БагоИскатель
0 #4 АдМинь БагоИскатель 24.04.2014 22:24
Цитирую Guest:
Имею vps и последнее время учистились случии атак на него и пару раз ложили его. Защиту ставил от брута (справляется отлично) вот щас задумался от досс атак защитить, хотя полность не получиться но всёже минимихзировать можно.
Статья хорошая, забил в закладки.

;-) Полностью никогда и ничего не бывает, - нет полной демократии, полной свободы или полной независимости! Так же и с защитой от ДДОС... Кстати, если для защиты от брута используется fail2ban, то его же можно приспособить и для дополнительной защиты от ДДОС-а.
Цитировать
Guest
+1 #3 Guest 24.04.2014 12:12
Имею vps и последнее время учистились случии атак на него и пару раз ложили его. Защиту ставил от брута (справляется отлично) вот щас задумался от досс атак защитить, хотя полность не получиться но всёже минимихзировать можно.
Статья хорошая, забил в закладки.
Цитировать
Guest
+1 #2 Guest 19.12.2013 16:53
Хорошая статья...все хорошо расписано и доступно, но от количества новой информации..чут ь мозг не взорвался. :o
Цитировать
Guest
+3 #1 Guest 27.06.2013 10:10
Спасибо за статью.
Очень интересно и подробно.
Буду штудировать...
Цитировать

Добавить комментарий

АХТУНГ! Все комменты модерасятся модерастом. Мессаги исключительно рекламного или оскорбительного содержания не публикуются, а поэтому злостным спамерам, пранкерам и прочей сетевой нечисти рекомендуем напрасно не тратить своего времени и удовлетворять свои больные фантазии на специализированных Интернет ресурсах! Разумная же критика, замечания, дополнения и хвалебные оды приветствуются, также допускается легкий флуд или троллинг :)


Защитный код
Обновить

Рейтинг@Mail.ru 6 megabytes