Архив рубрики: UNIX

Тюнинг MySQL в ISPmanager 4. Не сохраняются изменения.

Довелось мне недавно столкнуться с панелью ISPManager 4, установленной на CentOS 6.5. Это был довольно слабый сервер на десктопном железе, но при этом количество сайтов на нем переваливало за сотню. Всего лишь 2 SATA-винчестера по 500 Гб в зеркале и 32 Гб SSD для баз mysql. Оперативной памяти было всего-то 8 Гб, но этого должно быть достаточно для работы сервера при грамотной настройке. А вот с грамотной настройкой были проблемы и по этой причине Load Average скакал от 4 до 60. В общем-то, 4 — это нормальная цифра для 4-ядерного процессора, но 60…

Первое, за что я решил взяться — это тюнинг MySQL. Открыл рабочий конфиг и взялся за голову: это был дефолтный конфиг из типовых настроек для «маленького» сервера, т.е. my-small.cnf:

# Example MySQL config file for small systems.
#
# This is for a system with little memory (<= 64M) where MySQL is only used
# from time to time and it's important that the mysqld daemon
# doesn't use much resources.
#
# MySQL programs look for option files in a set of
# locations which depend on the deployment platform.
# You can copy this option file to one of those
# locations. For information about these locations, see:
# http://dev.mysql.com/doc/mysql/en/option-files.html
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.

# The following options will be passed to all MySQL clients
[client]
#password = your_password
port = 3306
socket = /var/lib/mysql/mysql.sock

# Here follows entries for some specific programs

# The MySQL server
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-locking
key_buffer_size = 16K
max_allowed_packet = 1M
table_open_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 128K

# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (using the "enable-named-pipe" option) will render mysqld useless!
#
#skip-networking
server-id = 1

# Uncomment the following if you want to log updates
#log-bin=mysql-bin

# binary logging format - mixed recommended
#binlog_format=mixed

# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = /var/lib/mysql
#innodb_data_file_path = ibdata1:10M:autoextend
#innodb_log_group_home_dir = /var/lib/mysql
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
#innodb_buffer_pool_size = 16M
#innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
#innodb_log_file_size = 5M
#innodb_log_buffer_size = 8M
#innodb_flush_log_at_trx_commit = 1
#innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M

[mysqlhotcopy]
interactive-timeout

Как видим из конфига, ничего хорошего с таким сервером при >100 сайтов просто не могло быть: все кэши минимальные, кэш запросов не указан, а значит выключен, thread_cache_size не установлен, а значит равен нулю и т.д. Помимо этого, лимит открытых файлов на сервере равнялся 1024. Первым делом поднят был именно он (до 80000), после этого были подкручены table_open_cache, query_cache_size, thread_cache_size и некоторое количество других буферов. Настало время перезапуска сервера для применения настроек. Перезапуск производился средствами панели и каково же было мое удивление, когда вместо своего конфига я опять увидел дефолтный!

Как водится, поиск в гугле на тему подмены конфига ничего не дал. Беглый осмотр вики производителя панели выдал только информацию по добавлению mysql-сервера в панель. Пришлось покопаться в самой панели и внезапно обнаружить, что при рестарте mysql-сервера, происходит копирование все того же my-small.cnf в my.cnf! Оставим вопросы о целесообразности такого решения разработчикам: есть у меня стойкое ощущение, что многие владельцы (язык не поворачивается называть этих людей администраторами) этих панелей не знают что такое ssh и для чего он вообще нужен, если все есть в панели.

Таким образом, одним из возможных решений этой проблемы, является внесение изменений в my-small.cnf (в центоси он лежит тут: /usr/share/mysql), который и будет скопирован в /etc/my.cnf.

А как же советы по настройке? Настройка параметров — дело индивидуальное и сильно зависит от самого сервера, количества сайтов, количества Innodb и myisam таблиц и т.д.

Очень медленно грузится web-интерфейс Zabbix

Утро началось как обычно: с проверки всех систем, отчетов и просмотра графиков заббикса. Вот только с последним возникла непонятная проблема. Он установлен на сервере, который является по совместительству веб-сервером для различных проектов. При попытке открыть страницу, браузер висел в ожидании каждого графика, да и страницы в целом секунд по 20-25. Просмотр вывода top не показал никакой нагрузки, ну т.е. совсем никакой — la около 0,3, загрузка процессора около 5%. Количество процессов вменяемое, никаких лимитов не превышено.

