воскресенье, 9 декабря 2012 г.

Setuid, Setgid


Поиск файлов с битом setuid

find / -type f -perm -4000 -exec ls -l {} \;

...
-rwsr-xr-x 1 root root 35712 Nov  8  2011 /bin/ping
-rwsr-xr-x 1 root root 40256 Nov  8  2011 /bin/ping6
-rwsr-xr-x 1 root root 69096 Mar 30  2012 /bin/umount
-rwsr-xr-x 1 root root 36832 Sep 13 02:29 /bin/su
-rwsr-xr-x 1 root root 31304 Mar  2  2012 /bin/fusermount
-rwsr-xr-x 1 root root 94792 Mar 30  2012 /bin/mount
...

(Бит setuid, установленный для директорий игнорируется (в большинстве дистрибутивов Linux/Unix))

Поиск файлов и каталогов с битом setgid

find / -perm -2000 -exec ls -l {} \;

...
-rwxr-sr-x 1 root tty 14648 Mar 31  2012 /usr/bin/bsd-write
-rwxr-sr-x 3 root mail 14544 Oct 18  2011 /usr/bin/mail-unlock
-rwxr-sr-x 3 root mail 14544 Oct 18  2011 /usr/bin/mail-touchlock
-rwsr-sr-x 1 daemon daemon 47928 Oct 25  2011 /usr/bin/at
-rwxr-sr-x 1 root mlocate 39472 Aug 17  2011 /usr/bin/mlocate
-rwxr-sr-x 1 root shadow 50760 Sep 13 02:29 /usr/bin/chage
-rwxr-sr-x 3 root mail 14544 Oct 18  2011 /usr/bin/mail-lock
-rwxr-sr-x 1 root utmp 375984 Jun  6  2011 /usr/bin/screen
-rwxr-sr-x 1 root shadow 23168 Sep 13 02:29 /usr/bin/expiry
-rwxr-sr-x 1 root tty 18976 Mar 30  2012 /usr/bin/wall
-rwxr-sr-x 1 root mail 14800 Oct 17  2011 /usr/bin/dotlockfile
-rwxr-sr-x 1 root crontab 35896 Jun 20  2012 /usr/bin/crontab
-rwxr-sr-x 1 root ssh 129104 Apr  2  2012 /usr/bin/ssh-agent
-rwsr-sr-x 1 libuuid libuuid 18856 Mar 30  2012 /usr/sbin/uuidd
...

Поиск файлов и каталогов c обеими битами сразу

find / -perm -6000 -exec ls -l {} \;

...
-rwsr-sr-x 1 daemon daemon 47928 Oct 25  2011 /usr/bin/at
-rwsr-sr-x 1 libuuid libuuid 18856 Mar 30  2012 /usr/sbin/uuidd
...

setuid, setgid для файла:

Когда атрибут setuid установлен файлу (chmod u+s), обычный пользователь, запускающий этот файл на исполнение, получает повышение прав до пользователя-владельца файла (обычно root) в рамках запущенного процесса. После получения повышенных прав приложение может выполнять задачи выполнение которых обычному пользователю недоступно. Пользователю будет запрещено системой изменение нового процесса. Из-за возможности состояния гонки многие операционные системы игнорируют установленный атрибут к shell-скриптам.
Хоть атрибут setuid очень удобен во многих случаях, его неправильное использование может представлять угрозу безопасности когда атрибут присваивается исполняемому файлу, который не тщательно спроектирован. Пользователи могут использовать уязвимости в недоработанных программах, чтобы получить повышенные привилегии или непреднамеренно запустить программу троянского коня.
Установленный setgid атрибут (chmod g+s) дает аналогичное повышение прав, но только для группы. Атрибуты setuid и setgid обычно устанавливаются командой chmod установкой первого бита в 4 (setuid) или 2 (setgid). Команда "chmod 6711" соответственно установит оба бита сразу (4+2=6). Также можно использовать символьные аргументы для установки этих битов командой "chmod ug+s".
Обычно, установка бита setuid и setgid на неисполняемых файлах бессмысленна.

