User Tools

Site Tools


Sidebar


Tags Cloud
start

Last updates

Установка из исходников php 5.2 на Debian Wheezy 7

На многих веб-серверах установлены php-скрипты, скомпилированные под старую версию Zend.
Из-за этого пришлось собирать php 5.2 на wheezy, что оказалось несколько нетривиальной процедурой.

  • Включаем deb-src в /etc/apt/sources.list
  • Выполняем
# apt-get build-dep php5
  • Тянем и распаковываем архив с исходниками в /opt/src
# mkdir -p /opt/src
# cd /opt/src
# wget http://museum.php.net/php5/php-5.2.17.tar.bz2
# tar xf php-5.2.17.tar.bz2
  • Следует учесть что старый php ничего не знает о новой мультиархитектурной структуре репозитория, потому не может нормально определить пути к библиотекам.
  • Стыдно и некультурно плодить симлинки из /usr/lib/x86_64-linux-gnu в /usr/lib/.

По возможности, избегайте этого, задавая LIBRARY_PATH и libdir при конфигурации

  • В директории с исходными кодами php создаем файл MyConfig.sh, в который записываем следующие строки:
#!/bin/sh
CFLAGS="-O2" LIBRARY_PATH=/usr/lib/x86_64-linux-gnu ./configure  --prefix=/opt/php-5.2.17 \
  --with-libdir=lib/x86_64-linux-gnu \
  --enable-calendar \
  --enable-sysvsem \
  --enable-sysvshm \
  --enable-sysvmsg \
  --with-jpeg-dir \
  --with-mcrypt \
  --with-mysql \
  --with-mysqli \
  --enable-bcmath \
  --with-bz2 \
  --with-gd \
  --with-zlib-dir \
  --with-curl \
  --enable-sockets \
  --with-iconv \
  --enable-mbstring \
  --enable-mbregex \
  --enable-ctype \
  --enable-shmop \
  --enable-wddx \
  --with-freetype-dir \
  --with-xmlrpc \
  --enable-dbase \
  --with-mime-magic \
  --with-mhash \
  --with-gettext \
  --with-pear \
  --with-apxs2=/usr/bin/apxs2
  • Возможно, придется доставить некоторые -dev в процессе конфигурации.

Если пан мае багато вильного часу та натхнення, то можно попробовать забекпортить и собрать suhosin.

  • По желанию - после компиляции применить checkinstall для сборки deb-пакета.
  • Устанавливаем Zend Optimizer для php 5.2.
2013/06/12 23:01 · kyxap

Welcome to your new DokuWiki

Congratulations, your wiki is now up and running. Here are a few more tips to get you started.

Enjoy your work with DokuWiki,
– the developers

Create your first pages

Your wiki needs to have a start page. As long as it doesn't exist, this link will be red: Last updates.

Go on, follow that link and create the page. If you need help with using the syntax you can always refer to the syntax page.

You might also want to use a sidebar. To create it, just edit the Tags Cloud page. Everything in that page will be shown in a margin column on the side. Read our FAQ on sidebars to learn more.

Please be aware that not all templates support sidebars.

Customize your Wiki

Once you're comfortable with creating and editing pages you might want to have a look at the configuration settings (be sure to login as superuser first).

You may also want to see what plugins and templates are available at DokuWiki.org to extend the functionality and looks of your DokuWiki installation.

Join the Community

DokuWiki is an Open Source project that thrives through user contributions. A good way to stay informed on what's going on and to get useful tips in using DokuWiki is subscribing to the newsletter.

The DokuWiki User Forum is an excellent way to get in contact with other DokuWiki users and is just one of the many ways to get support.

Of course we'd be more than happy to have you getting involved with DokuWiki.

2013/06/12 22:07

Техническое задание на подготовку и оптимизацию сервера с аппаратным raid10 из N x 3Tb (до 16TB) CentOS 6.x

Максимальный размер fs, который поддерживает ext4 - 16TB, в связи с чем на 16TB+ массивах приходится использовать btrfs.

Операционная система:
Linux CentOS 6.x amd64 последней версии

Роль сервера:
хранилище

Описание хранимых данных:
10% файлы по 5-7 Mb, 90% файлы 0.5-5Gb