После сбора расширенных логов с nginx (именно он стоит в качестве фронтенда) с временем генерации страниц, становится понятно, что затык не в нем, а ниже, т.е. либо в апаче, либо в mysql. Лог медленных запросов mysql тоже не сказал ничего насчет таблиц заббикса. Сервер «боевой», поэтому включать дебаг и смотреть чем же занят все это время httpd и почему же загрузка процессора им равна 0 никак нельзя. Процессы httpd висят в состоянии kqread и не грузят процессор совсем.

Что удивительнее, другие сайты/приложения работали без задержек. Пришлось судорожно вспоминать все изменения, которые вносились в конфигурацию сервера в последнее время. Из всего, что было сделано, на ум приходила только настройка форвардинга в DNS-сервере bind. С целью уменьшения задержек и объема внешнего трафика, был настроен форвардинг запросов DNS на сервер провайдера. Казалось бы, причем тут DNS? Но после отключения форвардинга и перезапуска dns-сервера, заббикс загрузился быстро, как ни в чем не бывало. Подробный анализ всех логов выявил таймауты при обращении к DNS провайдера… Но как? Как это могло повлиять на загрузку веб-интерфейса заббикса?..

RacoonVPN + Cisco ASA 5510 = Site-to-site IPSEC vpn

В связи с открытием нового офиса пришлось задуматься о канале связи между сетями. На основном офисе в качестве шлюза используется Cisco ASA 5510. На дополнительном необходимо было использовать решение «побюджетнее», т.к. офис сам по себе временный. Остановились на debian 7 :) Задача была простая: обеспечить полноценную работу удаленного офиса — доступ как в основную сеть без дополнительных настроек для пользователей, так и в сеть DMZ. При пробросе двух сетей есть некоторые нюансы, о которых речь пойдет чуть ниже.

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

Материалов по устройству IPSEC VPN в сети предостаточно. Вкратце могу напомнить, что есть 2 фазы установки соединения: защищенное IKE соединение и, собственно, ipsec-туннель.

Имеем:

  • Адреса локальной сети — 192.168.0.0/21
  • Адреса DMZ — 192.168.15.0/24
  • Адреса удаленного офиса — 192.168.30.0

Версия ПО на cisco asa — 8.2

Итак, приступим к настройкам на стороне Cisco. Создадим object-group для локальных сетей — так удобнее их добавлять/удалять в случае необходимости:

object-group network OUR-SUBNETS
 network-object 192.168.15.0 255.255.255.0
 network-object 192.168.0.0 255.255.248.0

Создадим access-list для выделения необходимого нам трафика:

access-list ISP1_cryptomap extended permit ip object-group OUR-SUBNETS 192.168.30.0 255.255.255.0

Пропишем параметры isakmp и ipsec, создадим crypto-map, transfrom-set и tunnel-group, укажем pre-shared-key:

crypto isakmp policy 10
 authentication pre-share
 encryption aes-256
 hash sha
 group 5
 lifetime 86400
crypto isakmp identity address
crypto isakmp enable ISP1
crypto ipsec transform-set ESP-AES-256-SHA esp-aes-256 esp-sha-hmac
crypto ipsec security-association lifetime seconds 28800
crypto ipsec security-association lifetime kilobytes 4608000
tunnel-group aaa.bbb.ccc.xxx type ipsec-l2l
tunnel-group aaa.bbb.ccc.xxx ipsec-attributes
 pre-shared-key A_VeRy_SeCuRe_KeY 
crypto map ISP1 1 match address ISP1_cryptomap
crypto map ISP1_map 1 set peer aaa.bbb.ccc.xxx
crypto map ISP1_map 1 set transform-set ESP-AES-256-SHA
crypto map ISP1_map interface ISP1

Не забываем прописать правило для NAT 0:

access-list LANVPN extended permit ip 192.168.30.0 255.255.255.0 192.168.0.0 255.255.248.0
access-list LANVPN extended permit ip 192.168.0.0 255.255.248.0 192.168.30.0 255.255.255.0
access-list DMZVPN extended permit ip 192.168.30.0 255.255.255.0 192.168.15.0 255.255.255.0
access-list DMZVPN extended permit ip 192.168.15.0 255.255.255.0 192.168.30.0 255.255.255.0
nat (LOCAL) 0 access-list LANVPN
nat (DMZ) 0 access-list DMZVPN

