воскресенье, 7 июля 2013 г.

Возможность чтения лог файлов пользователем отличным от root

Бывают случаи, когда нужно пользователю, не обладающему привилегиями root, дать возможность читать системные логи. В случае использования rsyslog, это легко сделать, предоставив определенной группе, в которую входит пользователь, право на чтение лог файлов. Для смены группы владельца всех журналов необходимо добавить в конфигурацию /etc/rsyslog.conf следующие директивы (точно работает в rhel\centos 6, версия rsyslog 5.8.10):

$umask 0000
$FileGroup some_group
$FileCreateMode 0640

Если вы пользуетесь более новой версией rsyslog, чем в rhel\centos 6 (например, которая поставляется в fedora 18 - rsyslog 7.2.6), можно воспользоватся более изящным способом - через action. К примеру, для того, чтобы лог файл messages имел группу владельца wheel:

*.info;mail.none;authpriv.none;cron.none   action(type="omfile" FileCreateMode="0644" FileGroup="wheel" File="/var/log/messages")



вторник, 11 июня 2013 г.

Аудит в Linux

Обычно об аудите задумываются когда возникают подозрения в компрометации системы. Лично я использовал аудит несколько раз за свою практику. И каждый раз я быстренько смотрел одним глазочком, как его настроить. Как правило это был аудит модификаций файлов. В данной статье я не преследую цель раскрыть архитектурные подробности устройства аудита в linux, или дать рекомендации по настройке/администрированию для сред CC-CAPP/EAL (Common Criteria-Controlled Access Protection Profiles/Evaluation Assurance Level), это скорее практическая статья. Хотя минимум теоретической информации все же необходим. Все ниже написанное справедливо для rhel6, расхождения с другими дистрибутивами не существенное.

Подсистема аудита состоит из нескольких компонентов:

  • модуль ядра — перехватывает системные вызовы (syscalls) и регистрирует событие;
  • даемон auditd — пишет зарегистрированное событие на диск в файл;
  • даемон audispd — осуществляет пересылку сообщений (диспетчер) к другому приложению;
  • ряд вспомогательных утилит:

    • auditctl — утилита управления демоном auditd;
    • aureport — дает возможность составить отчет, отчет может быть настроен под задачи;
    • ausearch — позволяет выбрать события по заданному критерию;
    • autrace — утилита позволяет выполнить трассировку отдельного приложения.

Используемые конфигурационные файлы:

  • /etc/sysconfig/auditd — содержит настройки используемые при старте даемона auditd;
  • /etc/audit/auditd.conf — настройки поведения даемона auditd;
  • /etc/audit/audit.rules — файл содержащий правил аудита.

Настройка даемона auditd.
Как отмечено выше, настройка сводится к изменению параметров в файлах конфигурации /etc/sysconfig/auditd и /etc/audit/auditd.conf. Поверьте мне на слово, файл /etc/sysconfig/auditd с содержимым по умолчанию можно не трогать, там ничего интересного нет. Разберем лучше сразу второй файл - /etc/audit/auditd.conf.

# cat /etc/audit/auditd.conf
log_file = /var/log/audit/audit.log 
log_format = RAW 
log_group = root 
priority_boost = 4 
flush = INCREMENTAL 
freq = 20 
num_logs = 5 
disp_qos = lossy 
dispatcher = /sbin/audispd 
name_format = NONE 
##name = mydomain 
max_log_file = 6 
max_log_file_action = ROTATE 
space_left = 75 
space_left_action = SYSLOG 
action_mail_acct = root 
admin_space_left = 50 
admin_space_left_action = SUSPEND 
disk_full_action = SUSPEND 
disk_error_action = SUSPEND 
##tcp_listen_port = 
tcp_listen_queue = 5 
tcp_max_per_addr = 1 
##tcp_client_ports = 1024-65535 
tcp_client_max_idle = 0 
enable_krb5 = no 
krb5_principal = auditd 
##krb5_key_file = /etc/audit/audit.key

