Jump to content
Калькуляторы

Защита против DoS в FreeBSD на NAT

Всем привет.

Решил проверить на атакоустойчивость маршрутизатор на FreeBSD

Железо: Corei7-4820k, Сетевуха на intel 82576 ОС:FreeBSD10 amd64

 

 

Правила PF баз NAT

set optimization aggressive
set limit states 1000000
set limit frags 1000000
set limit src-nodes 200000
set limit table-entries 1000000
#set limit tables 1000000
set block-policy drop
scrub in all
pass all
block in quick from any os NMAP
block quick proto tcp from any to any port $rubbish_tcp
block quick proto udp from any to any port $rubbish_udp
block quick proto tcp from any port $rubbish_tcp to any
block quick proto udp from any port $rubbish_udp to any
pass quick on $ext_if proto gre all no state
pass in on $ext_if from any to any
pass out on $ext_if from <internet> to any
#######################################
pass in on $int_if from <net> to any
pass out on $int_if from any to <net>

 

Сначала проверял без NATа

hping3 -V -c 10000000 -d 1400 -S -w 64 -p 445 -s 445 --flood <VICTIM_IP>

 

# netstat -i -h -w 1 igb0
           input        (Total)           output
  packets  errs idrops      bytes    packets  errs      bytes colls
        5     0     0        314          2     0        292     0
        4     0     0        254          2     0        244     0
        6     0     0        374          2     0        244     0
     2.5K     0     0       3.5M       2.5K     0       3.5M     0
     8.3K     0     0        12M       8.3K     0        12M     0
     8.3K     0     0        12M       8.3K     0        12M     0
     8.3K     0     0        12M       8.3K     0        12M     0
     8.3K     0     0        12M       8.3K     0        12M     0
     8.3K     0     0        12M       8.3K     0        12M     0

last pid:  1683;  load averages:  0.15,  0.17,  0.46                                         up 0+01:02:14  23:46:04
122 processes: 5 running, 75 sleeping, 42 waiting
CPU 0:  0.0% user,  0.0% nice,  0.0% system,  2.4% interrupt, 97.6% idle
CPU 1:  0.0% user,  0.0% nice,  0.0% system,  0.8% interrupt, 99.2% idle
CPU 2:  0.0% user,  0.0% nice,  0.0% system,  2.7% interrupt, 97.3% idle
CPU 3:  0.0% user,  0.0% nice,  0.0% system,  3.9% interrupt, 96.1% idle
Mem: 11M Active, 19M Inact, 720M Wired, 15M Buf, 7117M Free
Swap: 3615M Total, 3615M Free

 PID USERNAME   PRI NICE   SIZE    RES STATE   C   TIME    WCPU COMMAND
  11 root       155 ki31     0K    64K CPU0    0  57:01 100.00% idle{idle: cpu0}
  11 root       155 ki31     0K    64K RUN     1  57:00  97.85% idle{idle: cpu1}
  11 root       155 ki31     0K    64K CPU2    2  56:55  97.75% idle{idle: cpu2}
  11 root       155 ki31     0K    64K CPU3    3  57:01  97.46% idle{idle: cpu3}
  12 root       -92    -     0K   672K WAIT    3   0:57   2.29% intr{irq272: igb1:que}
  12 root       -92    -     0K   672K WAIT    2   0:57   2.29% intr{irq271: igb1:que}
  12 root       -92    -     0K   672K WAIT    0   1:02   2.20% intr{irq269: igb1:que}
  12 root       -92    -     0K   672K WAIT    1   0:55   2.10% intr{irq270: igb1:que}

 

pfctl -si
No ALTQ support in kernel
ALTQ related functions disabled
Status: Enabled for 0 days 00:11:12           Debug: Urgent

State Table                          Total             Rate
 current entries                   131140
 searches                         2380522         3542.4/s
 inserts                           712422         1060.2/s
 removals                          582555          866.9/s
Counters
 match                             900877         1340.6/s
 bad-offset                             0            0.0/s
 fragment                               0            0.0/s
 short                                  0            0.0/s
 normalize                              0            0.0/s
 memory                                 0            0.0/s
 bad-timestamp                          0            0.0/s
 congestion                             0            0.0/s
 ip-option                              0            0.0/s
 proto-cksum                            0            0.0/s
 state-mismatch                   1476619         2197.3/s
 state-insert                           0            0.0/s
 state-limit                            0            0.0/s
 src-limit                              0            0.0/s
 synproxy                               0            0.0/s

 

Далее добавляю NAT и запускаю тот же самый тест

