FastNetMon

Sunday, 29 March 2015

Стабильность работы netmap-ipfw на Linux

Тест выполнялся почти 3е суток, нагрузка со стороны генератора флуда была около 6MPPS, рандомного udp флуда.
ps aux|grep kipfwroot     19036 72.1  0.0 676328  2728 pts/2    R    Mar26 2731:56 ./kipfw netmap:eth4-0 netmap:eth6-0root     19037 68.9  0.0 676328  2728 pts/2    R    Mar26 2610:52 ./kipfw netmap:eth4-1 netmap:eth6-1root     19038 69.7  0.0 676328  2728 pts/2    S    Mar26 2640:07 ./kipfw netmap:eth4-2 netmap:eth6-2root     19039 68.9  0.0 676328  2992 pts/2    S    Mar26 2610:41 ./kipfw netmap:eth4-3 netmap:eth6-3root     21088  0.0  0.0   7768   852 pts/1    S+   11:17   0:00 grep kipfw
Нагрузка на машине была почти предельная:
  [||||||||||||||||||||||||||||||||||||||||||         72.7%]     Tasks: 35, 55 thr, 47 kthr; 2 running  [|||||||||||||||||||||||||||||||||||||||            69.1%]     Load average: 2.15 2.60 2.69   [|||||||||||||||||||||||||||||||||||||||||          71.4%]     Uptime: 12 days, 11:33:08  [||||||||||||||||||||||||||||||||||||||||           68.2%]  Mem[|||||||                                     1332/32207MB]  Swp[                                                0/8190MB]

Но ничего не упало и паразитный трафик не прошел! :)

Wednesday, 18 March 2015

Контроль за состоянием php-fpm силами monit на Debian

Вот так:
check process php5-fpm with pidfile /var/run/php5-fpm.pid
  start program = "/etc/init.d/php5-fpm start"
  stop program  = "/etc/init.d/php5-fpm stop"
  if failed unixsocket /var/run/php5-fpm.sock  then restart
  if 3 restarts within 5 cycles then timeout

Tuesday, 17 March 2015

Фильтрация трафика силами сетевой карты

Очень редко при защите от DDoS кто-либо освещает эту тему и совершенно неоправданно.

Итак, как? Начнем с того, что у Вас должна быть приличная 10GE сетевая карточка (например, Intel XL710 или же Intel 82599 - я буду проводить тесты на нем). Сразу хочу оговориться, что драйверы для сетевой карты нужно брать НЕ из дистрибутива (они очень малофункциональны), а из проекта ixgbe на Sourceforge.

Во-вторых, нужен механизм управления этим всем делом. Обычно, это делается силами ethtool.

Приступим!

Для начала нам нужно сконфигурировать сетевую и ее драйвер:
vim /etc/modprobe.d/ixgbe.conf
И добиваем к существующим там такой параметр (он нужен чтобы выделить 32 тысячи ):
FdirPballoc=3,3,3,3
После этого драйвер нужно передернуть и поднять ифейсы заново:
rmmod ixgbe
modprobe ixgbe
ifconfig 11.22.33.44. eth4
Что же мы сделали? Мы включили функциональность фильтрации сетевой. Почему именно 3?

Есть три варианта значения поля FdirPballoc и мы выбрали наибольший размер, чтобы побольше правил набить:
1 = 8k hash filters or 2k perfect filters
2 = 16k hash filters or 4k perfect filters
3 = 32k hash filters or 8k perfect filters (array of int)
Убеждаемся по dmesg, что все зацепилось:
dmesg|grep 'Flow Director'
[45847.024851] ixgbe: Flow Director packet buffer allocation set to 3
[45847.024874] ixgbe: 0000:0a:00.0: ixgbe_check_options: Flow Director will be allocated 256kB of packet buffer
Включаем поддержку ntuple фильтров на уровне сетевой:
ethtool -K eth4 ntuple on
Итак, посмотрим список наших правил - он должен быть пуст:
ethtool --show-ntuple eth4
4 RX rings available
Total 0 rules
А вот далее идет сложный синтаксис и поэтому привожу выдачу ethtool --help:
        ethtool -N|-U|--config-nfc|--config-ntuple DEVNAME    Configure Rx network flow classification options or rules
        rx-flow-hash tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 m|v|t|s|d|f|n|r... |
        flow-type ether|ip4|tcp4|udp4|sctp4|ah4|esp4
            [ src %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
            [ dst %x:%x:%x:%x:%x:%x [m %x:%x:%x:%x:%x:%x] ]
            [ proto %d [m %x] ]
            [ src-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]
            [ dst-ip %d.%d.%d.%d [m %d.%d.%d.%d] ]
            [ tos %d [m %x] ]
            [ l4proto %d [m %x] ]
            [ src-port %d [m %x] ]
            [ dst-port %d [m %x] ]
            [ spi %d [m %x] ]
            [ vlan-etype %x [m %x] ]
            [ vlan %x [m %x] ]
            [ user-def %x [m %x] ]
            [ action %d ]
            [ loc %d]] |
        delete %d