Рейд-контроллер:
Просьба сразу обновить firmware на raid-контроллере до последней версии, предварительно сохранив копию заводской прошивки.
Убедиться что не будет проблем с HDD firmware и данной моделью контроллера. При необходимости обновить прошивку и на дисках.
Если у рейд-контроллера есть возможность отправки почтовых извещений о проблемах - настроить ее.
Совместимость дисков: http://www.adaptec.com/en-us/_common/compatibility/

IPMI:
Если есть возможность - крайне желательно подключить ipmi-интерфейс в dedicated порт и выделить отдельный IP.
Если внешнее подключение невозможно и если позволяют стойки - соединить порт ipmi-интерфейса SOHO-свитчом с 2nd NIC любого из серверов.
Очень важно чтобы ipmi-интерфейс не работал в shared режиме через сетевые интерфейсы сервера. Иначе при аппаратных проблемах сервер будет полностью недоступен.
Так же следует обновить прошивку IPMI-интерфейса, т.к. у Supermicro очень часто бывают проблемы с удаленной работой через консоль IPMI.

Система:
лучше если это будет программный mdadm-рейд на 2 диска, подключенных к материнской плате, а не к контроллеру
т.к. надо оставить возможность загружаться в ОС вне зависимости от состояния контроллера

Swap:
не использовать вообще

Корневая файловая система:
единым разделом /dev/md0 подмонтировать в /
файловая система ext3 или ext4
никаких отдельных разделов создавать не следует
опции монтирования в /etc/fstab оставить по-умолчанию
флаги fs так же можно оставить по-умолчанию

Приложения:
огромная просьба ставить всё нужное из официального репозитория, не собирая ничего из исходников

RAID10:
  Расчет приблизительной производительности рейда
  http://www.wesworld.net/raidcalculator.html
  Расчет размера stride
  http://busybox.net/~aldot/mkfs_stride.html

Важно
1. обеспечить автоматический failover при сбоях дисков
2. обеспечить максимальную скорость перестройки массива
3. минимизировать потери дискового пространства

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

Создание RAID10 для 24 дисков:
  raid10 на 20 диска + 2 диска установить в hotspare
  stripe size установить в максимальное значение 4096K

Файловая система ext4:
На массиве будут храниться файлы с размером >4Mb, что позволяет выставить размер блока fs в максимальные 64k.
По этой же причине нет нужды в большом количестве инод, поэтому можно уменьшить их общее количество для освобождения зарезервированного места.
Это делается при запуске mkfs.ext4 изменением соотношения количества инод к количеству байт с 1 иноды к 16384 байтам на 1 иноду к 32768 байтам.

Так же при создании файловой системы ext4 необходимо задать правильный размер stride и stripe-width.

stride или размер шага - это количество блоков, которые должны быть прочитаны или записаны на диск перед переходом к следующему.
Выставление этого параметра позволяет равномерно распределять метаданные по массиву, не позволяя им скапливаться на одном диске.
Если этого не сделать, то в будущем возможно значительное уменьшение скорости работы с RAID-массивом.
  Stride size = Stripe Size / Block Size
  
stripe width или ширина полосы - параметр, позволяющий задать ширину страйпа в блоках fs.
Правильное выставление этого параметра выравнивает файловую систему относительно границ дисков,
позволяя избавиться от традиционного недостатка RAID-массивов с контролем четности - операций read-modify-write.
Формула расчета stripe width для raid10: 
  Stripe width = Stride size * ( Raid10 Disk Members / 2)

Команда для создания файловой системы на raid10 с размером stripe в 4096k:
  mkfs.ext4 /dev/raid10 –b 65536 -i 32768 –E stride=64,stripe-width=704

Освобождение зарезервированных под суперпользователя блоков, отключение автоматического запуска fsck:
  tune2fs -i 0 -m 0 -c 0

Точка монтирования raid10:
/home

Опции монтирования raid10:
  noatime,nodiratime,errors=remount-ro
  так же в /etc/fstab два последних поля - fs_freq и fs_passno - должны быть выставлены в 0.
  

Анализ логов nginx / apache с помощью скриптов wtop и logrep