setuid, setgid для директории:

Бит setgid для папки (chmod g+s) заставляет только новые папки и файлы, созданные в ней, наследовать ID группы этой папки вместо ID группы пользователя создавшего файл. Новые подпапки также наследуют бит setgid. Это например позволяет создать общее рабочее пространство для группы без неудобств членам группы явно менять их текущую группу для создания новых файлов и папок. Наследование устанавливается только для новых файлов и папок.

Бит setuid не несет никакого смысла, если он установлен на директорию.

Полезные shell команды


Nohup

Запуск процесса в фоновом режиме с игнорированием к сигналу HUP, чтобы процесс мог продолжать свою работу, после того как пользователь выйдет из системы.

nohup <command> &

nohup — UNIX-утилита, запускающая указанную команду с игнорированием сигналов потери связи (hangup)таким образом, команда будет продолжать выполняться в фоновом режиме и после того, как пользователь выйдет из системы. Если стандартным выводом (stdout) команды является терминал, то он и стандартный поток диагностики (stderr) перенаправляются с добавлением в файл «nohup.out» в текущей директории; если это невозможно сделать, то перенаправление происходит в файл «$HOME/nohup.out». Если и это невозможно сделать, то команда не запускается совсем.
При создании файлов «nohup.out» или «$HOME/nohup.out» команда nohup устанавливает им атрибуты доступа только для владельца этих файлов (группа и остальные пользователи не имеют прав доступа к этим файлам). Если же эти файлы уже существуют, то их права доступа не изменяются.
nohup не переводит автоматически команду в фоновый режим; пользователь должен сделать это явным образом, завершив командную строку символом «&».

Работа с сигналами


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

kill -n HUP <PID>

Временная остановка процесса:

Выполняется с помощью отправки сигнала stop:

kill -s STOP 1313, где 1313 PID процесса


после чего в выводе утилиты ps в поле STAT описывающее текущее состояние процесса он засветится как T

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

tsyrenov  1214  0.0  0.0  73360  1796 ?        S    23:06   0:00 sshd: tsyrenov@pts/1
tsyrenov  1215  0.0  0.3  26256  7516 pts/1    Ss+  23:06   0:00 -bash
tsyrenov  1313  0.4  0.1  14616  2200 pts/1    T    23:06   0:02 watch -n0 date


Возобновление работы приостановленного процесса можно выполнить отправкой сигнала CONT

kill -s CONT 1313

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

Гарантированное уничтожение процесса

kill -s KILL <PID>

Уничтожение процесса с созданием дампа памяти

kill -s SEGV <PID>

Nice, renice

Запуск процесса с понижением приоритета на право доступа к cpu (чем выше значение, тем ниже приоритет). Возможный диапазон значений от +20 до -19.

nice -n '12' bash

процесс был запущен из под рядового пользователя у которого по умолчанию есть права только на понижение приоритета, но не на повышение. В выводе утилиты ps с ключом lax, данный процесс в поле NI отображающего фактор уступчивости засветится значением 12

F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND

5  1000 19138 19006  20   0  73360  1788 poll_s S    ?          0:00      \_ sshd: tsyrenov@pts/1
0  1000 19139 19138  20   0  26256  7520 wait   Ss   pts/1      0:00          \_ -bash
0  1000 19238 19139  32  12  22816  3972 n_tty_ SN+  pts/1      0:00              \_ bash

вся дальнейшая работа из под такого shell'а будет выполнятся с пониженным, унаследованным приоритетом 12.

Уже работающим процессам на лету изменить приоритет можно с помощью renice.

Из под пользователя root мы можем на лету изменить приоритет в любую сторону

root@srv:~# renice -22 19238
19238 (process ID) old priority 12, new priority -20

Видим что приоритет у процесса поднялся до -20