Итак, запустим на машину DDoS атаку вот таким паттерном:
12:45:19.050037 IP 10.10.10.100.41356 > 10.10.10.200.61598: UDP, length 18
12:45:19.050045 IP 10.10.10.100.9967 > 10.10.10.200.24210: UDP, length 18
12:45:19.050052 IP 10.10.10.100.17254 > 10.10.10.200.44345: UDP, length 18
12:45:19.050061 IP 10.10.10.100.17516 > 10.10.10.200.41543: UDP, length 18
12:45:19.050069 IP 10.10.10.100.29307 > 10.10.10.200.60769: UDP, length 18
12:45:19.050078 IP 10.10.10.100.56313 > 10.10.10.200.49897: UDP, length 18
12:45:19.050085 IP 10.10.10.100.17761 > 10.10.10.200.6767: UDP, length 18
12:45:19.050093 IP 10.10.10.100.24303 > 10.10.10.200.12295: UDP, length 18
12:45:19.050101 IP 10.10.10.100.27105 > 10.10.10.200.52313: UDP, length 18
12:45:19.050109 IP 10.10.10.100.32141 > 10.10.10.200.55003: UDP, length 18
12:45:19.050119 IP 10.10.10.100.10274 > 10.10.10.200.11494: UDP, length 18

Итог - плачевен, машина почти убита нагрузкой:
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 75.0 id,  0.0 wa,  0.0 hi, 75.0 si,  0.0 st

Попробуем собрать фильтр под эту атаку.
ethtool --config-ntuple eth4 flow-type udp4 src-ip 10.10.10.100 m 255.255.255.0 action -1
Как можно догадаться, -1 означает безусловный drop трафика.

Посмотрим, что у нас получилось:
ethtool --show-ntuple eth4
4 RX rings available
Total 1 rules

Filter: 8189
    Rule Type: UDP over IPv4
    Src IP addr: 0.0.0.100 mask: 255.255.255.0
    Dest IP addr: 0.0.0.0 mask: 255.255.255.255
    TOS: 0x0 mask: 0xff
    Src port: 0 mask: 0xffff
    Dest port: 0 mask: 0xffff
    VLAN EtherType: 0x0 mask: 0xffff
    VLAN: 0x0 mask: 0xffff
    User-defined: 0x0 mask: 0xffffffffffffffff
    Action: Drop
Как удалить правило? Проще простого:
ethtool --config-ntuple eth4 delete 8189
Вуаля, при той же атаке в 7mpps мы не наблюдаем нагрузки вообще:
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
При этом убедиться, что правило flow director работает можно очень просто:
ethtool -S eth4 |grep fdir
     fdir_match: 916143392
     fdir_miss: 139427055
     fdir_overflow: 0
Вот таким образом можно сильно облегчить жизнь Linux боксу под атакой :) Но не стоит забывать, что функциональность по фильтрации довольно слабая - только IP и порты для входящего и исходящего трафика.

Но, например, таким образом можно сделать крутую защиту от UDP амплификации. И выживать пока не кончится аплинк :)

Monday, 16 March 2015

Установка exabgp - швейцарский нож для готовки BGP и flow spec

В Debian:
apt-get install -y python-pip

И ставим через pip:
pip install exabgp
 Блин, и чего с ней дальше делать :) Документация гхм...

Thursday, 12 March 2015

Установка и использование ipset на Debian 7 Wheezy