Фантастически полезная вещь для анализа логов вебсервера.

Очень быстро позволяют отловить медленные выполняющиеся запросы, найти использованную уязвимость, определить файлы с самым большим количеством трафика, отфильтровать ддос-ботов, выбрать самые популярные файлы для перемещения на SSD-кеш, собирать гео-статистику в live режиме, а так же железным аргументом дерзко попячить гордое щячло любителей денвера.

Скрипты написаны на python, соответственно, работать должны везде.

Брать по адресу http://code.google.com/p/wtop/

Главная утилита - logrep.
wtop лично мне не пригодился.

Руководство к logrep: http://code.google.com/p/wtop/wiki/UsingLogrep
Примеры использования: http://code.google.com/p/wtop/wiki/LogrepCookbook

Самое замечательное в logrep - это возможность применять к выводимым значениям операторы.
Т.е. мы можем полностью сформировать вывод скрипта, состоящий из заданных нами параметров и с примененными к ним необходимыми операторами.

Полный список выходных параметров, которыми мы можем оперировать, указан в руководстве под строкой AVAILABLE FIELDS.

Ключ -o позволяет указать используемые в output значения, разделенные табуляцией. К каждому выводимому зачению можно применить оператор.

Список операторов

count(*)     
avg(FIELD)   mean average
min(FIELD)   lowest seen value
max(FIELD)   highest seen value
sum(FIELD)   summation of all values
var(FIELD)   population variance
dev(FIELD)   deviation (square root of variance)

Ключ -s позволяет нам сортировать список, используя параметры вида -s "LIMIT:FIELDS:DIRECTION",
где LIMIT - это общее количество выводимых строк, FIELDS - выводимые значения, а DIRECTION - направление сортировки: 'd' - descending (по умолчанию), 'a' - acending.

Формирование списка наиболее востребованных файлов для выноса на SSD-диск (для Nginx)

Т.к. изначально скрипт создавался для работы с CustomLog типа combined вебсервера Apache, нам необходимо добавить в формат лога nginx переменную $request_time.

Формат лога для nginx

log_format mp4 '$remote_addr - $remote_user [$time_local] '
              '"$request" $status $body_bytes_sent "$http_referer" '
              '"$http_user_agent" $request_time' ;

Сортировка по top10 URL:

# logrep -o 'url,count(*)' -s '10:2' /home/log/httpd/yziltz.com/access_log

/videos/ztod.com/546fg/168nzrr/1.mp4            324
/videos/wtfpass/104ghd/560wyqe/1.mp4            259
/videos/evilangel/1004hf/457elux/1.mp4          205
/videos/ztod.com/546fg/84rqek/1.mp4             203
/videos/wtfpass/104ghd/505dtve/1.mp4            192
/videos/realitykings/986fk/314qiga/1.mp4        173
/videos/wtfpass/104ghd/18ifvr/1.mp4             153
/videos/brazzers/758gf/350ihij/1.mp4            143
/videos/wtfpass/104ghd/533jdzo/1.mp4            125
/videos/bangbros/754hj/100geoo/1.mp4            122

где параметрами -o являются

url - URL файла
count(*) - количество всех уникальных вхождений URL,

а параметрами -s

10 - это количество выводимых файлов,
2 - сортировка по полю #2.

В нашем случае поле #2 - это count(*).
Тип сортировки не указан и по умолчанию это 'd' - descending.

Сортировка по top10 URL с отображением дополнительных параметров:

Добавим новые значения в список параметров:

# logrep -o 'url,count(*),avg(msec),sum(bytes)' -s '10:2' /home/log/httpd/yziltz.com/access_log

/videos/evilangel/1004hf/457elux/1.mp4          800     63330.12        1265011232
/videos/wtfpass/104ghd/18ifvr/1.mp4             446     55150.93        199966883
/videos/naughty_america/634fs/6kryk/1.mp4       413     66149.11        422437989
/videos/naughty_america/634fs/83nbna/1.mp4      361     41608.23        284347235
/videos/wtfpass/104ghd/606pfgb/1.mp4            352     35669.83        129798205
/videos/wtfpass/104ghd/216pcko/1.mp4            330     50201.86        563510318
/videos/ztod.com/546fg/168nzrr/1.mp4            325     48295.78        238183106
/videos/wtfpass/104ghd/560wyqe/1.mp4            311     121607.30       4415056002
/videos/wtfpass/104ghd/387jkmy/1.mp4            309     52073.58        677026365
/videos/wtfpass/104ghd/505dtve/1.mp4            240     233122.70       1272250219