При настройке соединения на linux будет лучше отключить firewall совсем — проще дебажить

Теперь переместимся на debian. Начнем с установки необходимого софта.

apt-get install racoon ipsec-tools

Отредактируем в соответствии с выбранными параметрами /etc/racoon/racoon.conf:

path pre_shared_key "/etc/racoon/psk.txt";


padding {
    maximum_length 20;  # maximum padding length.
    randomize off;      # enable randomize length.
    strict_check off;   # enable strict check.
    exclusive_tail off; # extract last one octet.
}

listen {
    isakmp bbb.ccc.ddd.xxx[500];
}

timer {
    # These value can be changed per remote node.
    counter 5;          # maximum trying count to send.
    interval 10 sec;    # maximum interval to resend.
    persend 1;          # the number of packets per a send.

    # timer for waiting to complete each phase.
    phase1 30 sec;
    phase2 15 sec;

}

log warning;


remote aaa.bbb.ccc.ddd {
    my_identifier address bbb.ccc.ddd.xxx;
    peers_identifier address aaa.bbb.ccc.ddd;
    exchange_mode main;
    initial_contact on;
    doi ipsec_doi;
    proposal_check claim; 
    lifetime time 24 hour;
    proposal {
        encryption_algorithm aes 256;
        hash_algorithm sha1;
        authentication_method pre_shared_key;
        dh_group 5;
    }
    generate_policy off;
    nat_traversal on;
    passive off;
    dpd_delay 30; 
}

sainfo subnet 192.168.30.0/24 any subnet 192.168.0.0/21 any {
    encryption_algorithm aes 256;
    authentication_algorithm hmac_sha1;
    compression_algorithm deflate;
    lifetime time 24 hour; 
}

sainfo subnet 192.168.30.0/24 any subnet 192.168.15.0/24 any {
    encryption_algorithm aes 256;
    authentication_algorithm hmac_sha1;
    compression_algorithm deflate;
    lifetime time 24 hour;
}

Впишем наш pre-shared key в файл /etc/racoon/psk.txt:

# IPv4/v6 addresses
aaa.bbb.ccc.ddd A_VeRy_SeCuRe_KeY

Отредактируем /etc/ipsec-tools.conf:

#!/usr/sbin/setkey -f

# NOTE: Do not use this file if you use racoon with racoon-tool
# utility. racoon-tool will setup SAs and SPDs automatically using
# /etc/racoon/racoon-tool.conf configuration.
#

## Flush the SAD and SPD
#
 flush;
 spdflush;

 spdadd 192.168.30.0/24[any] 192.168.0.0/21[any] any -P out ipsec esp/tunnel/bbb.ccc.ddd.xxx-aaa.bbb.ccc.ddd/require;
 spdadd 192.168.0.0/21[any] 192.168.30.0/24[any] any -P in ipsec esp/tunnel/aaa.bbb.ccc.ddd-bbb.ccc.ddd.xxx/require;

 spdadd 192.168.30.0/24[any] 192.168.15.0/24[any] any -P out ipsec esp/tunnel/bbb.ccc.ddd.xxx-aaa.bbb.ccc.ddd/unique;
 spdadd 192.168.15.0/24[any] 192.168.30.0/24[any] any -P in ipsec esp/tunnel/aaa.bbb.ccc.ddd-bbb.ccc.ddd.xxx/unique; 

Есть один очень важный нюанс: при создании туннеля для 2 и более подсетей, только у одной подсети может быть указан параметр require в ipsec-tools.conf. У остальных он должен быть unique. Иначе будет поднят туннель только для одной подсети. Много времени ушло на то, чтобы выяснить эту маленькую особенность…

Перезапускаем racoon и setkey:

/etc/init.d/setkey restart
/etc/init.d/racoon restart

Прописываем маршруты:

route add -host aaa.bbb.ccc.ddd dev eth1
ip route add 192.168.0.0/21 via aaa.bbb.ccc.ddd
ip route add 192.168.15.0/24 via aaa.bbb.ccc.ddd
route del aaa.bbb.ccc.ddd dev eth1

И, если никаких ошибок и очепяток допущено не было, идем отдыхать. Если же туннель не поднимается — начинаем построчно сравнивать конфиги на линуксе и cisco. Полезно также будет включить debug в конфиге racoon (log debug; вместо log warning;) и проверить логи.