Просто бесконечно проста с учетом того, что ipset теперь идет в поставке ядра:
dpkg -S /lib/modules/3.2.0-4-amd64/kernel/net/netfilter/ipset/ip_set_list_set.ko
linux-image-3.2.0-4-amd64: /lib/modules/3.2.0-4-amd64/kernel/net/netfilter/ipset/ip_set_list_set.ko
Ставим зависимости:
apt-get install ipset 
Создаем хэш:
ipset --create blacklist iphash --hashsize 4096
Смотрим его содержимое:
ipset --list
Name: blacklist
Type: hash:ip
Header: family inet hashsize 4096 maxelem 65536
Size in memory: 65656
References: 0
Members:
Добавляем несколько IP в список блокировки:
ipset --add blacklist 41.231.136.121
ipset --add blacklist 37.236.253.170
ipset --add blacklist 37.236.239.42
Убеждаемся, что они добавлены:
ipset --list
Name: blacklist
Type: hash:ip
Header: family inet hashsize 4096 maxelem 65536
Size in memory: 65704
References: 0
Members:
41.231.136.121
37.236.253.170
37.236.239.42
Добавляем правило iptables для отсечения товарищей, кто в этом списке:
iptables -I INPUT -m set --match-set blacklist src -p TCP --destination-port 80 -j DROP
В итоге это будет выглядеть примерно так:
iptables -nvL
Chain INPUT (policy ACCEPT 2822 packets, 188K bytes)
 pkts bytes target     prot opt in     out     source               destination        
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set blacklist src tcp dpt:80

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        

Chain OUTPUT (policy ACCEPT 1882 packets, 320K bytes)
 pkts bytes target     prot opt in     out     source               destination          

Огромное преимущество ipset в том, что он сам проверяет на наличие дубликатов (на самом деле это приятное следствие из его структуры данных - хэша) и не нужно заниматься этим самостоятельно:
ipset --add blacklist 41.176.136.101
ipset v4.2: 41.176.136.101 is already in set blacklist.

Удалять IP из бана нужно следующим образом:
ipset --del blacklist 41.176.136.101

Полностью очистить спсиок блокировки можно так:
ipset --flush blacklist

Использования модуля при ну очень большом числе IP показывает, что он весьма стабилен и отлично работает:
ipset  -L | wc -l
43815
Баги/фичи:  "ipset v4.2: IP/port/element is outside of the set or set is full", при достжении размера очереди 65 тысячам IP:
ipset -L |wc -l
65541
Фикс - нет фикса (http://flug.org.ua/lists/debian-russian/71086/) Как обходник можно создать кучу хэшей и пропускать трафик через них.

Еще будет полезной фича ipset save, с помощью которой можно сделать восстановление/сохранение содержимого списков при перезагрузке:
ipset save
create blacklist hash:ip family inet hashsize 4096 maxelem 65536
add blacklist 41.231.136.121
add blacklist 37.236.253.170
add blacklist 37.236.239.42

Источники: http://lmn.name/archives/331 http://daemonkeeper.net/781/mass-blocking-ip-addresses-with-ipset/


Sunday, 8 March 2015

Сброс полного содержимого BGP таблица в демоне Quagga

Обращаю внимание, что извлекать мы будем не скомпонованный дамп с "лучшими путями", а именно сырую информацию, на основании которой Quagga BGP демон выбирает лучший путь.

Осуществляется вот так:
vtysh -d bgpd -c "conf term" -c "dump bgp routes-mrt /var/run/bgpdata/rib.%F.%H%M 10m"
Отключается вот так:
vtysh -d bgpd -c "conf term" -c "no dump bgp routes-mrt /var/run/bgpdata/rib.%F.%H%M 10m"
Стоит отметить, что папка /var/run/bgpdata должна существовать и принадлежать пользователю quagga:quagga.

Если хотите вбить в конфиг, то это будет выглядеть вот так:
dump bgp routes-mrt /var/run/bgpdata/rib.%F.%H%M 10m
Стоит отметить, что внутри этого дампа (его размер считается как 40 мегабайт умноженное на число аплинков от которых принимается Full Table BGP).

Он в бинарном формате и чтобы конвертировать в текст понадобится спец тулза, которой конвертируем в текстовый вид (и 114 мб для 3*Full BGP превратятся сразу же в 450 мб в текстовом формате):
/opt/libbgpdump/bgpdump rib.2015-03-08.2010 -O rib.2015-03-08.2010.parsed 

За исследование и реализацию огромное спасибо Andrey Ziltsov :)

Wednesday, 4 March 2015

Использование решения на базе Linux и netmap-ipfw для суперскоростной фильтрации паразитного трафика

