PF аномально тормозит web-сервер

Настройка сетевых служб, маршрутизации, фаерволлов. Проблемы с сетевым оборудованием.
Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Dmitriy_K
сержант
Сообщения: 200
Зарегистрирован: 2009-04-07 6:22:33
Откуда: г.Королёв

PF аномально тормозит web-сервер

Непрочитанное сообщение Dmitriy_K » 2012-12-11 14:39:02

Сейчас занимаюсь тестированием и настройкой производительности web-сервера.
При этом обнаружилось, что PF имеет странную особенность после некоторого количества запросов тормозить поток запросов без превышения лимитов и сильно задерживать ответы (см. ниже "longest request"). Последняя часть длинной серии запросов (5-20%) имеет аномально долгое завершение.

Код: Выделить всё

Server Software:        nginx
Server Hostname:        127.0.0.1
Server Port:            80

Document Path:          /
Document Length:        1152 bytes

Concurrency Level:      500
Time taken for tests:   245.439 seconds
Complete requests:      1000000
Failed requests:        1
   (Connect: 0, Receive: 0, Length: 1, Exceptions: 0)
Write errors:           0
Total transferred:      1390998609 bytes
HTML transferred:       1151998848 bytes
Requests per second:    4074.33 [#/sec] (mean)
Time per request:       122.719 [ms] (mean)
Time per request:       0.245 [ms] (mean, across all concurrent requests)
Transfer rate:          5534.56 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   54 381.1      6    9409
Processing:     0   68 364.5     19   26733
Waiting:        0   67 363.7     19   26733
Total:         10  122 533.0     25   26739

Percentage of the requests served within a certain time (ms)
  50%     25
  66%     26
  75%     27
  80%     27
  90%     30
  95%    255
  98%   3025
  99%   3027
 100%  26739 (longest request)

Код: Выделить всё

Server Software:        nginx
Server Hostname:        10.8.1.7
Server Port:            80

Document Path:          /
Document Length:        1152 bytes

Concurrency Level:      250
Time taken for tests:   34.783 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      13570000 bytes
HTML transferred:       11520000 bytes
Requests per second:    287.49 [#/sec] (mean)
Time per request:       869.587 [ms] (mean)
Time per request:       3.478 [ms] (mean, across all concurrent requests)
Transfer rate:          380.98 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1  481 2237.7      1   22007
Processing:     1   12   5.1     10      30
Waiting:        1   11   5.4     10      30
Total:          2  493 2236.5     15   22013

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     16
  75%     18
  80%     20
  90%     26
  95%   3011
  98%   6211
  99%   6219
 100%  22013 (longest request)
Причём эффект проявляет себя даже при тестировании localhost. Но если серия запросов короткая (около 5000), этого эффекта торможения нет. :cz2:
Конфиг PF сейчас используется совсем простой, тестовый:

Код: Выделить всё

set skip on lo0
#scrub in all

pass in proto tcp from any to self port 65000
pass in quick proto tcp from 10.0.0.0/8 to self port 80

# Allow all outgoing connections
# pass out quick all
pass out quick from self to any

# Block all
# block drop in all
Закомментированные строки на эффект не влияют. Пробовал для дополнительной диагностики загрузиться с обнулённым sysctl.conf и loader.conf - не помогло. Тестировал на нескольких серверах с разными версиями FreeBSD - эффект одинаков. Набор правил PF на серверах был разный, только несколько базовых правил везде есть, как в тестовом конфиге.
Обойтись без файрволла на сервере невозможно, поскольку он много всего разруливает.

Большая просьба к знающим подсказать природу этого эффекта и как это преодолеть. :(

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Dmitriy_K
сержант
Сообщения: 200
Зарегистрирован: 2009-04-07 6:22:33
Откуда: г.Королёв

Re: PF аномально тормозит web-сервер

Непрочитанное сообщение Dmitriy_K » 2012-12-11 20:34:01

Разобрался :oops:
Файрволлу не хватало стэйтсов.
Увеличил все лимиты в сотню раз:

Код: Выделить всё

set limit { states 1000000, frags 500000, src-nodes 1000000 }
И всё взлетело: :smile:

Код: Выделить всё

Server Software:        nginx
Server Hostname:        10.8.1.7
Server Port:            80

Document Path:          /
Document Length:        1152 bytes

Concurrency Level:      250
Time taken for tests:   5.003 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      135700000 bytes
HTML transferred:       115200000 bytes
Requests per second:    19989.55 [#/sec] (mean)
Time per request:       12.507 [ms] (mean)
Time per request:       0.050 [ms] (mean, across all concurrent requests)
Transfer rate:          26490.06 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    6 117.9      1    3000
Processing:     1    7   6.1      5     136
Waiting:        1    7   6.1      4     135
Total:          2   12 118.1      6    3013

Percentage of the requests served within a certain time (ms)
  50%      6
  66%      8
  75%     10
  80%     12
  90%     14
  95%     16
  98%     17
  99%     20
 100%   3013 (longest request)
Но на рабочем конфиге файрволла, к сожалению, всёравно получается очень замедленно:

Код: Выделить всё

Server Software:        nginx
Server Hostname:        10.8.1.7
Server Port:            800

Document Path:          /
Document Length:        1152 bytes

Concurrency Level:      500
Time taken for tests:   33.591 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      139100000 bytes
HTML transferred:       115200000 bytes
Requests per second:    2977.02 [#/sec] (mean)
Time per request:       167.953 [ms] (mean)
Time per request:       0.336 [ms] (mean, across all concurrent requests)
Transfer rate:          4043.98 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.2      0      19
Processing:    13  167 302.3    116    6902
Waiting:       13  167 302.3    116    6902
Total:         17  167 302.4    117    6906

Percentage of the requests served within a certain time (ms)
  50%    117
  66%    236
  75%    243
  80%    247
  90%    271
  95%    283
  98%    288
  99%    322
 100%   6906 (longest request)
Так что буду благодарен за какие-либо рекомендации.
Рабочий конфиг PF примерно такой:

Код: Выделить всё

 eface="bce0"

 main_addr="10.8.1.2"
 main_jail_1="10.8.1.3"
 main_jail_2="10.8.1.37"

 mirr_main="95.28.6.6"
 mirr_jail_1="95.28.6.7"
 mirr_jail_2="95.28.6.1"

 mirr_int="192.168.2.11"
 sys="10.8.1.15"
 admins="XXXXXXXX"
 programmers="YYYYYYYYYY"

 table <ssh_users>  { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 95.28.6.6/31, $admins } persist
 table <ftp_users>  { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, $programmers } persist
 table <mysql>      { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 } persist
 table <white>      { $admins } persist
 table <internal>   { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 13.119.27.0/24, 15.147.04.0/24 } persist
 table <ddos>         persist
 table <icmp_ddos>    persist
 table <blacklist> file "/var/tmp/blacklist"

 options="(max-src-conn 500, max-src-conn-rate 500/20, overload <ddos>)"
 icmp_options="(max-src-conn 1, max-src-conn-rate 10/20, overload <icmp_ddos>)"

 set limit { states 10000000, frags 500000, src-nodes 1000000 }

 set skip on lo0
 scrub in all

# Redirect SSL traffic
 rdr on $eface proto tcp from any to 10.8.1.4 port 443 -> 10.8.1.3 port 4430
 rdr on $eface proto tcp from any to 10.8.1.4 port 80  -> 10.8.1.3 port 80
 rdr on $eface proto tcp from any to 10.8.1.32 port 443 -> 10.8.1.3 port 4440
 rdr on $eface proto tcp from any to 10.8.1.32 port 80  -> 10.8.1.3 port 80

# Allow "white list"
 pass  in  quick on $eface proto tcp from <white> to self keep state

# Temp proxy
 pass  in  quick on $eface proto tcp from <internal>    to $main_addr port 8080 keep state

# Allow http/https access from internal networks to jails
 pass  in  quick on $eface proto tcp from <internal>    to $main_jail_1 port { 80 443 4430 4433 4440 4443 4450 4453 } keep state
 pass  in  quick on $eface proto tcp from <internal>    to $main_jail_2 port { 80 443 843 337 997 998 } keep state

# Block DDoS'ers
 block drop in  quick from <ddos> to any
 block drop out quick from self to <ddos>
 block drop in  quick from <icmp_ddos> to any
 block drop out quick from self to <icmp_ddos>
 block drop in  quick from <blacklist> to any
 block drop out quick from self to <blacklist>


# Allow http/https access from any to jails
 pass  in  quick on $eface proto tcp from any           to $main_jail_1 port { 80 443 4430 4433 4440 4443 4450 4453 } keep state $options
 pass  in  quick on $eface proto tcp from any           to $main_jail_2 port { 80 443 843 337 997 998 } keep state $options

# Allow ssh connections
 pass  in  quick on $eface proto tcp from <ssh_users>   to { $main_addr, $main_jail_1, $main_jail_2 } port 22 keep state $options

# Allow mysql connections
 pass  in  quick on $eface proto tcp from <mysql>       to { $main_jail_1, $main_jail_2 } port 3306 keep state

# Allow mysql replication
 pass  in  quick on $eface proto tcp from $mirr_jail_1  to $main_jail_1 port 33306 keep state

# Allow zabbix-connections from sys
 pass  in  quick on $eface proto tcp from $sys      to { $main_addr, $main_jail_1, $main_jail_2 } port 10050 keep state

# Allow smtp
 pass  in  quick on $eface proto tcp from any to { $main_jail_1, $main_jail_2 } port 25 keep state $options

# Allow ftp connections
 anchor "ftpsesame/*" in on $eface
 pass  in  quick on $eface proto tcp from <ftp_users> to $main_jail_1 port 21 keep state

# Allow dns
 pass  in  quick on $eface proto udp from any to $main_addr port 53 keep state $options

# Allow zones transfers
 pass  in  quick on $eface proto tcp from $mirr_main to $main_addr port 53 keep state
 pass  in  quick on $eface proto tcp from $mirr_int  to $main_addr port 53 keep state

# Allow ping
# pass  in  quick on $eface inet proto icmp all icmp-type echoreq keep state $options
 pass  in  quick on $eface inet proto icmp all icmp-type echoreq keep state $icmp_options

# Allow all outgoing connections
 pass  out quick all keep state

# Block all
 block drop in all
(Не ищите реальных IP :smile: )

Dmitriy_K
сержант
Сообщения: 200
Зарегистрирован: 2009-04-07 6:22:33
Откуда: г.Королёв

Re: PF аномально тормозит web-сервер

Непрочитанное сообщение Dmitriy_K » 2012-12-12 12:24:02

Насчёт степени торможения на полном наборе правил PF ошибся. Позднее потестил, получилось 10-15%, это приемлемо.
Возник ещё интересный вопрос каким образом во FreeBSD лимитируется максимальное количество FIN_WAIT_2 на уровне 55500?
Пробовал крутить, вроде, всё что можно. Не нашёл.
Местами эта хрень сильно достаёт. :(