5  1000 19138 19006  20   0  73360  1788 poll_s S    ?          0:00      \_ sshd: tsyrenov@pts/1
0  1000 19139 19138  20   0  26256  7520 wait   Ss   pts/1      0:00          \_ -bash
0  1000 19238 19139   0 -20  22816  4072 n_tty_ S<+  pts/1      0:00              \_ bash

С ключом -u можно увеличить фактор уступчивости для всех процессов конкретного пользователя

root@srv:~# renice 10 -u tsyrenov
1000 (user ID) old priority -20, new priority 10

4     0 19006   435  20   0  73360  3540 poll_s Ss   ?          0:00  \_ sshd: tsyrenov [priv]
5  1000 19138 19006  30  10  73360  1788 poll_s SN   ?          0:00      \_ sshd: tsyrenov@pts/1
0  1000 19139 19138  30  10  26256  7520 wait   SNs  pts/1      0:00          \_ -bash
0  1000 19238 19139  30  10  22816  4072 wait   SN   pts/1      0:00              \_ bash

Fuser

Для определения процессов использующих те или иные файлы или сокеты, можно воспользоваться утилитой fuser. Fuser полезен при диагностике, например при ситуации когда размонтируемая файловая система занята по причине того что используется какими либо процессами, все эти процессы можно без труда выявить.


root@srv:~# fuser -mv /dev
                     USER        PID ACCESS COMMAND
/dev:                root     kernel swap  /dev/dm-1
                     root     kernel mount /dev
                     root          1 F.... init
                     root        306 F.... upstart-udev-br
                     root        310 F.... udevd
                     root        474 F.... sshd
                     messagebus    482 F.... dbus-daemon
                     root        546 F.... upstart-socket-
                     root        579 F.... udevd
                     root        616 F.... udevd
                     root        746 F.... getty
                     root        757 F.... getty
                     root        776 F.... getty
                     root        778 F.... getty
                     root        784 F.... getty
                     root        796 F.... acpid
                     whoopsie    806 F.... whoopsie
                     root        812 F.... cron
                     daemon      813 F.... atd
                     root        844 F.... getty
                     root        864 F.... sshd

root@srv:~# fuser -mv /run/shm
                     USER        PID ACCESS COMMAND
/run/shm:            root     kernel mount /run/shm




воскресенье, 8 января 2012 г.

Настройки PHP-FPM

(PHP 5.2.17, PHP-FPM 0.5.14)


Глобальные параметры


pid_file - pid файл. По умолчанию: то, что было указано при maleextra компилировании опцией --with-fpm-pid

error_log - файл журнала ошибок. По умолчанию: то, что было указано при компилировании опцией --with-fpm-log

log_level - уровень записываемых в журнал ошибок. По seo India умолчанию: "notice" (TODO: get list)

emergency_restart_threshold - при это числе рабочий процессов завершенных с SIGSEGV или SIGBUS... По умолчанию: 10

emergency_restart_interval - ...менее чем за этот промежуток instant performer времени, php-fpm будет мягко перезапущен. Это необходимо, чтобы исключить случайные повреждения памяти. По умолчанию: "1 минута"

process_control_timeout - время ожидания ответа от рабочий процессов. По умолчанию: "5 секунд"

daemonize - укажите "no" для отладки php-fpm или для его performer5 запуска в диспетчере (runit/sv, daemontools, upstart, etc.) По умолчанию: "yes"

Настройки пулов

Пул естественно может быть не один, а сколько вам потребуется. Это позволяет запускать их под разными системными пользователями, разными chroot'ами и т.д. Вообщем это дает определенною гибкость, так как позволяет в каждом пуле использовать свои собственные настройки под веб-приложение, которое будет его использовать. Улучшает безопасность, так как веб-приложения изолированы друг от друга и при компрометации одного приложения, остальные останутся в относительной безопасности. Кроме того это же и облегчает процесс обнаружения скомпрометированных веб-приложений.