Последнее время стали довольно распространены высокоскоростные атаки, осуществляемые с использованием различных вариантов усиления (amplification) трафика.

Как же с ними бороться? Довольно сложно, это стоит понимать. Дешевые решения в виде ACL на 10GE свиче либо аппаратных правил на NIC (сетевой карте) - могут блокировать лишь часть паразитного трафика с очень ограниченным набором параметров - src/dst IP, src/dst port и протокол.

Более серьезные решения требуют привлечения либо высокопроизводительных роутеров (речь про роутеры класса Juniper MX 120+, и к слову, возможности фильтрации трафика у роутеров тоже весьма ограничены) либо аппаратных фаерволлов, например, от Arbor. Роутеры стоят огромных денег, но почти всегда есть в ДЦ - это плюс. А специализированное железо от Arbor стоит совершенно непомерные суммы.

Итак, наше решение софт бокс-фильтр, машина 10GE картами, кучей процессорных мощностей и Linux либо FreeBSD на борту.

Стоит понимать, что стандартными средствами того же Linux атаку в 10Mpps не отбить, в конце концов, он просто упадет, например, вот так. Во FreeBSD ситуация во многом похожая и еще более усложняющаяся (для меня) не особо хорошим пониманием этой ОС.

Поэтому в качестве решения я обратился к системам прямого доступа к сетевой карте класса netmap, PF_RING, DPDK, а именно - мы будем использовать netmap, потому что он очень быстр, не требует лицензии и под него есть портированный фаерволл ipwf.

Итак, приготовим машину на Debian 7, с сетевыми картами ixgbe с по меньшей мере двумя интефейсами. Так как машина должна подключаться в разрез между атакуемой машиной и аплинком.

Сборка довольно проста, сначала нужно собрать netmap со всеми драйверами и загрузить его.

После этого нужно установить в систему заголовочные файлы для netmap, чтобы собрать тулкит:
Стягиваем заголовки:
cd /usr/include/net
wget https://raw.githubusercontent.com/luigirizzo/netmap/master/sys/net/netmap_user.h
wget https://raw.githubusercontent.com/luigirizzo/netmap/master/sys/net/netmap.h
Собираем:
cd /usr/src
git clone https://github.com/luigirizzo/netmap-ipfw.git
cd netmap-ipfw
make
Запускаем:
./kipfw netmap:eth4 netmap:eth6
После этого можем загрузить тестовое правило в ipfw:

cd ipfw
./ipfw add 1 deny tcp from any to any 80 in
Для испытания насколько это решение хорошо в продакшене я запустил syn флуд в 7mpps с тестовой машины силами trafgen.

Метрики моей  тесты машины (а это слабый CPU E5-2407 0 @ 2.20GHz x 4) на картинке:
top - 13:33:05 up 3 min,  2 users,  load average: 0.44, 0.13, 0.05
Tasks:  78 total,   2 running,  76 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.0 us, 14.8 sy,  0.0 ni, 74.6 id,  0.0 wa,  0.0 hi,  0.7 si,  0.0 st
KiB Mem:  32980328 total,   546592 used, 32433736 free,    45320 buffers
KiB Swap:  8387580 total,        0 used,  8387580 free,    32204 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                 
 3105 root      20   0  660m 9060 8908 R  99.5  0.0   0:25.36 kipfw    


  1  [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]     Tasks: 26, 3 thr, 52 kthr; 2 running
  2  [                                                             0.0%]     Load average: 0.60 0.19 0.07
  3  [                                                             0.0%]     Uptime: 00:03:48
  4  [|                                                            0.7%]
  Mem[|||                                                   458/32207MB]
  Swp[                                                         0/8190MB]
Как можно видеть, машина прогрузилась лишь на 1/5, но одно ядро выгружено полностью (об этом отдельно).

Вполне неплохой показатель для такого слабого железа!

Теперь попробуем ту же самую задачу простого бриджинга сделать на Linux.

Ставим бридж утилс:
apt-get install -y bridge-utils
Добавляем интерфейсы в него:
brctl addbr mybridge
brctl addif mybridge eth4
brctl addif mybridge eth6
ifconfig mybridge up
И после этого вливаем те же 7mpps:
 1  [||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||99.1%]     Tasks: 25, 3 thr, 48 kthr; 2 running
  2  [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]     Load average: 0.47 0.23 0.15
  3  [|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%]     Uptime: 1 day, 14:24:01
  4  [||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||99.1%]
  Mem[||||                                                  497/32207MB]
  Swp[                                                         0/8190MB]