nat on $ext_if from { 10.3.0.76 10.3.0.79 } to any -> 172.27.0.10

 

Смотрим загрузку

Система периодически уходит в даун

last pid:  1722;  load averages:  5.74,  1.81,  0.89                                                                                     up 0+01:12:36  23:56:26
121 processes: 17 running, 72 sleeping, 32 waiting
CPU 0:  0.0% user,  0.0% nice, 83.6% system,  6.6% interrupt,  9.8% idle
CPU 1:  0.0% user,  0.0% nice, 82.8% system,  7.0% interrupt, 10.2% idle
CPU 2:  0.0% user,  0.0% nice, 92.2% system,  6.3% interrupt,  1.6% idle
CPU 3:  0.0% user,  0.0% nice, 92.2% system,  6.3% interrupt,  1.6% idle
Mem: 13M Active, 20M Inact, 721M Wired, 16M Buf, 7114M Free
Swap: 3615M Total, 3615M Free

 PID USERNAME   PRI NICE   SIZE    RES STATE   C   TIME    WCPU COMMAND
  11 root       155 ki31     0K    64K RUN     2  66:49  54.05% idle{idle: cpu2}
   0 root       -92    0     0K   432K -       0   4:29  49.76% kernel{igb1 que}
   0 root       -92    0     0K   432K CPU3    3   4:42  49.56% kernel{igb1 que}
  11 root       155 ki31     0K    64K CPU0    0  66:51  48.39% idle{idle: cpu0}
  11 root       155 ki31     0K    64K RUN     3  66:51  43.26% idle{idle: cpu3}
   0 root       -92    0     0K   432K -       1   4:36  43.16% kernel{igb1 que}
   0 root       -92    0     0K   432K CPU2    2   4:35  31.69% kernel{igb1 que}
  11 root       155 ki31     0K    64K RUN     1  66:46  26.56% idle{idle: cpu1}
  12 root       -92    -     0K   672K RUN     2   1:04  11.57% intr{irq271: igb1:que}
  12 root       -92    -     0K   672K WAIT    0   1:08   9.86% intr{irq269: igb1:que}
  12 root       -92    -     0K   672K RUN     3   1:03   8.06% intr{irq272: igb1:que}
  12 root       -92    -     0K   672K WAIT    1   0:59   1.27% intr{irq270: igb1:que}
   0 root       -16    0     0K   432K swapin  1   0:25   0.00% kernel{swapper}
   2 root       -16    -     0K    16K pftm    1   0:07   0.00% pf purge
  12 root       -60    -     0K   672K WAIT    1   0:03   0.00% intr{swi4: clock}
  12 root       -72    -     0K   672K RUN     2   0:01   0.00% intr{swi1: netisr 2}
  12 root       -72    -     0K   672K WAIT    1   0:01   0.00% intr{swi1: netisr 1}
  12 root       -72    -     0K   672K WAIT    0   0:01   0.00% intr{swi1: netisr 0}
  12 root       -72    -     0K   672K RUN     3   0:01   0.00% intr{swi1: netisr 3}
  12 root       -92    -     0K   672K RUN     3   0:01   0.00% intr{irq267: igb0:que}
  12 root       -92    -     0K   672K RUN     2   0:01   0.00% intr{irq266: igb0:que}
  12 root       -92    -     0K   672K WAIT    1   0:01   0.00% intr{irq265: igb0:que}
  12 root       -92    -     0K   672K WAIT    0   0:01   0.00% intr{irq264: igb0:que}
  14 root       -16    -     0K    16K -       0   0:01   0.00% rand_harvestq
1386 root        20    0 23492K  3408K ttyin   1   0:00   0.00% csh
   3 root       -16    -     0K    16K ccb_sc  0   0:00   0.00% xpt_thrd

Появляются дропы

# netstat -i -h -w 1 igb1
           input        (Total)           output
  packets  errs idrops      bytes    packets  errs      bytes colls
     7.6K     0     0        11M          4     0        292     0
     7.8K     0     0        11M          2     0        244     0
     9.6K     0     0        14M          2     0        244     0
     7.4K     0     0        11M          2     0        244     0
     3.8K     0     0       5.4M          1     0        170     0
     3.9K     0     0       5.5M          1     0        170     0
     2.3K  1.9K     0       3.3M          2     0        244     0
     2.8K  2.2K     0       3.9M          2     0        244     0
     2.8K    64     0       4.0M          2     0        212     0
     5.7K     0     0       8.1M          1     0        170     0
     6.2K  1.1K     0       8.8M         10     0       429K     0
     9.0K   590     0        13M        343     0       1.7M     0
      11K     0     0        16M       1.8K     0       990K     0
     8.1K     0     0        11M          2     0        244     0
     8.3K     0     0        12M        176     0       247K     0
     8.3K     0     0        12M        133     0       186K     0
     8.3K     0     0        12M       3.4K     0       4.8M     0
      15K     0     0        21M       2.4K     0       3.4M     0
     4.4K     0     0       6.2M          1     0        170     0
     8.1K     0     0        12M          1     0       577K     0