Значения параметров:

  • log_file — место расположения и название файла аудита;
  • log_format — формат ведения лога. Возможные значения: RAW — сообщения записываются в том виде как их передало ядро; nolog — не писать сообщения;
  • log_group — группа-владелец лог-файла аудита;
  • priority_boost — приоритет c каким работает даемон (nice).
  • flush — как будет записываться лог-файл на диск. Возможные значения: none — не использовать политики записи, incremental —  лог будет записываться с определенной периодичностью, определенной в параметре freq; data — данные пишутся в файл в синхронном режиме; sync — в синхронном режиме находятся не только данные но и метаданные файла.  
  • freq — число событий при котором осуществляется запись данных на диск, используется при значении flush = incremental. 
  • num_logs — число лог файлов аудита хранимых на диске, если настроена ротация в параметре max_log_file_action.
  • disp_qos — определяет надежность передачи данных между даемоном auditd и диспетчером audispd. Возможные значения: lossy — auditd может не передавать некоторые события аудита, если очередь событий полна при этом события будут записаны на диск; lossless — логирование событий на диск будет остановлено пока не освободится место в очереди.
  • dispatcher — где располагается исполняемый файл диспетчера.
  • name_format и name. name_format — определяет порядок разрешения имен хостов. Возможные значения: none — имя не используется; hostname — имя возвращенное через запрос gethostname; fqd — полное имя хоста, возвращенное через DNS запрос; numeric — ip адрес; user — строка определенная в параметре name.
  • max_log_file и max_log_file_action. max_log_file — максимальный размер лог файла в мегабайтах, по достижению которого будет выполнено действие определенное в max_log_file_action. Возможные действия: ignore — ничего не делать; syslog — отправить предупреждение в syslog; suspend — остановить запись событий на диск; rotate — произвести ротацию лог файлов в соответствии с числом num_logs; keep_logs — осуществить ротацию, при этом не удалять старые файлы.
  • space_left, space_left_action и action_mail_acct. space_left — величина в мегабайтах, определяющая размер оставшегося дискового пространства при достижении которого будет выполнно действие space_left_action. Возможные действия: ignore — ничего не делать;  syslog — отправить предупреждение в syslog; email — отправить письмо аккаунту определенному в action_mail_acct; exec — выполнить скрипт; suspend — остановить запись на диск, перевести систему в single mode; halt — выключить систему.
  • admin_space_left и admin_space_left_action. admin_space_left — величина в мегабайтах оставшегося свободного пространства на диске. Последний шанс для администратора что бы добавить/очистить свободное пространство. Величина должна быть меньше чем space_left. Действия которые можно определить в admin_space_left_action аналогичны space_left_action.
  • disk_full_action — действия выполняемые при заполнении всего дискового пространства, аналогичны space_left_action. 
  • disk_error_action — действия выполняемые при возникновении дисковой ошибки, аналогичны space_left_action.
  • tcp_listen_port, tcp_listen_queue, tcp_max_per_addr, tcp_client_ports и tcp_client_max_idle — даемон аудита может принимать сообщения от других даемонов. Данные переменные определяют сетевые настройки.
  • enable_krb5, krb5_principal, krb5_key_file — переменные определяющие аутентификацию по протоколу kerberos. 

Управление подсистемой аудита
Управление подсистемой аудита и добавление новых правил осуществляется утилитой — auditctl. Естественно эти изменения временные, для того что бы они стали постоянными их необходимо прописать в /etc/audit/audit.rules.

Основные команды управления auditctl:

  • -e [0..2] — (enabled), при 0 — отключить, 1 — включить, 2 — включить и заблокировать конфигурацию аудита. В случае блокировки изменение конфигурации аудита будет доступно только после перезагрузки хоста; 
  • -f [0..2] — (flag), установка поведения при критической ошибке, 1 — ничего не делать, 1 — вывести сообщение на консоль, 2 — немедленное выключение системы;
  • -r — (rate_limit), лимит скорости сообщений в минуту, при 0 — скорость не лимитируется. Если будет осуществлено превышение — будет выполнено действие поведения при критической ошибке flag;
  • -b — (backlog_limit), размер буфера сообщений ожидающих обработки. Если будет осуществлено превышение — будет выполнено действие поведения при критической ошибке flag;
  • -s — запрос текущего состояние даемона аудита;
  • -l — вывод всех текущих правил аудита;
  • -D — очистить все правила аудита.

Приведу несколько примеров:
Посмотрим как выглядит настройка по умолчанию даемона аудита:

# auditctl -s 
AUDIT_STATUS: enabled=1 flag=1 pid=985 rate_limit=0 backlog_limit=320 lost=0 backlog=0