Шапка top выглядит еще более ужасающе:
top - 13:21:10 up 1 day, 14:24,  2 users,  load average: 1.57, 0.53, 0.26
Tasks:  73 total,   5 running,  68 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,  0.4 id,  0.0 wa,  0.0 hi, 99.6 si,  0.0 st
KiB Mem:  32980328 total,   812976 used, 32167352 free,    40784 buffers
KiB Swap:  8387580 total,        0 used,  8387580 free,   263172 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                 
   15 root      20   0     0    0    0 R  93.5  0.0  57:08.71 ksoftirqd/2                                                                             
   10 root      20   0     0    0    0 R  90.9  0.0  39:51.09 ksoftirqd/1                                                                             
    3 root      20   0     0    0    0 R  65.8  0.0  71:59.15 ksoftirqd/0                                                                             
   19 root      20   0     0    0    0 R  64.8  0.0  59:43.95 ksoftirqd/3                                                                             
 2806 root      20   0 20520  824  548 S   1.3  0.0   0:12.81 irqbalance                                                                              
 4723 root      20   0     0    0    0 S   1.0  0.0   0:18.05 kworker/1:2                                                                             
  342 root      20   0     0    0    0 S   0.7  0.0   0:13.04 kworker/2:1                                                                             
 2866 ntp       20   0 39076 2404 1764 S   0.7  0.0   0:08.80 ntpd                                                                                    
 5163 root      20   0     0    0    0 S   0.7  0.0   0:32.55 kworker/0:1    
Как можете видеть - Linux с этой задачей не справился потому что в нем используется схема с многократным копированием пакета вместо одноразового. Кроме этого, сам по себе стек Linux довольно тяжел и плохо приспособлен к подобной нагрузке по умолчанию.

А теперь попробуем силами все того же netmap-ipfw отбить эту атаку по отпечатку. А именно используя ее снимок из tcpdump:
11:43:10.008418 IP 198.18.51.106.62978 > 10.10.10.248.http: Flags [S], seq 1137192741, win 16, length 0
11:43:10.008419 IP 198.18.51.93.34560 > 10.10.10.113.http: Flags [S], seq 4245548258, win 16, length 0
11:43:10.008419 IP 198.18.51.98.30252 > 10.10.10.89.http: Flags [S], seq 1765400726, win 16, length 0
11:43:10.008420 IP 198.18.51.144.19980 > 10.10.10.91.http: Flags [S], seq 1052340006, win 16, length 0
11:43:10.008420 IP 198.18.51.30.38034 > 10.10.10.38.http: Flags [S], seq 2198215300, win 16, length 0
11:43:10.008421 IP 198.18.51.140.60388 > 10.10.10.133.http: Flags [S], seq 2831049352, win 16, length 0

В Linux блокировка такого трафика была бы задачей нетривиальной, но тут мы можем попробовать использовать необычайно малый размер окна и отсутствие опций tcp пакета вообще (в реальной жизни это нонсенс):
./ipfw add 8 deny tcp from any to any tcpwin 16 tcpdatalen 0
Сразу убеждаемся, что в правило начал лететь трафик:
./ipfw -a list
connected to 127.0.0.1:5555
nalloc 2248 nbytes 124 ptr (nil)
00008 578904841 23156193640 deny tcp from any to any tcpwin 16 tcpdatalen 0
65535  18831554   753262160 allow ip from any to any
Нагрузка машины-фильтра при этом была в рамках разумного:
top - 13:46:15 up 16 min,  2 users,  load average: 0.87, 0.65, 0.40
Tasks:  74 total,   2 running,  72 sleeping,   0 stopped,   0 zombie
%Cpu(s): 21.8 us,  3.0 sy,  0.0 ni, 74.7 id,  0.0 wa,  0.0 hi,  0.4 si,  0.0 st
KiB Mem:  32980328 total,   547800 used, 32432528 free,    45708 buffers
KiB Swap:  8387580 total,        0 used,  8387580 free,    32824 cached

 Как я уже обращал внимание, процесс kipfw выедает одно ядро полностью и это будет (если уже не является) причиной провалов в трафике, потому что он не успевает отбрабатывать весь проходящий трафик корректно.