Счетчики pfctl

# pfctl -si
No ALTQ support in kernel
ALTQ related functions disabled
Status: Enabled for 0 days 00:00:15           Debug: Urgent

State Table                          Total             Rate
 current entries                    69680
 searches                       111793660      7452910.7/s
 inserts                            26415         1761.0/s
 removals                           30688         2045.9/s
Counters
 match                              41943         2796.2/s
 bad-offset                             0            0.0/s
 fragment                               0            0.0/s
 short                                  0            0.0/s
 normalize                              0            0.0/s
 memory                                 0            0.0/s
 bad-timestamp                          0            0.0/s
 congestion                             0            0.0/s
 ip-option                              0            0.0/s
 proto-cksum                            0            0.0/s
 state-mismatch                     87615         5841.0/s
 state-insert                           1            0.1/s
 state-limit                            0            0.0/s
 src-limit                              0            0.0/s
 synproxy                               0            0.0/s

 

Кто-нибудь знает как защититься от такой атаки?

 

UPD: Тюнинг

sysctl

net.inet.ip.intr_queue_maxlen=10240
net.route.netisr_maxqlen=4096
net.inet.icmp.icmplim=50
net.inet.tcp.msl=7500
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
kern.ipc.somaxconn=8192
net.inet.icmp.drop_redirect=1
net.inet.ip.redirect=0
net.inet.ip.fastforwarding=1
kern.random.sys.harvest.ethernet=0
kern.random.sys.harvest.point_to_point=0
kern.random.sys.harvest.interrupt=0
net.inet.raw.maxdgram=16384
net.inet.raw.recvspace=16384

 

loader.conf

kern.ipc.nmbclusters=512000
hw.igb.rxd=4096
hw.igb.txd=4096
hw.igb.max_interrupt_rate=128000
net.isr.maxthreads=4
net.isr.bindthreads=1
net.isr.dispatch=deferred

Edited by mnemonic

Share this post


Link to post
Share on other sites

net.inet.tcp.msl=7500

net.inet.tcp.blackhole=2

net.inet.udp.blackhole=1

kern.ipc.somaxconn=8192

net.inet.icmp.drop_redirect=1

net.inet.ip.redirect=0

net.inet.raw.maxdgram=16384

net.inet.raw.recvspace=16384

К прохождению трафика сквозь вообще отношения не имеет. redirect - вроде имеют но на производительность не влияют так чтобы заметно в нормальной ситуации.

 

Фильтровать трафик лучше на входе, на выход выпускать всё. (бывают исключения - в основном касается трафика который генерирует сам хост либо запретить определённым сервисам выходить в определённый интерфейс (при маршрутизации)).

 

net.isr.dispatch=deferred - тюнится в сисцтл, на лету.

net.inet.ip.fastforwarding=1 - фактически отключает ISR для маршрутизируемого траффика.

 

net.inet.ip.intr_queue_maxlen=10240

net.route.netisr_maxqlen=4096

поставьте уже 16к и не мучайтесь.

vmstat -z

и netstat с ещё другими ключиками, типа netstat -Q и пр по ману помогут понять где дропы.

 

# intel IGB tuning

hw.igb.rxd="4096" # Number of receive descriptors allocated by the driver.

hw.igb.txd="4096" # Number of transmit descriptors allocated by the driver.

hw.igb.rx_process_limit="4096" #

hw.igb.tx_process_limit="4096" #

hw.igb.max_interrupt_rate="32000" #

hw.igb.enable_msix="1" #

hw.igb.lro="0" #

hw.igb.fc_setting="0" #

 

 

# NETWORKING OPTIONS

net.link.ifqmaxlen=16384 # max send queue size

 

net.inet.tcp.hostcache.hashsize="16384" # Incresed hostcache

net.inet.tcp.hostcache.bucketlimit="100" # Incresed hostcache

net.inet.tcp.syncache.hashsize="1024" # syncache Hash table tuning

net.inet.tcp.syncache.bucketlimit="100" # syncache Hash table tuning

net.inet.tcp.tcbhashsize="16384" # Set the value of TCBHASHSIZE