Дополнительными параметрами будут avg(msec) - среднее время отдачи файла и sum(bytes) - общий трафик, пришедшийся на этот файл.

А теперь добавим фильтр -f, в котором выведем результаты только за последний час (3600 секунд).
Для этого мы применим unixtime как самый простой способ.

# CUR_DATE=`date +"%s"`; HOUR_OFFSET=`echo "$CUR_DATE - 3600" | bc`; logrep -f "ts<$HOUR_OFFSET" -o 'url,count(*),avg(msec),sum(bytes)' -s '10:2' /home/log/httpd/yziltz.com/access_log
/videos/ztod.com/546fg/168nzrr/1.mp4            325     48295.78        238183106
/videos/wtfpass/104ghd/560wyqe/1.mp4            267     117390.16       2869373722
/videos/evilangel/1004hf/457elux/1.mp4          225     152913.27       954288822
/videos/ztod.com/546fg/84rqek/1.mp4             203     55998.36        188930211
/videos/wtfpass/104ghd/505dtve/1.mp4            196     216440.77       1093232840
/videos/realitykings/986fk/314qiga/1.mp4        173     203926.49       973211068
/videos/wtfpass/104ghd/18ifvr/1.mp4             161     114550.71       145899888
/videos/wtfpass/104ghd/533jdzo/1.mp4            147     182660.09       1100896430
/videos/bangbros/754hj/100geoo/1.mp4            145     175528.83       609455138
/videos/brazzers/758gf/350ihij/1.mp4            143     213783.88       144107563
2013/06/01 08:20

Эпичный скрипт бекапа mysql

Саппорт webazilla.com поставили клиенту скрипт резервирования баз mysql.
Конструкция WHICH_WHICH='which' заслуживает второго киселя и дополнительных 15 минут прогулки,
ветвление глубиной в 8 уровней - осиновый кол в серде, а акты непроизвольной обфускации смогут быть купированы только отрубанием верхних конечностей.

#!/bin/sh
# MySQL backup creation/rotation scenario

# =============== Config Section ====================<
BDIR='/home/backup'
DATADIR='/home/mysql'
DBA_PASSWORD=''
# >========== End Of Config Section ==================

# non-user serviceable settings
DATE=`date "+%Y-%m-%d"`
DATE_TOUCH=`date "+%Y%m%d0001"`
BEXT='.sql'
GZEXT='.gz'
TAREXT='.tar'
FULLBACKPREFIX='mysql-data'
NICENUM=19
CHMODBDIR='700'
CHMODSTORE='400'
BACKMTIME_COMPRESSED=8
BACKMTIME_STORED=14
BACKMINIMUMDAYS=3
TARGET_BACKUP='backup'
TARGET_CHECK='check'

# paths
export PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/local/mysql/bin"
WHICH_WHICH='which'
WHICH_FIND=`$WHICH_WHICH find` || 'find'
WHICH_BASENAME=`$WHICH_WHICH basename` || 'basename'
WHICH_NICE=`$WHICH_WHICH nice` || 'nice'
WHICH_MYSQLDUMP=`$WHICH_WHICH mysqldump` || 'mysqldump'
WHICH_TAR=`$WHICH_WHICH tar` || 'tar'
WHICH_GZIP=`$WHICH_WHICH gzip` || 'gzip'
WHICH_CHMOD=`$WHICH_WHICH chmod` || 'chmod'
WHICH_TOUCH=`$WHICH_WHICH touch` || 'touch'
WHICH_MKDIR=`$WHICH_WHICH mkdir` || 'mkdir'
WHICH_ECHO=`$WHICH_WHICH echo` || 'echo'
WHICH_UNAME=`$WHICH_WHICH uname` || 'uname'