Что с этим делать? Нужно делать патчи для kipfw для параллельной обработки либо попробовать запустить число инстансов kipfw по числу аппаратных очередей на сетевой карте. Таким образом в самом худшем случае на каждый процессор выйдет нагрузка не более чем 14/4=3.5Mpps на ядро, что в принципе разумная цифра.

В принципе, тот же самый подход скорее всего решит проблемы с производительностью kipfw на FreeBSD, там он ровно также упирается в скорость одного ядра.

Если у кого есть желание присоединиться к проекту в качестве тестера или разработчика - мои контакты справа.

Monday, 2 March 2015

Сборка netmap с поддержкой ixgbe драйвера из поставки дистрибутива


Как гайд для начала рекомендую следующую статью: http://www.stableit.ru/2014/10/netmap-debian-7-wheezy-intel-82599.html

Обращаю внимание, что репо netmap переехал и новый адрес его такой: https://github.com/luigirizzo/netmap.git

Build netmap on Debian 7 Wheezy with ixgbe 10GE NIC (82599):

Get kernel sources:
cd /usr/src
apt-get source  linux-image-3.2.0-4-amd64
Стягиваем код netmap:
cd /usr/src
git clone https://github.com/luigirizzo/netmap.git
cd netmap/LINUX/
Собираем netmap и драйвер:
./configure --kernel-sources=/usr/src/linux-3.2.65 --drivers=ixgbe
make
make install

Load modules:
insmod ./netmap.ko
modprobe mdio
modprobe ptp
modprobe dca
insmod ixgbe/ixgbe.ko
Стоит обратить внимание, что данный режим работы единственный, стабильно работы которого удалось достичь на Linux.

Чтобы добиться запуска при загрузке машины нужно сделать что-то вот такое:
rmmod ixgbe
insmod /usr/src/netmap/LINUX/netmap.ko
modprobe mdio
modprobe ptp
modprobe dca
insmod /usr/src/netmap/LINUX/ixgbe/ixgbe.ko

Thursday, 12 February 2015

Установка htop на FreeBSD 10

Стандартный top на FreeBSD очень не интуитивен, поэтому воткнем же htop!

Итак, ставим:
pkg install htop

Активируем модули эмуляции Linux:
echo 'linux_load="YES"' >> /boot/loader.conf
echo 'linux_enable="YES"' >> /etc/rc.conf

Добавляем монтирование Linux proc fs в /etc/fstab:
linproc         /compat/linux/proc      linprocfs         rw 0 0

После этого перезагружаемся либо делаем:
mount linproc
И наслаждаемся видом htop!

Wednesday, 28 January 2015

Система фиксации входящих и исходящих DDoS атак с поддрежкой sFLOW v5/NetFlov v5/v9 и mirror-портов - FastNetMon

Друзья! Кто заинтересовался заголовком прошу на GitHub, попробовать новую версию FastNetMon, где добавлена поддержка NetFlow, что позволяет фиксировать атаки на любой имеющейся инфраструктуре с минимальными телодвижениям: https://github.com/FastVPSEestiOu/fastnetmon :)

Wednesday, 21 January 2015

Новое слово в хранении данных - BLOCK-RAID

Я довольно давно вынашивал эту идею и довольно странно, что она никем еще не реализована.

Как многие знают, при очень большом числе дисков в массиве - 12/24/48 или даже 96 стандартные режимы работы RAID (к ним я отношу 0/1/10/5/6) уже категорически неприменимы, ибо даже самый надежный RAID-6 дает совершенно неадекватные цифры по уровню надежности.

Разумеется, можно использовать совмещенные режимы, когда, например, RAID-0 собирается поверх нескольких RAID-6. Это немного улучшает ситуацию, но для кейсов 48/96 дисков по-прежнему не особо приятно себя ведет.

Кроме этого, очень мало реальных данных, которые будут эффективно разбросаны по 24м дискам (кейс RAID-6). Какой объем нужно записывать в среднем, чтобы он был разбросан по аж 24м дискам? Нереальный, согласитесь. А если писать на каждый диск по байту - тоже получится весьма и весьма печальная ситуация.

Кроме этого, редкий RAID даст собрать, скажем, 24х дисковый RAID-10 (тот же LSI ограничен 16ю дисками).