В конфигурационном файле php-fpm.conf объявление 2-3 пулов будет выглядеть примерно так

<?xml version="1.0" ?>
<configuration>
<workers>
<section name="pool">
<value name="name">pool-1</value>
...
...
</section>
<section name="pool">
<value name="name">pool-2</value>
...
...

</section>
<section name="pool">
<value name="name">pool-3</value>
...
...
</section>
</workers>
</configuration>


Но так как PHP-FPM с PHP версий ниже 5.3.3 не поддерживает динамическое число дочерних процессов, то путем разнесения веб-приложений по свои отдельным php-fpm пулам, мы теряем по ресурсам. Связано это с тем что при static style pm кол-во процессов всегда одинаковое и если все процессы в одном пуле и ими пользуются все веб-приложения, то единовременно каждому приложению доступно на порядок большее число php-fpm процессов для обработки запросов, чем если бы у каждого приложения было по собственному персональному пулу.


name - имя пула, используется php-fpm'ом при ведении логов

listen_address - прослушиваемый адрес, здесь можно указать как сетевой адрес и порт, так и файловый сокет, например 127.0.0.1:9000 или tmp/php-fpm.sock, соответственно

owner - владелец, который будет назначен файловому сокету

group - группа, которая будет назначена файловому сокету

mode - права, которые будут выставлены на созданный файловый сокет

php_defines - описание настроек php, которые будут применены к данному пулу, перекрыв настройки указанные в /etc/php.ini. Например задание параметров max_execution_time и upload_max_filesize будет выглядеть вот так


<value name="php_defines">
<value name="max_execution_time">120</value>
<value name="upload_max_filesize">30</value>
</value>


user - системный пользователь из под которого будет работать процесс текущего пула

group - системная группа из под которой будет работать процесс текущего пула

style - задает стиль управления кол-вом рабочих процессов php-fpm. Возможные значения это static и apache-like (для PHP версии 5.2.17 с патчем PHP-FPM 0.5.14 - apache-like скорее всего работать не будет, с PHP версии 5.3.3 значение apache-like переименовано в dynamic и работает)

max_children - максимальное кол-во одновременно обрабатываемых запросов, т.е. кол-во процессов php-fpm которое будет запущено

startservers - кол-во создаваемых рабочих процессов php-fpm при запуске (применяется только при использовании apache-like для style)

minspareservers - минимальное кол-во рабочих процессов php-fpm (применяется только при использовании apache-like для style)

maxspareservers - максимальное кол-во рабочих процессов php-fpm (применяется только при использовании apache-like для style)

request_terminate_timeout - время в секундах на обслуживание одного запроса, по истечение которого рабочий процесс будет остановлен. Используется в том случае когда php параметру max_execution_time по каким либо причинам не удается остановить выполнение скрипта. Значение "0s" отключает использование этой функции.

request_slowlog_timeout - время в секундах для обработки одного запроса и при превышении которого данные о выполненном php скрипте будут сброшены в slow.log файл (аналог логирования медленных sql запросов Mysql сервера). 
Значение "0s" отключает использование этой функции.

slowlog - лог файл для записи в него информации о медленных запросах

rlimit_files - устанавливает лимит дескрипторов открытых файлов rlimit

rlimit_core - устанавливает максимальное кол-во используемых ядер rlimit

chroot - директория chroot окружения при запуске. Путь должен быть абсолютным

chdir - изменяет текущую директория при запуске

catch_workers_output - перенаправление STDOUT и STDERR рабочего процесса в главный лог ошибок. Если не установлен, STDOUT и STDERR будут перенаправлены в /dev/null в соответствии со спецификацией FastCGI

max_requests - кол-во запросов которое может обработать процесс, по истечению лимита которого он будет перезапущен. Полезно для минимизации негативного эффекта от утечки памяти при использовании сторонних библиотек. Нулевое значение отключает перезапуск

allowed_clients - список IP адресов запросы с которых будут разрешены к обработке, IP адреса перечисляются через запятую. Нулевое значение снимает ограничение на доступ к php-fpm по IP адресу