Проверить статус туннеля на cisco можно командой sh ipsec sa. Мы должны увидеть что-то вроде:

interface: ISP1
    Crypto map tag: ISP1_map, seq num: 1, local addr: aaa.bbb.ccc.ddd

      access-list ISP1_cryptomap extended permit ip 192.168.0.0 255.255.248.0 192.168.30.0 255.255.255.0
      local ident (addr/mask/prot/port): (192.168.0.0/255.255.248.0/0/0)
      remote ident (addr/mask/prot/port): (192.168.30.0/255.255.255.0/0/0)
      current_peer: bbb.ccc.ddd.xxx

      #pkts encaps: 162550535, #pkts encrypt: 162550493, #pkts digest: 162550493
      #pkts decaps: 84864900, #pkts decrypt: 84864899, #pkts verify: 84864899
      #pkts compressed: 0, #pkts decompressed: 0
      #pkts not compressed: 162550536, #pkts comp failed: 0, #pkts decomp failed: 0
      #pre-frag successes: 5, #pre-frag failures: 47, #fragments created: 10
      #PMTUs sent: 47, #PMTUs rcvd: 1, #decapsulated frgs needing reassembly: 0
      #send errors: 0, #recv errors: 0

      local crypto endpt.: aaa.bbb.ccc.ddd, remote crypto endpt.: bbb.ccc.ddd.xxx

      path mtu 1492, ipsec overhead 74, media mtu 1500
      current outbound spi: 0351F3AB
      current inbound spi : 462D7034

    inbound esp sas:
      spi: 0x462D7034 (1177382964)
         transform: esp-aes-256 esp-sha-hmac no compression
         in use settings ={L2L, Tunnel, }
         slot: 0, conn_id: 4915200, crypto-map: ISP1_map
         sa timing: remaining key lifetime (sec): 13076
         IV size: 16 bytes
         replay detection support: Y
         Anti replay bitmap:
          0xFFFFFFFF 0xFFFFFFFF
    outbound esp sas:
      spi: 0x0351F3AB (55702443)
         transform: esp-aes-256 esp-sha-hmac no compression
         in use settings ={L2L, Tunnel, }
         slot: 0, conn_id: 4915200, crypto-map: ISP1_map
         sa timing: remaining key lifetime (sec): 13076
         IV size: 16 bytes
         replay detection support: Y
         Anti replay bitmap:
          0x00000000 0x00000001

Работа WordPress на nginx + apache (постоянный 301 редирект)

В последнее время связка nginx + apache стала очень популярной среди администраторов веб-серверов. Эта связка довольно эффективна: nginx обеспечивает высокую скорость отдачи статического контента, кэширование, балансировку нагрузки, а apache, в свою очередь, давно признан стандартом де-факто среди веб-серверов за свою многофункциональность.

Ожидаемым было и появление хостинг-провайдеров, работающих с данной связкой. Чаще всего настройка nginx в данной связке ограничивается примерно такой конструкцией:

location / {
     index index.php index.html index.htm;
     try_files $uri $uri/ @proxy;
}
location ~ \.php$ {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1;
}
location @proxy {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1;
}

В таком случае установка WordPress вызовет бесконечную переадресацию с кодом 301. Дело в том, что nginx при получении запроса GET / будет подставлять индексный файл index.php и отправлять этот запрос на прокси, в качестве которого выступает apache. Apache, в свою очередь, запустит этот файл и за обработку запроса и формирование страницы примется WordPress. Для пущей красоты WordPress удалит из адресной строки index.php, который туда «дописал» nginx и вернет новый «красивый» урл с редиректом 301 клиенту. Клиент перейдет по нему, nginx допишет index.php и мы будем иметь то, что имели в самом начале.

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

Во избежание такой ситуации можно применить простой фикс: добавить в nginx еще один location, который будет отправлять запросы без указания конкретного файла сразу на apache без дописывания индексного файла. Таким образом, надо добавить примерно такую конструкцию:

location ~[^?]*/$ {
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header Host $host;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://127.0.0.1;
}

В таком случае запрос вида GET / будет передан на apache без изменений, wordpress его корректно обработает и вернет главную страницу сайта. При этом, естественно, индексный файл index.php должен быть определен и в конфигурации apache.