Удалим все существующие правила:

# auditctl -D

Увеличим размер буфера сообщений:

# auditctl -b 1024

Добавим правило аудита, оно включает протоколирование всех попыток изменить содержимое файла /etc/shadows или изменить его атрибуты, структуру правил рассмотрим позже:

# auditctl -w /etc/shadow -p wa

В файл /etc/audit/audit.rules параметры конфигурации и правила записывается точно в таком же виде, как и  консольные команды, за исключением самой команды auditctl, т.е для вышеприведенных примеров будет справедливо:

# cat /etc/audit/audit.rules
-D
-b 1024
-w /etc/shadow -p wa

среда, 23 января 2013 г.

Клонирование P2V в инфраструктуру VMware без vCenter Converter


Производить миграцию или клонирование P2V серверов в инфраструктуру vmware, конечно удобно проводить при помощи vCenter Converter. Однако, vCenter Converter будет работать только если разделы ОС находятся под управлением LVM, или это должны быть диски с разделами (а не просто диски). Подробнее узнать об ограничениях можно здесь. В случае если условия не удовлетворяют, Вам придется произвести миграцию самостоятельно. В моем случае было 10 серверов, настроенных на загрузку с SAN, LVM на них не используется, в качестве разделов ОС как раз использовались целые диски без партиций (LUN с схд). Операционная система – CentOS 5 x86_64. Сервера располагаются в ЦОД’е в Нью Йорке, виртуальные машины должны быть во Франкфурте. Итак, миграция по шагам, используя примеры команд. Я постарался документировать этот достаточно утомительный процесс и попробовать его автоматизировать:

Создание виртуальной машины
Создайте виртуальную машину с нужными характеристиками. Если хотите что то поменять по сравнению с физической - самое время это сделать. Я изменил количество дисков, т.к. разумно использовать один диск совместно с LVM.
Примонтируте любой live дистрибутив linux, например knoppix, fedora, gentoo и т.д. Обратите внимание на то, что архитектура дистрибутива Live CD должна соответствовать той, которую имеет переносимый сервер. У меня под руками был Gentoo 11.0. После загрузки, назначите IP адрес, шлюз, пароль root, и запустите sshd:

Gentoo-11 ~ # ifconfig eth0 192.168.1.25/24
Gentoo-11 ~ # route add default gw 192.168.1.25
Gentoo-11 ~ # passwd root
Gentoo-11 ~ # /etc/init.d/sshd start

Создание и форматирование разделов:
Поскольку я хотел использовать LVM, то простое копирование структуры дисковой подсистемы не годилось. Выбранная структура – один диск, разделенный на две партиции. Первая партиция - под загрузчик (500МБ), а вторая отдается под управление LVM.

Gentoo-11 ~ # parted -s /dev/sda mklabel msdos
Gentoo-11 ~ # parted -s /dev/sda mkpart primary 1MB 525MB
Gentoo-11 ~ # parted -s /dev/sda toggle 1 boot
Gentoo-11 ~ # parted -s /dev/sda mkpart primary 525MB 53.7GB
Gentoo-11 ~ # parted -s /dev/sda toggle 2 lvm

Создадим тома в LVM, разделы: подкачки, /root и /var/log

Gentoo-11 ~ # pvcreate /dev/sda2
Gentoo-11 ~ # vgcreate vgname /dev/sda2
Gentoo-11 ~ # lvcreate -L 2048 -n swap vgname
Gentoo-11 ~ # lvcreate -L 20480 -n root vgname
Gentoo-11 ~ # lvcreate -l 7042 -n log vgname

Внесите необходимые коррективы, если ваша таблица разделов будет отличаться.
Произведем форматирование:

Gentoo-11 ~ # mkfs.ext3 -L boot /dev/sda1
Gentoo-11 ~ # mkswap -L swap /dev/mapper/vgname-swap
Gentoo-11 ~ # mkfs.ext3 -L root /dev/mapper/vgname-root
Gentoo-11 ~ # mkfs.ext3 -L log /dev/mapper/vgname-log

Создайте папки, в которые затем примонтируем разделы:

Gentoo-11 ~ # mkdir -p /mnt/root
Gentoo-11 ~ # mount /dev/mapper/vgname-root /mnt/root/
Gentoo-11 ~ # mkdir -p /mnt/root/boot /mnt/root/var/log
Gentoo-11 ~ # mount /dev/sda1 /mnt/root/boot
Gentoo-11 ~ # mount /dev/mapper/vgname-log /mnt/root/var/log

Перенос данных.
Переносить данные будем через sftp. Для того, что бы не вводить пароль – скопируйте публичный ключ пользователя root с физического сервера:

root@source:~# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.1.25

Данные будем переносить в виде tar архива. Архив можно не создавать на исходном сервере, а сразу передать на целевой с помощью pipe, например:

root@source:~# tar czf - /usr | ssh root@192.168.1.25 "dd of=/mnt/root/var/usr.tgz"

Команде tar так же можно указать, что не нужно помещать в архив. Это можно указать в командной строке через параметр --exclude pattern, или создать файл исключений, который указывается через параметр -X file. В файле исключений можно указать директории /dev, /proc, /var/log и т.д. Но в отличие от данных в нутрии этих директорий – сами директории нужны, поэтому после переноса данных их нужно будет создать.
Перенос данных можно автоматизировать. Я написал скрипт converter.sh. Он создает tar архив и формирует файл скрипта mkdir.sh, которые передаются на целевой сервер. Скрипт mkdir.sh необходим для создания директорий, а так же он монтирует служебные файловые системы, такие как например proc. Файл exclude используется для указания исключений.

root@source:~# cat converter.sh
#!/bin/bash

exclude=./exclude
log=./converter.log