# initialization
OSMARKER=`$WHICH_UNAME -s`
TARGET="$1"
[ "$TARGET" = "" ] && TARGET=$TARGET_BACKUP
db_list=''
db_list_notrecent=''
db_cnt=0
db_cnt_notrecent=0

# collecting database list
if [ -d "$DATADIR" ]; then
    for f in `$WHICH_FIND "$DATADIR" -maxdepth 1 -type d`; do
        if [ "$f" != "$DATADIR" ]; then
            db_list=$db_list" "`$WHICH_BASENAME $f`
            db_cnt=$(($db_cnt+1))
        fi
    done
fi

# section: backup
if [ "$TARGET" = "$TARGET_BACKUP" ]; then
    # preparing backup directory
    [ ! -d $BDIR ] && ( $WHICH_MKDIR "$BDIR" && $WHICH_CHMOD $CHMODBDIR "$BDIR" )
    [ ! -d $BDIR ] && return 1
    # database backup loop
    for db_name in ${db_list}; do
        if [ $db_name!='' ]; then
            db_file_name="$BDIR/$db_name.$DATE$BEXT"
            gz_file_name="$db_file_name$GZEXT"
            $WHICH_NICE -n $NICENUM $WHICH_MYSQLDUMP -q -p$DBA_PASSWORD $db_name > "$db_file_name"
            if [ -s "$db_file_name" ]; then
                $WHICH_NICE -n $NICENUM $WHICH_GZIP -f -S "$GZEXT" "$db_file_name"
                if [ -s "$gz_file_name" ]; then
                    $WHICH_CHMOD $CHMODSTORE "$gz_file_name"
                    $WHICH_TOUCH -c -t $DATE_TOUCH "$gz_file_name"
                    # performing rotation
                    for listfile_name in `$WHICH_FIND "$BDIR" -type f -iname "$db_name.*$BEXT$GZEXT" -mtime +$BACKMTIME_COMPRESSED`; do
                        if [ -s "$listfile_name" ]; then
                            [ "$listfile_name" != "$gz_file_name" ] && rm "$listfile_name"
                        else
                            rm "$listfile_name"
                        fi
                    done
                else
                    [ -f "$gz_file_name" ] && rm "$gz_file_name"
                fi
            else
                [ -f "$db_file_name" ] && rm "$db_file_name"
            fi
        fi
    done
    # full backup (just to be sure)
    store_file_name="$BDIR/$FULLBACKPREFIX.$DATE$TAREXT"
    $WHICH_NICE -n $NICENUM $WHICH_TAR cf "$store_file_name" "$DATADIR"
    if [ -s "$store_file_name" ]; then
        $WHICH_CHMOD $CHMODSTORE "$store_file_name"
        $WHICH_TOUCH -c -t $DATE_TOUCH "$store_file_name"
        for listfile_name in `$WHICH_FIND "$BDIR" -type f -iname "$FULLBACKPREFIX.*$TAREXT" -mtime +$BACKMTIME_STORED`; do
            [ "$listfile_name" != "$store_file_name" ] && rm "$listfile_name"
        done
    fi
