Отслеживание гостевых систем KVM с помощью libvirt и подсистемы аудита Linux Отслеживание и фильтрация событий, связанных с гостевыми системами и хост-системой, в виртуализированном окружении Марчелло Х. Черри, разработчик ПО, IBM Дата: 13.12.2012 http://www.ibm.com/developerworks/ru/library/l-kvm-libvirt-audit/ Описание: libvirt – это полезный инструмент для управления виртуализированными средами, развернутыми на Linux-системах. Отслеживание событий, произошедших на хост-системе во время исполнения libvirt, зачастую требуется для мониторинга, оценки совместимости, анализа причин сбоев и других задач. В этой статье рассказывается, как использовать подсистему аудита, имеющуюся в Linux, для отслеживания операций, выполняемых libvirt, и как связать события libvirt с другими событиями, происходившими на хост-системе, чтобы получить цельное и всестороннее представление об изменениях, произошедших из-за работы libvirt. Обзор Инструмент libvirt широко применяется для управления виртуализированными средами в Linux®. Он предоставляет различные функции, включая управление жизненным циклом гостевых систем, выделение ресурсов и управление ими с помощью cgroups, а также усовершенствование системы безопасности с помощью SELinux и другие возможности. Все эти операции реализуются libvirt, который обеспечивает контроль использования ресурсов хост-системы, выделенных гостевым системам или наоборот изъятых у них. Начиная с версии 0.9.0 libvirt может общаться с подсистемой аудита, имеющейся в Linux хост-системе, чтобы создавать записи об определенных операциях. Эта функциональность имеет большое значение, так как позволяет системным администраторам, аудиторам или пользователям других приложений получить доступ к подробной истории изменений, произошедших в виртуализированной среде, включая операции, связанные с жизненным циклом гостевой системы, и изменения в распределении ресурсов хоста, выделенных гостевым системам. Подсистема аудита в Linux способна обрабатывать события различных типов из множества источников, а не только события, связанные с виртуализацией, которые генерирует libvirt. Эта подсистема часто используется для отслеживания изменений в файлах, отказов в доступе со стороны SELinux или AppAmor и системных вызовов. Все эти события могут содержать полезную информацию для аудита виртуальных машин. Например, доступ к ресурсу, выделенному гостевой системе, может быть запрещен политикой SELinux, что приведет к созданию AVC-записи (AVC - Access Vector Cache) об отказе в доступе. Хотя это событие и не генерируется libvirt, но оно связано с гостевой системой. Аналогичным способом многие события могут быть связаны с гостевой системой, и среди них "аномальные" события, генерируемые ядром или программами, расположенными в пользовательском пространстве. В следующих разделах мы кратко рассмотрим, как работает система аудита и как libvirt взаимодействует с ней, а также извлечение из журналов аудита информации, относящейся к гостевым системам. Основные принципы аудита Ядро Linux генерирует большую часть событий, отслеживаемых с помощью аудита, например, события системных вызовов, события мониторинга файлов и события системы безопасности. Но и пользовательские приложения также могут создавать события. Центральным компонентом системы аудита в Linux является ядро. Все события, генерируемые другими компонентами, сначала отправляются в ядро. В ядре к каждому событию применяется набор правил, чтобы определить, можно ли проигнорировать это событие или нет. На рисунке 1 показаны компоненты, входящие в состав системы аудита в Linux. Рисунок 1. Компоненты системы аудита Правила аудита, хранящиеся в ядре, можно изменить с помощью команды auditctl. Некоторые приложения со специальными возможностями, такие как демон libvirt, рассматриваются как "доверенные" приложения и могут посылать события аудита в ядро. После применения правил ядро посылает события демону аудита. Этот демон (auditd) сохраняет записи о событиях на жесткий диск и потенциально может запускать специальные действия с помощью демона auditspd. Другими важными компонентами являются инструменты пользовательского пространства (ausearch, aureport, aulast и auvirt), используемые для обработки журналов аудита и представления информации, извлеченной из них, в более понятной форме. Инструмент auvirt специально разработан для представления событий, связанных с виртуализацией. Стоит отметить одно важное различие между событием аудита и записью аудита. Событие аудита – это действие, инициированное пользователем или каким-либо приложением, которое можно отследить с помощью аудита, например, открытие файла. Запись аудита содержит информацию об одном из аспектов данного события, поэтому событие может породить одну или несколько записей в журнале аудита. Если вернуться к примеру с открытием файла, то это событие может создать запись с информацией о системном вызове и запись с информацией об открытом файле, как это показано в листинге 1. Листинг 1. Записи аудита для события открытия файла (для удобства чтения расставлены концы строк) Code: type=SYSCALL msg=audit(1328292445.908:40194): arch=c000003e syscall=2 success=yes exit=3 a0=7fffe3d2e85c a1=941 a2=1b6 a3=7fffe3d2c570 items=3 ppid=26377 pid=26677 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts8 ses=1 comm="touch" exe="/bin/touch" subj=unconfined_u:unconfined_r:unconfined_t:s0 key=(null) type=CWD msg=audit(1328292445.908:40194): cwd="/home/mhcerri" type=PATH msg=audit(1328292445.908:40194): item=0 name="/tmp/file" inode=1196 dev=fd:01 mode=0100775 ouid=500 ogid=501 rdev=00:00 obj=unconfined_u:object_r:user_tmp_t:s0 Отметим, что все записи имеют разные значения параметра type (тип) и во всех записях содержится один и тот же идентификатор события - строка "1328292445.908:40194". Первые два числа перед символом ":" - это временная метка события, до символа "." — текущее время в Unix®-системе в секундах, а после символа "." - количество миллисекунд. Третье число, приведенное после символа ":", используется для отображения сгенерированного серийного номера. Записи в этом формате, используемый в записях аудита, неудобно просматривать, и поэтому система аудита предлагает дополнительные инструменты, способные помочь при анализе записей журнала. libvirt и система аудита Программа libvirt в основном генерирует записи трёх типов, обладающих одним общим параметром — полем uuid (Universal Unique Identifier — универсальный уникальный идентификатор), которое идентифицирует конкретную гостевую систему в записях, созданных libvirt. Ниже перечислены три типа записей, используемых libvirt: -VIRT_CONTROL: создаётся на каждом этапе жизненного цикла виртуальной машины. Подобные записи генерируются при запуске или остановке виртуальной машины и содержат такие поля, как причина выполнения операции и имя гостевой системы. -VIRT_MACHINE_ID: генерируется, когда libvirt пытается присвоить гостевой системе идентификатор безопасности. При использовании QEMU вместе с sVirt в этой записи содержится идентификатор безопасности QEMU-процесса и защитные идентификаторы дисков, подключенных к гостевой системе. -VIRT_RESOURCE: генерируется, когда происходят изменения, связанные с ресурсами, выделенными гостевой системе, например, когда диск удаляется из гостевой системы или к ней подключается новое сетевое устройство. Утилита auvirt Утилита auvirt используется для поиска в журналах аудита записей, созданных libvirt, чтобы вывести список сеансов виртуальных машин. Также она выполняет поиск таких событий, как остановка хост-системы, отказы в доступе, связанных с гостевыми системами, и аномальные события, связанныя с QEMU-процессами. В листинге 2 приведен пример вывода auvirt. В первом поле выводится имя гостевой системы. Во втором поле выводится имя пользователя запустившего гостевую систему. А в третьем поле представлен временной интервал, в течение которого гостевая система функционировала. Отметим, что в листинге 2 один сеанс работы с гостевой системой Arch оказался неудачным (она не запустилась), а другой сеанс работы с этой системой продолжается до сих пор (время окончания не указано). Листинг 2. Результат работы auvirt Code: # auvirt Fedora root Tue Jan 24 16:28 - 16:28 (00:00) Fedora root Wed Jan 25 10:31 - 10:34 (00:02) CentOS root Wed Jan 25 10:34 - 13:50 (03:16) Fedora root Wed Jan 25 13:51 - 13:54 (00:03) Fedora root Wed Jan 25 13:54 - 13:55 (00:00) Arch root Wed Jan 25 13:55 - failed Arch root Wed Jan 25 13:56 Вывод информации можно ограничить определенным временным диапазоном, используя следующие опции: --start <дата> [<время>] : установить начало интересующего периода; --end <дата> [<время>] : установить конец интересующего периода. Если не указывать время, то по умолчанию инструмент использует "00:00:00" в качестве отправной временной метки и "23:59:59" в качестве конечной. Листинг 3. Фильтрация вывода auvirt по времени Code: # auvirt --start 01/25/2012 12:00:00 --end 01/25/2012 Fedora root Wed Jan 25 13:51 - 13:54 (00:03) Fedora root Wed Jan 25 13:54 - 13:55 (00:00) Arch root Wed Jan 25 13:55 - failed Arch root Wed Jan 25 13:56 Также можно выводить информацию, относящуюся только к одной гостевой системе. Нужная гостевая система может быть идентифицирована по ее имени или UUID. По умолчанию, инструмент auvirt не отображает значения UUID, чтобы облегчить восприятие информации, но значения UUID можно добавить к выводу, если воспользоваться опцией --show-uuid. Листинг 4. Фильтрация вывода auvirt по имени конкретной гостевой системы Code: # auvirt --vm Fedora Fedora root Tue Jan 24 16:28 - 16:28 (00:00) Fedora root Wed Jan 25 10:31 - 10:34 (00:02) Fedora root Wed Jan 25 13:51 - 13:54 (00:03) Fedora root Wed Jan 25 13:54 - 13:55 (00:00) # auvirt --show-uuid --uuid cabf9532-99f1-3756-930f-59e8f19d4144 Arch cabf9532-99f1-3756-930f-59e8f19d4144 root Wed Jan 25 13:55 - failed Arch cabf9532-99f1-3756-930f-59e8f19d4144 root Wed Jan 25 13:56 По умолчанию auvirt выводит информацию в сокращенной форме. Чтобы вывести все события, связанные с виртуализацией, необходимо указать опцию --all-events. С этой опцией auvirt будет показывать записи для каждого запуска и остановки системы, выделении ресурсов и связанных с этим событий. В листинге 5 представлен пример вывода auvirt при использовании --all-events (в листинге приведен сокращенный вариант вывода, а его полную версию можно найти в разделе "Материалы для скачивания"). Листинг 5. Подробная информация, представленная в выводе auvirt Code: # auvirt --vm CentOS --all-events down root Wed Jan 25 08:34 res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) cgroup allow major rw pty [...] avc CentOS root Wed Jan 25 10:34 relabelto denied libvirtd CentOS.img system_u:object_r:svirt_image_t:s0:c6,c883 [...] res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) disk start /var/lib/libvirt/images/CentOS.img res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) net start 52:54:00:DB:AE:B4 res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) mem start 1048576 res CentOS root Wed Jan 25 10:34 - 13:50 (03:16) vcpu start 1 start CentOS root Wed Jan 25 10:34 - 13:50 (03:16) [...] stop CentOS root Wed Jan 25 13:50 В первом поле указывается тип события, который может иметь следующие значения: start, stop, res, avc, anom или down (в случае остановки хост-системы). В записях о выделении ресурсов и AVC-записях находятся дополнительные поля с информацией. Например, в дополнительных полях записей о выделении ресурсов указываются: -в поле resource type указываются различные типы ресурсов, которые могут быть выделены гостевым системам, например, диски, виртуальные CPU, память и сетевые устройства. Кроме того, libvirt с cgroups можно настроить так, чтобы ограничить ресурсы, используемые каждой гостевой системой, и это тоже будет записываться в виде события, связанного с ресурсами. Для этого поля доступны следующие значения: vcpu, mem, disk, net и cgroup. -в поле reason указывается действие, которое привело к выделению ресурса. Например, гостевой системе при ее запуске может быть выделен жесткий диск (тогда значение этого поля будет равно start), а если жесткий диск был выделен в процессе работы, то используется значение attach. Для событий, связанных c сgroups в этом поле указывается, что доступ к ресурсу был разрешен (значение allow) или запрещен (значение deny). -в поле resource указывается описание ресурса, выделенного гостевой системе. Это может быть путь к дисковым ресурсам, количество мегабайт для памяти, MAC-адрес сетевого устройства или количество виртуальных процессоров. Для событий, относящихся к cgroups, значение этого поля состоит из трёх частей: типа, ACL-кода и описания ресурса. События, связанные с AVC и отображаемые в выводе auvirt, не относятся к случаям, когда указанной гостевой системе было отказано в доступе к определенным ресурсам. Наоборот, эти события описывают ситуацию, когда произошел отказ при попытке доступа к ресурсам гостевой системы со стороны другого процесса, запущенного в хост-системе. Для AVC-событий предусмотрены следующие дополнительные поля. -operation: - описание операции, в выполнении которой процессу было отказано, например, read, write, open, relabelto, relabelfrom; -operation result: результат данной операции, обычно значение этого поля равно denied (отказ); -program: имя исполняемого файла процесса, который пытался выполнить запрещенную операцию; -target: цель, на которую была направлена запрещенная операция, например, если процесс из хост-системы пытается получить доступ к файлу с образом диска гостевой системы, и этот запрос отклоняется SELinux, то в качестве значения поля target указывается имя файла с образом диска; -context: это поле добавляется для операций relabelto и relabelfrom для указания контекста безопасности, относящегося к события: целевой контекст (target) для операции relabelto и контекст источника (source) для операции relabelfrom. Доступ к необработанным данным Хотя auvirt предоставляет информацию в удобном для изучения формате, но она не обязательно содержит все сведения о событии из журнала аудита. Иногда эта дополнительная информация может оказаться полезной, и потребуется доступ к необработанным данным для получения подробных сведений. Поэтому у auvirt имеется опция --proof, которой можно воспользоваться, чтобы вывести идентификаторы событий, использовавшихся для генерации всех записей в выводе auvirt. Листинг 6. Использование опции --proof Code: # auvirt --vm Fedora -ts 01/23/2012 00:00 -te 01/23/2012 17:30 --proof Fedora root Mon Jan 23 17:02 - 17:27 (00:24) Proof: 1327345338.087:41631, 1327346831.548:41702 В листинге 6 представлен пример вывода auvirt c отображением start и stop-идентификаторов события, использовавшегося для создания записи. Используя эту информацию можно извлечь исходные записи из журнала аудита с помощью инструмента ausearch, как показано в листинге 7. Листинг 7. Использование ausearch для получения необработанных записей Code: # ausearch -a 41631 --start 01/23/2012 17:02:00 --end 01/23/2012 17:27:59 ---- time->Mon Jan 23 17:02:18 2012 type=VIRT_CONTROL msg=audit(1327345338.087:41631): user pid=2433 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:initrc_t:s0 msg='virt=kvm op=start reason=booted vm="Fedora" uuid=7bcae45c-c179-6cea-a185-c7abe50520c7: exe="/usr/sbin/libvirtd" hostname=? addr=? terminal=? res=success' В этом примере используется опция -a, которая ограничивает вывод записями с определенным серийным номером и опции —start и —end, которые работают аналогично подобным опциям в auvirt. Можно отметить, что необработанные записи содержат дополнительную информацию, например, поля reason, executable, name и pid. Заключение Из-за растущей популярности облачных вычислений виртуализация стала сегодня одной из ключевых технологий, поэтому крайне важно иметь чёткое понимание того, что происходит в виртуализированных средах. Кроме того, аудит может быть обязательным требованием для определенных секторов экономики, например, для финансового или государственного. В этой статье дан обзор инструментов аудита, которые могут оказаться полезными для фильтрации событий, связанных с виртуальными операциями хост-системы. С помощью этих инструментов можно получить более подробные сведения о функционировании гостевой системы, рассматривая события, произошедшие как на самой гостевой системе, так и события хост-системы, связанные с конкретной гостевой системой.