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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this