Переменные окружения

Особо описывать нечего, ниже часть настроек по умолчанию из конфига php-fpm

                        <value name="environment">
                                <value name="HOSTNAME">$HOSTNAME</value>
                                <value name="PATH">/usr/local/bin:/usr/bin:/bin</value>
                                <value name="TMP">/tmp</value>
                                <value name="TMPDIR">/tmp</value>
                                <value name="TEMP">/tmp</value>
                                <value name="OSTYPE">$OSTYPE</value>
                                <value name="MACHTYPE">$MACHTYPE</value>
                                <value name="MALLOC_CHECK_">2</value>
                        </value>

понедельник, 2 января 2012 г.

Сборка PHP-FPM в Deb пакет

Пошаговый мануал по сборке PHP-FPM в Deb пакет


(ОС: Debian GNU/Linux 6.0 amd64, PHP 5.2.17, PHP-FPM 0.5.14)

Устанавливаем пакеты необходимые для работы

apt-get install build-essential dh-make libxml2-dev


Создаем каталог в который будем производить инсталляцию пакета до его сборки в deb пакет

mkdir /tmp/package


Логинимся в систему под обычным пользователем и все дальнейшие действия выполняем из под него. Скачиваем нужную нам версию PHP (в примере это будет PHP версии 5.2.17) и распаковываем ее в домашнем каталоге пользователя, под которым зашли в систему

cd ~
wget http://ru.php.net/distributions/php-5.2.17.tar.gz
tar -xf php-5.2.17.tar.gz


скачиваем PHP-FPM патч для нашей версии PHP, выполняем декомпрессию

wget http://php-fpm.org/downloads/php-5.2.17-fpm-0.5.14.diff.gz
gzip -d php-5.2.17-fpm-0.5.14.diff.gz


проходим в каталог с исходным кодом PHP

cd php-5.2.17


теперь патчим наш PHP патчем PHP-FPM и включаем поддержку FastCGI и собственно PHP-FPM (в ./configure не забываем добавить нужные нам ключи для сборки PHP с необходимыми нам модулями, например поддержка Mysql)

patch -p1 < ../php-5.2.17-fpm-0.5.14.diff
./configure --prefix= --bindir=/usr/bin --sbindir=/usr/sbin --mandir=/usr/share/man --libdir=/usr/lib --includedir=/usr/include --enable-fastcgi --enable-fpm --with-fpm-log=/var/log/php-fpm.log --with-fpm-pid=/var/run/php-fpm.pid --with-mysql --with-zlib --with-config-file-path=/etc


выполняем компиляцию и установку PHP в заранее подготовленный нами каталог /tmp/package. Данный процесс займет некоторое время, зависит от мощности сервера

INSTALL_ROOT=/tmp/package make all install


если все пройдет нормально, то по завершению будет примерно такой вывод

Build complete.
Don't forget to run 'make test'.


Installing PHP SAPI module:       cgi
Installing PHP CGI binary: /tmp/package/usr/bin/
Installing FPM config:            /tmp/package/etc/php-fpm.conf
Installing init.d script:         /tmp/package/sbin/php-fpm
Installing PHP CLI binary:        /tmp/package/usr/bin/
Installing PHP CLI man page:      /tmp/package/usr/share/man/man1/
Installing build environment:     /tmp/package/usr/lib/build/
Installing header files:          /tmp/package/usr/include/php/
Installing helper programs:       /tmp/package/usr/bin/
  program: phpize
  program: php-config
Installing man pages:             /tmp/package/usr/share/man/man1/
  page: phpize.1
  page: php-config.1