if [ $# -ne 2 ]; then echo "Usage: converter.sh destionation_server destination_directory"; exit 1; fi

cat /dev/null > $log 

ls / | while read dir
  do
    tar -czX $exclude -f - /$dir 2>>$log| ssh root@$1 "dd of=$2/$dir.tgz"
    echo -e "Backup /$dir \e[00;32mcomplete\e[00m"
  done

# Make the file, which makes directories
echo -n "Make and transfer executive file:"
cat /dev/null > ./mkdir.sh
echo -e "#!/bin/sh \n\n#Make directories" >> ./mkdir.sh
echo "if [ \$# -ne 1 ]; then echo \"Usage: mkdir.sh mount_point\"; exit 1; fi" >> ./mkdir.sh

for dir in /dev /proc /selinux /sys /tmp
do
  usrgrp=`stat -c %u:%g $dir`
  perm=`stat -c %a $dir`
  echo -e "mkdir \$1$dir \nchmod $perm \$1$dir \nchown $usrgrp \$1$dir" >> ./mkdir.sh
done

dirs=(`grep -v "$#\|$^\|dev\|proc\|selinux\|lost+found\|sys\|tmp" ./exclude | while read dir
do
  find $dir -type d | grep -v "lost+found"
done`)
element_count=${#dirs[@]}

index=0
while [ "$index" -lt "$element_count" ]
do
  usrgrp=`stat -c %u:%g ${dirs[$index]}`
  perm=`stat -c %a ${dirs[$index]}`
  echo -e "mkdir \$1${dirs[$index]} \nchmod $perm \$1${dirs[$index]} \nchown $usrgrp \$1${dirs[$index]}" >> ./mkdir.sh
  let "index=$index+1"
done

echo -e "mount --bind /dev \$1/dev \nmount --bind /proc \$1/proc \nmount --bind /sys \$1/sys" >> ./mkdir.sh

scp ./mkdir.sh root@$1:$2 2>>$log
echo -e " \e[00;32mcomplete\e[00m"

Для корректной работы скрипта, файл exclude должен быть в той же директории что и скрипт. Содержимое моего exclude:

root@source:~# cat ./exclude
/dev
/lost+found
/proc
/selinux
/sys
/var/log

Входные параметры скрипта converter.sh – dns имя сервера или его ip адрес, а так же директория назначения.
Выполним перенос данных:

root@source:~# ./converter.sh 192.168.1.25 /mnt/root/var/log

Развертывание данных
Теперь перейдем на целевой сервер и развернем данные:

Gentoo-11 ~ # cd /mnt/root
Gentoo-11 root # ls var/log/*.tgz | while read arch; do tar -xf $arch; done

Создадим директории и примонтируем служебные файловые системы при помощи скрипта mkdir.sh. Скрипт имеет входной параметр – место куда примонтирован корневой раздел:

Gentoo-11 root # sh var/log/mkdir.sh /mnt/root

Внесение изменений в конфигурационные файлы, установка grub
Так как, по сравнению с исходной системой, в таблицу разделов внесено изменение, то необходимо внести соответствующие изменения на целевом сервере. Внесите коррективы в fstab. Согласно моему:

Gentoo-11 root # cat /mnt/root/etc/fstab
LABEL=root  /        ext3   defaults 1 1
LABEL=boot  /boot    ext3   defaults 1 2
tmpfs       /dev/shm tmpfs  defaults 0 0
devpts      /dev/pts devpts gid=5,mode=620 0 0
sysfs       /sys     sysfs  defaults 0 0
proc        /proc    proc   defaults 0 0
LABEL=swap  swap     swap   defaults 0 0
tmpfs       /tmp     tmpfs  defaults,size=1G 0 0
LABEL=log   /var/log ext3   defaults 1 3

Теперь нужно войти в созданное окружение:

Gentoo-11 root # chroot /mnt/root

Уберите все лишнее из /etc/modprobe.conf и проверьте есть ли у вас строки:

Gentoo-11 root # cat /etc/modprobe.conf
alias scsi_hostadapter mptbase
alias scsi_hostadapter1 mptspi
alias scsi_hostadapter2 ata_piix

Это позволит включить эти модули ядра в initrd, что позволит в свою очередь корректно произвести загрузку (по умолчанию vmware выбирает адаптер LSI Logic Parallel)

Создадим новый initrd:

Gentoo-11 root # mkinitrd -v /boot/initrd-2.6.18-274-1.el5.img 2.6.18-274.el5

Внесите коррективы в настройки grub, учитывая смену диска root и новый initrd:

Gentoo-11 root # cat boot/grub/menu.lst
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-274.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-274.el5 ro root=/dev/vgname/root
initrd /initrd-2.6.18-274-1.el5.img

Финальная часть, необходимо установить загрузчик:

Gentoo-11 root # grub

grub> root (hd0,0)
root (hd0,0)
Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)
setup (hd0)
Checking if "/boot/grub/stage1" exists... no
Checking if "/grub/stage1" exists... yes
Checking if "/grub/stage2" exists... yes
Checking if "/grub/e2fs_stage1_5" exists... yes
Running "embed /grub/e2fs_stage1_5 (hd0)"... failed (this is not fatal)
Running "embed /grub/e2fs_stage1_5 (hd0,0)"... failed (this is not fatal)
Running "install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf "... succeeded
Done.
grub> quit
quit


Все! Можно перегружать виртуальный сервер и расслабиться после нудной работы.

Напоследок, команды, которые могут понадобиться:

  1. Просмотр таблицы разбиения диска
parted /dev/sda print
  1. Активация lvm
vgchange -a y

суббота, 19 января 2013 г.

Использование записей /etc/hosts в nginx


Недавно столкнулся с интересной особенностью в nginx. У меня возникла необходимость прописать в параметре proxy_path имя сервера, которое в свою очередь определено в /etc/hosts. Не работает! Немного погуглив, я нашел совет. Рекомендации которого заключается в следующем:
Прописать директиву

resolver 127.0.0.1

Которая указывает адрес (можно указать так же и порт) для днс запросов, установить на этот же сервер dnsmasq, который может брать информацию из /etc/hosts (немного о настройке dnsmasq можно прочитать в статье про настройку wi-fi точки доступа). Однако, имена в /etc/hosts все же можно использовать без этих манипуляций. Имя сервера нужно прописать в upstream, которое затем использовать в proxy_path. Все работает! Пример использования:

upstream example {
  server  www.host.local;
}


location = /api/example/ {
  rewrite  ^/api/example(/.*) $1 break;
  access_log  /var/log/nginx/example.access.log main;
  error_log   /var/log/nginx/example.error.log  debug;
  proxy_set_header        Host  dns-name.domain.ru;
  proxy_pass              http://example/$request_uri;
}

В данном примере запросы вида http://nginx_site/api/example/something проксируются на хост dns-name.domain.ru с использованием hosts записи www.host.local. Проксированный урл запроса после обработки будет выглядеть так: http://dns-name.domain.ru/something.