Журнал LinuxFormat - перейти на главную

LXF112:DrBrown3

Материал из Linuxformat
Версия от 15:14, 29 ноября 2009; Crazy Rebel (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Наследить для аудита

Sudo и auditctl Вооружившись Fedora 9 и насушив сухарей, рассмотрим пару способов записать действия системного администратора.

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

Первый подход – запретить вход в систему от имени суперпользователя-root, сделав так, чтобы все действия с привилегиями администратора выполнялись через команду sudo. Если sudo соответствующим образом настроена, то все команды, выполняемые от имени root, будет записываться в журнальный файл, обычно /var/log/secure.

Чтобы избежать вольготного доступа кому ни попадя, ограничим использование sudo членами группы wheel. Итак, для начала настроим sudo так, чтобы члены группы wheel могли запустить любую команду с правами root. Соответствующая строка в файле sudoers будет выглядеть так:

%wheel ALL=(ALL) ALL

Возможно, эта строка уже там, и ее надо просто раскомментировать. Затем занесем в группу wheel хотя бы одного пользователя. Я добавил пользователя chris в нее таким образом:

# usermod -G wheel chris

Теперь я могу войти в систему как пользователь chris и выполнять отдельные команды с привилегиями root с помощью sudo таким образом:

$ sudo /usr/sbin/useradd ellie
[sudo] password for chris:

В этом примере я создаю нового пользователя. Пароль, который у меня запрашивается – мой собственный, а не пароль root.

Убедившись, что это работает (но не раньше!), можете запретить непосредственный вход в систему под пользователем root, заблокировав его пароль:

$ sudo passwd -l root
Locking password for user root.
passwd: Success

Теперь пользователю root в систему не войти. Нельзя даже воспользоваться командой su для работы от имени root: все действия придется выполнять с помощью sudo. (В Ubuntu этот механизм установлен по умолчанию.) При всей нудности, тут есть и ощутимые преимущества. Во-первых, вы всем объявляете: «Я буду работать от имени root». Во-вторых, число ваших покушений на команды с привилегиями root сводится к минимуму. В-третьих, sudo зафиксирует в файле журнала все выполняемые команды. Пусть, например, мне нужно изменить настройки Apache. Это можно сделать так:

$ sudo vi /etc/httpd/conf/httpd.conf

В файл журнала /var/log/secure запишутся следующие строки:

Aug 18 11:51:54 fedora9 sudo: chris : TTY=pts/2 ; PWD=/etc/
httpd/conf ; USER=root ; COMMAND=/bin/vi /etc/httpd/conf/
httpd.conf

Итак, теперь мы знаем, кто и когда влез в файл httpd.conf и с какого терминала он зашел в систему.

Если вам нужен более тонкий контроль над процессом аудита, возможно, вы захотите поэкспериментировать с системой аудита, встроенной в ядро. С ее помощью можно наблюдать за любым файлом в системе и журналировать для него все операции чтения, записи, выполнения или изменения прав доступа. Можно отслеживать все системные вызовы указанного процесса или пользователя или, например, записывать каждую операцию open(), завершившуюся с ошибкой. А можно отслеживать неправомерное поведение пользователей или собирать доказательства нарушений политики безопасности.

Любишь одно, полюби и другое

Предположим, мы заметили, что кто-то сканирует порты компьютеров локальной сети. У нас установлена утилита сканирования портов Nmap; вопрос в том, использует ли ее кто-нибудь. Командой auditctl мы просим ядро отслеживать любые попытки запустить Nmap таким образом:

# auditctl -w /usr/bin/nmap -p x -k port-scan

Проанализируем команду. Аргументы -w /usr/bin/nmap определяют файл – объект наблюдения. Здесь нельзя использовать шаблоны: только обычные имена файлов. Аргументы -p x определяют действие, которое надо отследить – некая комбинация из r (чтение), w (запись), x (исполнение) или a (изменение атрибута). Наконец, аргументы -k port-scan задают ключ для фильтрации (произвольная строка): он будет добавлен к записи в журнале, чтобы запись можно было найти командой ausearch или, конечно, grep.

Далее мы проверяем файл журнала, отыскивая там записи, содержащие наше ключевое слово port-scan:

# ausearch -k port-scan
----
time->Mon Aug 18 21:15:42 2008
 type=PATH msg=audit(1219072542.201:117): item=1 name=(null)
 inode=354635 dev=fd:00 mode=0100755 ouid=0 ogid=0
 rdev=00:00 obj=system_u:object_r:ld_so_t:s0
 type=PATH msg=audit(1219072542.201:117): item=0 name=”/usr/
 bin/nmap” inode=33539 dev=fd:00 mode=0100755 ouid=0 ogid=0
 rdev=00:00 obj=system_u:object_r:traceroute_exec_t:s0
 type=CWD msg=audit(1219072542.201:117): cwd=”/home/ellie”
 type=EXECVE msg=audit(1219072542.201:117): argc=2
 a0=”nmap” a1=”192.168.0.1-20”
 type=SYSCALL msg=audit(1219072542.201:117): arch=40000003
 syscall=11 success=yes exit=0 a0=83096e0 a1=83079d8
 a2=830fd48 a3=0 items=2 ppid=2766 pid=2790 auid=0 uid=501
 gid=501 euid=501 suid=501 fsuid=501 egid=501 sgid=501
 fsgid=501 tty=pts2 ses=10 comm=”nmap” exe=”/usr/bin/nmap”
 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
 key=”port-scan”

Весь предыдущий результат был получен при единственном запуске Nmap. Посмотрев внимательно, вы увидите, что пользователь с идентификатором 501 запустил команду nmap 192.168.0.1-20 в 9.15 вечера в понедельник 18 августа. Проверка пользователя с идентификатором 501 в файле паролей выявляет нарушителя: это ellie, шалопай, учетную запись которого мы создали ранее на нашем уроке.

Команда auditctl делает для аудита то же самое, что и команда iptables для пакетного фильтра – она загружает правила в ядро. Ее синтаксис задает определенный язык правил аудита, точно так же, как синтаксис iptables определяет язык для правил фильтрации пакетов. Чтобы посмотреть на чуть более сложный пример, создадим правило аудита, которое запишет в файл журнала все неудачные попытки открыть файл для пользователя ellie. Правило может выглядеть так:

 # auditctl -a exit,always -S open -F uid=501 -F success=0

Снова разберемся с ним по частям. Мы добавляем (-a) правило к списку exit системного вызова. Данный список просматривается при возврате из системного вызова: с его помощью ядро определяет, нужно ли создавать событие аудита. Для аудита мы выбираем системный вызов open (он используется программой, чтобы получить доступ к данным в файле.) Мы отслеживаем только те события для пользователя с идентификатором 501 (учетная запись ellie), для которых системные вызовы завершились неудачно. Вместо идентификатора пользователя можно было использовать другие критерии – реальные или эффективные идентификаторы пользователя и группы, код выхода системного вызова, индексный дескриптор файла, к которому производится доступ, идентификатор процесса и др.

Чуть позже можно просмотреть содержимое файла журнала аудита, попросив команду aureport показать нам все события открытия файла, завершившиеся с ошибкой:

 #aureport -f
 ...
 14. 19/08/08 18:47:58 /etc/passwd 5 no /bin/cp 0 310
 ...

Я удалил из результата множество строк, оставив только те, что нам интересны. 19 августа в 6.47 вечера кто-то попытался открыть файл /etc/passwd командой /bin/cp, и операция завершилась неудачно. В конце строки мы видим идентификатор события (310), представляющий собой индекс в файле журнала аудита. Используйте аргумент команды ausearch, чтобы забраться поглубже:

# ausearch -a 310
time->Tue Aug 19 18:47:58 2008
type=PATH msg=audit(1219168078.990:310): item=0 name=”/etc/
passwd” inode=256011 dev=fd:00 mode=0100644 ouid=0 ogid=0
rdev=00:00 obj=system_u:object_r:etc_t:s0
type=CWD msg=audit(1219168078.990:310): cwd=”/home/ellie”
type=SYSCALL msg=audit(1219168078.990:310): arch=40000003
   syscall=5 success=no exit=-13 a0=bfd559d8 a1=8201 a2=0
   a3=8201 items=1 ppid=4954 pid=4978 auid=0 uid=501 gid=501
   euid=501 suid=501 fsuid=501 egid=501 sgid=501 fsgid=501
   tty=pts2 ses=33 comm=”cp” exe=”/bin/cp” subj=unconfined_u:
   unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)