Намного более хорошая ситуация у нас с ZFS. Там есть режимы RAIDZ-1/2/3 которые в свою очередь являются аналогами RAID-5 (выдерживает отказ 1го диска) / RAID-6 (выдерживает отказ 2х дисков), а RAID-Z3 аналогов вовсе не имеет! Зато переживает отказ аж 3х любых дисков в массиве!

Но даже ZFS в чистом при большом числе дисков не панацея. Но если сделать, скажем ZFS stripe поверх десятка RAID-Z3, то можно достигнуть очень крутого уровня надежности и емкости!

Но если речь идет о хранении очень больших файлов, то самый гибкий вариант, который приходит в голову - это разбить файл на блоки и разбросать по N (2 и более) разным логическим устройствам!
Таким образом, мы сможем читать файл параллельно из двух мест (например, осуществляя выборку четных/нечетных блоков с разных дисков), но при записи придется писать на два устройства, что может привести к задержкам, так как скорость записи будет ограничена скоростью дисковых устройств.

Такой режим распределения данных используется в распределенном хранилище-mapdreduce кластере HADOOP (а также его реализации HDFS).

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

Конечно, такой режим приводит к 2-3х кратной потере места, но дает очень высокий уровень гибкости и полной независимости от числа дисков в массиве.

Но стоит отметить, что для случая механических дисков все не так очевидно - этот вариант будет точно очень плох для SATA и даже SAS. Но вот для SSD, когда скорости одного диска хватает почти любому приложению (а вот надежности - нет), будет просто идеален.

Стоит отметить, что такой режим можно легко реализовать с помощью Linux Device Mapper или же того же ZFS, с помощью использования опции copies:
copies=1 | 2 | 3
Controls the number of copies of data stored for this dataset. These copies are in addition to any redundancy provided by the pool, for example, mirroring or RAID-Z. The copies are stored on different disks, if possible. The space used by multiple copies is charged to the associated file and dataset, changing the used property and counting against quotas and reservations. Changing this property only affects newly-written data. Therefore, set this property at file system creation time by using the -o copies=N option.
Разве что стоит обратить внимание, что ZFS не умеет "жесткой" гарантии на размещение таких данных на разных дисках. Она лишь пытается, но не гарантирует.

Также стоит отметить потрясающий уровень гибкости такого решения.
  1. Мы можем на лету добавлять диски, сколько угодно и никакого полного копирования данных.
  2. Мы можем свободно удалять диск из системы не заменяя его ни на что при наличии свободного места на другом массиве - все данные перетекут на свободное место
  3. Мы можем собирать массивы из разных по скорости дисков и при выделении нового volume указывать, что "разместить на пуле с SSD".
  4. Мы можем постоянно двигать блоки с диска на диск (например, как раз в случае потребности в более высокой скорости). Причем, это может осуществляться динамически (сама система переносит их на более быстрый сторадж)!
  5.  При таком подходе даже теряя 3+ дисков, на которых размещен раздел мы теряем лишь  разделы, размещенные лишь на этом диске! Но других разделов это не касается!
Пункт 5 на самом деле очень и очень важный потому что в классических RAID (что программных, что аппаратных) потеря дисков больше чем допустима для соотвествующего уровня RAID - фатальна, а для BLOCK RAID - это можно пережить - повредятся лишь затронутые данные! Это крайне актуально особенно в случае хранения нескольких тысяч терабайт данных. Безусловно, потеря 1/100 этих данных будет крайне неприятна, но это в миллион раз менее неприятно и фатально, чем потеря ВСЕГО массива!

Добрые люди подсказали, что по похожей схеме устроен Google File System: https://ru.wikipedia.org/wiki/Google_File_System

ZFS on Linux боевые тесты на бажном железе!

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

Насколько бажна эта машина и диски на ней? За последний год на ней диски менялись 12 раз! 2 раза менялся контроллер и 2 раза полностью пересоздавалась фс (ext4 поверх LSI/RAID-10) в связи с тотальным повреждением. 

Итак, после недели работы и активной записи перезаписи ZFS-таки перешел в состояние DEGRADED!

И порадовал меня 23 тыщами ошибок записи на /dev/sdd:
zpool status
  pool: data
 state: DEGRADED
status: One or more devices are faulted in response to persistent errors.
    Sufficient replicas exist for the pool to continue functioning in a
    degraded state.
action: Replace the faulted device, or use 'zpool clear' to mark the device
    repaired.
  scan: none requested