net.inet6.ip6.auto_linklocal=0 # do not generate a link-local automatically: nd6 options=<AUTO_LINKLOCAL>

 

# NetISR

net.isr.maxthreads="1024" # Use at most this many CPUs for netisr processing

net.isr.bindthreads="1" # Bind netisr threads to CPUs.

net.isr.defaultqlimit="16384" # Default netisr per-protocol, per-CPU queue limit if not set by protocol

net.isr.maxqlimit="16384" # Maximum netisr per-protocol, per-CPU queue depth.

Share this post


Link to post
Share on other sites

Спасибо Ivan_83 за тюнинг. Выставил почти все параметры.

 

Насколько я понимаю, если бы не хватало размера очереди то копились бы ошибки

sysctl net.inet.ip.intr_queue_drops

net.inet.ip.intr_queue_drops: 0

Но их нет.

 

hw.igb.enable_msix="1"

Включена по умолчанию

 

LRO, TSO, TXCSUM отключены в ifconfig

-txcsum -lro -tso

 

hw.igb.tx_process_limit # Нет такого параметра

 

Пробовал выставлять разные вариации

net.isr.dispatch

net.inet.ip.fastforwarding

 

но результат нулевой.

 

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

Причем во время затыка сильно грузиться system

vmstat -z и netstat -Q показывают что ошибки не накапливаются

 

systat -vmstat 1 показывает в момент сильной загрузки вот такую картину. При этом загрузка постоянно меняется, от полного отсутсвия до 100%

    2 users    Load  7.39  6.16  4.69                  Sep 21 16:33

Mem:KB    REAL            VIRTUAL                       VN PAGER   SWAP PAGER
       Tot   Share      Tot    Share    Free           in   out     in   out
Act   23464    6448   536312     7748 7513988  count
All  120960    7328   556796    16580          pages
Proc:                                                            Interrupts
 r   p   d   s   w   Csw  Trp  Sys  Int  Sof  Flt        ioflt  9035 total
            19      9841    6  142 4874   54             cow         atkbd0 1
                                                         zfod        ehci0 16
0.0%Sys  76.5%Intr  0.0%User  0.0%Nice 23.5%Idle         ozfod       ehci1 23
|    |    |    |    |    |    |    |    |    |           %ozfod   785 cpu0:timer
++++++++++++++++++++++++++++++++++++++                    daefr    16 igb0:que 0
                                       10 dtbuf          prcfr     1 igb0:que 1
Namei     Name-cache   Dir-cache    213105 desvn          totfr     1 igb0:que 2
  Calls    hits   %    hits   %       533 numvn          react     1 igb0:que 3
      3       3 100                    32 frevn          pdwak       igb0:link
                                                       5 pdpgs  4843 igb1:que 0
Disks  ada0   cd0 pass0 pass1 pass2                       intrn     1 igb1:que 1
KB/t   0.00  0.00  0.00  0.00  0.00                514732 wire      1 igb1:que 2
tps       0     0     0     0     0                 14152 act       1 igb1:que 3
MB/s   0.00  0.00  0.00  0.00  0.00                 13460 inact       igb1:link
%busy     0     0     0     0     0                       cache     1 igb2:que 0

 

В целом после тюнинга ситуация улучшилась, но не намного.

 

UPD:Кстати во время атаки отваливается USB клавиатура. Пришлось поставить PS/2

Edited by mnemonic

Share this post


Link to post
Share on other sites

С данной атакой удалось справиться правилом в PF

pass in on igb1 inet proto tcp from <net> to any flags S/SA keep state (source-track rule, max-src-states 2000, max-src-conn 2000, max-src-conn-rate 500/5

Share this post


Link to post
Share on other sites

scrub in all

Не нужно вам это.

 

pass out on $ext_if from to any

разрешить весь исходящий траф первым же правилом и добавить quick.

 

Можно как то так нарисовать:

 

set optimization aggressive

set limit states 1000000

set block-policy drop

pass quick on $ext_if proto gre all no state

pass quick proto { icmp, icmp6 } from any to any no state allow-opts

pass out quick keep state

 

block quick proto tcp from any to any port $rubbish_tcp

block quick proto udp from any to any port $rubbish_udp

block quick proto tcp from any port $rubbish_tcp to any

block quick proto udp from any port $rubbish_udp to any

pass in quick from any to any

 

если захочется лучше - man pf

и тулза pftop может натолкнуть на мысли.

 

Share this post


Link to post
Share on other sites

Если лаги были через строго равные промежутки времени то возможно это:

set timeout

 

interval Interval between purging expired states and fragments.

src.track Length of time to retain a source tracking entry after

the last state expires.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.