Прошу извинить меня за столь сумбурный результат; но, вглядевшись, вы увидите время и идентификатор пользователя события. Опять ellie.

Правила аудита, предоставляемые auditctl, действуют только «здесь и сейчас» – они не сохранятся после перезагрузки. Чтобы сделать правила постоянными, поместите их в файл /etc/audit/audit.rules, считываемый во время старта системы. Правила в этом файле – просто параметры, которые будут переданы auditctl. Например, строка в файле audit.rules, соответствующая правилу, с которым мы работали раньше, выглядит таким образом:

-w /usr/bin/nmap -p x -k port-scan

Чтобы узнать больше о системе аудита в Linux, ознакомьтесь с разделами man для auditd, auditd.conf, auditctl, aureport и ausearch. Зайдите на сайт http://www.intersectalliance.com; утилита Snare предоставляет графический интерфейс для построения наборов правил аудита и просмотра результатов. LXF

В таблице ниже показаны основные компоненты системы аудита.

Компонент Описание
Ядро Ядро генерирует события аудита в соответствии с заданным набором правил.
auditctl Пользовательская программа загружает правила поиска событий в ядро. В сущности, это похоже на iptables, которые загружают правила фильтрации пакетов в ядро. Во время загрузки скрипт запуска демона auditd запускает