config:

    NAME        STATE     READ WRITE CKSUM
    data        DEGRADED     0     0     0
      mirror-0  ONLINE       0     0     0
        sdb     ONLINE       0     0     0
        sdc     ONLINE       0     0     0
      mirror-1  DEGRADED     0     0     0
        sdd     FAULTED      3 23.0K     0  too many errors
        sde     ONLINE       0     0     0
      mirror-2  ONLINE       0     0     0
        sdf     ONLINE       0     0     0
        sdg     ONLINE       0     0     0
При этом в dmesg творился настоящий ад!
[919595.775408] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.775492] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 07 67 c7 40 00 00 08 00
[919595.775551] end_request: I/O error, dev sdd, sector 124241728
[919595.775622] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.775698] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 08 59 39 50 00 00 08 00
[919595.775756] end_request: I/O error, dev sdd, sector 140065104
[919595.775808] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.775884] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 09 15 92 b8 00 00 08 00
[919595.775940] end_request: I/O error, dev sdd, sector 152408760
[919595.775987] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.776061] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 09 24 1c 40 00 00 08 00
[919595.776118] end_request: I/O error, dev sdd, sector 153361472
[919595.776165] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.776240] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 08 56 f5 00 00 00 08 00
[919595.776297] end_request: I/O error, dev sdd, sector 139916544
[919595.776349] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.776424] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 06 40 4a 30 00 00 08 00
[919595.776481] end_request: I/O error, dev sdd, sector 104876592
[919595.776529] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.776605] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 02 7f ef 10 00 00 08 00
[919595.776662] end_request: I/O error, dev sdd, sector 41938704
[919595.776709] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.776783] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 09 3e 8d 98 00 00 08 00
[919595.776841] end_request: I/O error, dev sdd, sector 155094424
[919595.776889] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.776965] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 09 8a 21 a8 00 00 08 00
[919595.777021] end_request: I/O error, dev sdd, sector 160047528
[919595.777070] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919595.777145] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 08 86 97 80 00 00 08 00
[919595.777202] end_request: I/O error, dev sdd, sector 143038336
[919596.519092] megaraid_sas: scanning for scsi0...
[919610.884574] __ratelimit: 94 callbacks suppressed
[919610.884625] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919610.884691] sd 0:2:3:0: [sdd] CDB: Read(10): 28 00 00 00 0a 10 00 00 10 00
[919610.884741] __ratelimit: 94 callbacks suppressed
[919610.884776] end_request: I/O error, dev sdd, sector 2576
[919610.884821] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919610.884887] sd 0:2:3:0: [sdd] CDB: Read(16): 88 00 00 00 00 01 5d 3f b4 10 00 00 00 10 00 00
[919610.884969] end_request: I/O error, dev sdd, sector 5859423248
[919610.885009] sd 0:2:3:0: [sdd]  Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[919610.885075] sd 0:2:3:0: [sdd] CDB: Read(16): 88 00 00 00 00 01 5d 3f b6 10 00 00 00 10 00 00
[919610.885155] end_request: I/O error, dev sdd, sector 5859423760
После этого выполняем замену сбойного диска и ждем ресилверинга :)

Для чистоты эксперимента нагрузка (тесты) с машины не снимается:
 zpool status
  pool: data
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
    continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Wed Jan 21 15:04:27 2015
    7.78G scanned out of 2.36T at 9.38M/s, 73h4m to go
    2.60G resilvered, 0.32% done
config:

    NAME             STATE     READ WRITE CKSUM
    data             DEGRADED     0     0     0
      mirror-0       ONLINE       0     0     0
        sdb          ONLINE       0     0     0
        sdc          ONLINE       0     0     0
      mirror-1       DEGRADED     0     0     0
        replacing-0  FAULTED      0     0     0
          sdd        FAULTED      3 23.0K     0  too many errors
          sdh        ONLINE       0     0     0  (resilvering)
        sde          ONLINE       0     0     0
      mirror-2       ONLINE       0     0     0
        sdf          ONLINE       0     0     0
        sdg          ONLINE       0     0     0

errors: No known data errors

Tuesday, 20 January 2015

Создание Linux Kdump поверх bonding

Настраиваем kdump как обычно, но добавялем в него опцию в файле /etc/kdump.conf:
options bonding mode=1 
Соответственно, режим бондинга меняете на свой!