Installing PEAR environment:      /tmp/package/usr/lib/php/
[PEAR] Archive_Tar    - installed: 1.3.7
[PEAR] Console_Getopt - installed: 1.2.3
[PEAR] Structures_Graph- installed: 1.0.3
[PEAR] XML_Util       - installed: 1.2.1
warning: pear/PEAR requires package "pear/Archive_Tar" (recommended version 1.3.7)
warning: pear/PEAR requires package "pear/Structures_Graph" (recommended version 1.0.3)
warning: pear/PEAR requires package "pear/Console_Getopt" (recommended version 1.2.3)
warning: pear/PEAR requires package "pear/XML_Util" (recommended version 1.2.1)
[PEAR] PEAR           - installed: 1.9.1
Wrote PEAR system config file at: /tmp/package//etc/pear.conf
You may want to add: /usr/lib/php to your php.ini include_path
Installing PDO headers:          /tmp/package/usr/include/php/ext/pdo/


(в корне каталога /tmp/package удаляем все файлы и каталоги имя которых начинается на точку)


В каталоге /tmp/package создаем подкаталог DEBIAN, в нем файл control с примерно таким содержимым

Package: php-5.2.17-fpm-0.5.14
Architecture: amd64
Depends:
Provides:
Priority:
Version: 5.2.17
Maintainer: nobody
Description: PHP 5.2.17 with PHP-FPM 0.5.14


в этом же каталоге создаем еще один файл c именем preinst (выставляем ему права 775). Этот файл выполняется перед разворачиванием пакета в системе, в нашем случае это простой скрипт, который создаст системного пользователя php-fpm из под которого будет работать PHP-FPM. Выглядит скрипт вот так

#!/bin/sh -e


id php-fpm >/dev/null 2>&1 || addgroup --system php-fpm && \
adduser --system --no-create-home --disabled-password --ingroup php-fpm php-fpm

теперь создаем файл postinst (выставляем ему права 775), это скрипт запускается после разворачивания пакета. Он копирует php-fpm скрипт к init скриптам, делает его исполняемым и прописывает в автозагрузку

#!/bin/sh -e

cp /sbin/php-fpm /etc/init.d/ && \
chmod +x /etc/init.d/php-fpm && \
/usr/sbin/update-rc.d -f php-fpm defaults

и последний файл имеющий отношение к pre, post, rm скриптам Deb пакета это prerm. Он запускается перед удалением пакета из системы, у нас он останавливает PHP-FPM, удаляет системного пользователя php-fpm, убирает php-fpm из автозагрузки и удаляет init скрипт. Как обычно права на него 775

#!/bin/sh -e

/usr/sbin/invoke-rc.d php-fpm stop && \
userdel php-fpm && \
/usr/sbin/update-rc.d -f php-fpm remove && \
rm -f /etc/init.d/php-fpm

В файле /tmp/package/sbin/php-fpm корректируем путь к php-cgi

php_fpm_BIN=/usr/bin/php-cgi


в /tmp/package/etc/php-fpm.conf выставляем пользователя из под которого будет работать PHP-FPM, эту часть конфига:

                        Unix user of processes
                <!--    <value name="user">nobody</value>                               -->

                        Unix group of processes
                <!--    <value name="group">nogroup</value>             -->

меняем на такую:

                        Unix user of processes
                        <value name="user">php-fpm</value>

                        Unix group of processes
                        <value name="group">php-fpm</value>

из под root пользователя меняем владельца и группу для всех файлов в каталоге /tmp/package

chown -R root:root /tmp/package


и из под обычного пользователя выполняем сборку Deb пакета


cd ~
dpkg-deb -b /tmp/package/ php-5.2.17-fpm-0.5.14-amd64.deb


будет аналогичное сообщение

dpkg-deb: building package `php-5.2.17-fpm-0.5.14' in `php-5.2.17-fpm-0.5.14-amd64.deb'.


и в текущем каталоге появится собранный Deb пакет php-5.2.17-fpm-0.5.14-amd64.deb

Теперь из под root пользователя можем установить собранный нами пакет

dpkg -i php-5.2.17-fpm-0.5.14-amd64.deb


(конфигурационный файл php.ini размещаем в каталоге /etc)