auditctl, чтобы загрузить исходный набор правил из файла /etc/audit/audit.rules.

auditd Этот демон захватывает выходной поток событий аудита из ядра и записывает их в файл журнала, а также может выполнять «ротацию» файлов журнала. Файл конфигурации демона – /etc/audit/auditd.conf.
aureport Утилита, используемая для создания отчетов из файлов журнала аудита в формате, воспринимаемом человеком. У нее масса флагов, задающих тип отслеживаемых событий и временные интервалы.
ausearch Утилита, отображающая подробные записи о событиях. У нее есть множество опций для выбора интересующих событий.

LXF112 49 1.jpg

Система аудита ядра фиксирует события в соответствии с правилами, определенными командой auditctl.

Лучше перебдеть

Другой способ ограничить использование sudo группой wheel – тщательная настройка группывладельца и прав на исполнение исполняемого файла sudo таким образом:

 # chown root:wheel /usr/bin/sudo
 # chmod 4110 /usr/bin/sudo
 # ls -l /usr/bin/sudo
 ---s--x--- 2 root wheel 148836 2008-03-31 15:13 /usr/bin/sudo

Обратите внимание на необычный режим доступа 4110. Программа выполняет setuid to root и разрешена пользователю root и членам группы wheel. Это гораздо более сильное ограничение доступа, чем строка

%wheel ALL=(ALL) ALL

в файле sudoers, так как совершенно запрещает sudo для повышения привилегий пользователей, не являющихся членами группы wheel.

Это не для дома!

Не блокируйте учетную запись root, не будучи абсолютно уверены, что есть хотя бы один пользователь, которому разрешено использовать sudo для запуска команд с привилегиями root, или что вы способны произвести реанимацию. Не мешает также иметь под рукой «огнетушитель» и знать, например, как загрузиться с Live CD.

Если бы да кабы

Вдруг бы юристы применили накопленную мудрость к языку C? Конечно, получился бы LEGOL, но этот был бы совсем другой язык. Например, выражение на языке C

int i = 1;

преобразуется в LEGOL как «Сим утвердить и признать всеми присутствующими, что вновь созданный объект здесь и далее будет назван (и для ссылки на него будет использоваться) ‘i’ в рамках, определенных выбранным воплощением ранее представленного патента на пространство имен, оформленного ссылкой, а ‘i’ далее будет типа, объявленного и признанного как целый, и ему напрямую без помех и препятствий будет предоставлено и присвоено значение 1 (ОДИН), и оно будет хранить это значение до тех пор, пока какое-то другое значение в юрисдикции Акта Безопасности Типов не будет предоставлено и присвоено ему».

Следующий пример переведите на LEGOL сами.

 x += *p++;

А вот еще одна тревожная мысль. Что было бы, если бы Бьерн Страуструп [Bjarne Stroustrup] решил начать с COBOL, а не с C? Мы бы сейчас писали на POSTFIX INCREMENT COBOL BY ONE. И если вы согласны с тем, что C# – на самом деле C++++, программисты .NET, наверное, предпочитали бы POSTFIX INCREMENT POSTFIX INCREMENT COBOL BY ONE BY ONE.

Подробности можно найти в книге Стена Келли-Бутла [Stan Kelly-Bootle] «The Computer Contradictionary [Противоречия компьютера]».

Персональные инструменты
купить
подписаться
Яндекс.Метрика