# section: check
elif [ "$TARGET" = "$TARGET_CHECK" ]; then
    check_result=''
    check_status=1
    meolder_border=$(($BACKMINIMUMDAYS+1))
    if [ `$WHICH_FIND $0 \( -type f -or -type l \) \( -atime +$meolder_border -or -mtime +$meolder_border \)` ]; then
        # collecting list of databases which are not recent
        if [ -d "$DATADIR" ]; then
            atime_border=$(($BACKMINIMUMDAYS+1))
            if [ $OSMARKER = "FreeBSD" ]; then
                atime_crit='Btime'
            else
                atime_crit='atime'
            fi
            for f in `$WHICH_FIND "$DATADIR" -maxdepth 1 -type d -$atime_crit +$atime_border`; do
                if [ "$f" != "$DATADIR" ]; then
                    db_list_notrecent=$db_list_notrecent" "`$WHICH_BASENAME $f`
                    db_cnt_notrecent=$(($db_cnt_notrecent+1))
                fi
            done
            db_cnt_new=$(($db_cnt-$db_cnt_notrecent))
            check_result="OK - healthy backups, databases: $db_cnt_new/$db_cnt (new/total)"
            check_status=0
        else
            check_result="WARNING - Database directory does not exist: '$DATADIR'"
            check_status=1
        fi
        if [ -d "$BDIR" ]; then
            if [ $OSMARKER = "Linux" ]; then
                mtime_first=1
                mtime_last=$BACKMINIMUMDAYS
            else
                mtime_first=2
                mtime_last=$(($BACKMINIMUMDAYS+1))
            fi
            for db_name in ${db_list_notrecent}; do
                if [ $db_name!='' ]; then
                    cnt_healthy_backups=0
                    mtime_check=$mtime_first
                    while [ "$mtime_check" -le "$mtime_last" ]; do
                        search_result=`$WHICH_FIND "$BDIR" -type f -iname "$db_name.*$BEXT$GZEXT" \! -size 0 -mtime $mtime_check`
                        [ "$search_result" != "" ] && cnt_healthy_backups=$(($cnt_healthy_backups+1))
                        mtime_check=$(($mtime_check+1))
                    done
                    if [ "$cnt_healthy_backups" -lt "$BACKMINIMUMDAYS" ]; then
                        cnt_missing=$(($BACKMINIMUMDAYS-$cnt_healthy_backups))
                        check_result="CRITICAL - missing $cnt_missing backup(s) of database '$db_name'"
                        check_status=2
                        break
                    fi
                fi
            done
        else
            check_result="WARNING - Backup directory does not exist: '$BDIR'"
            check_status=1
        fi
    else
        check_result="OK - check has not been performed, it's new installation"
        check_status=0
    fi
    $WHICH_ECHO $check_result
    exit $check_status
fi
2013/05/23 17:54

Настройка rsyslog для удаленного протоколирования в Debian

Клиент

/etc/rsyslog.d/logclient.conf

# UDP
*.*     @123.123.123.123:514
Сервер

Создадим директорию для логов

# mkdir -p /var/log/remote/
# chmod 700 /var/log/remote/

/etc/rsyslog.d/logserver.conf

# log settings for host

# loading UDP listener module
$ModLoad imudp

# bind listener to specified IP
$UDPServerAddress 123.123.123.123

# allow remote client
$AllowedSender UDP, 321.321.321.321

# template for all remote clients
$template RemoteHost,"/var/log/remote/%HOSTNAME%.log"

# ruleset for remote clients
$RuleSet remote
*.* ?RemoteHost

# applying remote ruleset to UDP listener
$InputUDPServerBindRuleset remote

# run listener
$UDPServerRun 514
2013/04/23 23:44

Скрипт установки модуля ustats для nginx в Debian

Автоматическая установка модуля ustats, предназначенного для отображения статистики upstream'ов для nginx.
Версия под Debian wheezy. Должен быть установлен пакет build-essential.

Активируется по добавлению в конфиг виртуального хоста

      location /ustats {
          ustats memsize=2m;
          ustats_refresh_interval 6000;
          ustats_html_table_width 95;
          ustats_html_table_height 95;
      }

Сам скрипт:

#!/bin/bash

SRC_DIR="/opt/src/ustats"

mkdir -p $SRC_DIR
git clone https://github.com/0xc0dec/ustats.git $SRC_DIR
cd $SRC_DIR
git pull

rm -rf $SRC_DIR/nginx-src
mkdir -p $SRC_DIR/nginx-src
cd $SRC_DIR/nginx-src
apt-get source nginx-full
apt-get build-dep nginx-full -y

nginx_src=`find $SRC_DIR/nginx-src -maxdepth 1 -type d | tail -n 1`
cd $nginx_src

cat $SRC_DIR/nginx.patch | patch -p1 --dry-run
OUT=$?
if [[ $OUT == 0 ]]; then
    cat $SRC_DIR/nginx.patch | patch -p1
    cp -a $SRC_DIR/ustats src/http/modules/
    sed 's#--prefix=/etc/nginx \\#--prefix=/etc/nginx --add-module=src/http/modules/ustats \\#g' -i debian/rules
    debuild -us -uc -b
fi
2013/04/22 23:15
start.txt · Last modified: 2016/09/22 01:27 by kyxap