Product SiteDocumentation Site

Глава 61. Управление доступом в виртуальной инфраструктуре

Права пользователя могут управляться с помощью правил polkit.
В каталоге /usr/share/polkit-1/actions/ имеются два файла с описанием возможных действий для работы с ВМ, предоставленные разработчиками libvirt:
  • файл org.libvirt.unix.policy описывает мониторинг ВМ и управление ими;
  • в файле org.libvirt.api.policy перечислены конкретные действия (остановка, перезапуск и т. д.), которые возможны, если предыдущая проверка пройдена.
Перечисление конкретных свойств с комментариями доступно в файле /usr/share/polkit-1/actions/org.libvirt.api.policy.
В libvirt названия объектов и разрешений отображаются в имена polkit действий, по схеме:
org.libvirt.api.$объект.$разрешение
Например, разрешение search-storage-vols на объекте storage_pool отображено к действию polkit:
org.libvirt.api.storage-pool.search-storage-vols
Чтобы определить правила авторизации, polkit должен однозначно определить объект. Libvirt предоставляет ряд атрибутов для определения объектов при выполнении проверки прав доступа. Набор атрибутов изменяется в зависимости от типа объекта.
Пример тонкой настройки. Необходимо разрешить пользователю test (должен быть в группе vmusers) действия только с ВМ alt-server. Для этого необходимо выполнить следующие действия:
  1. Раскомментировать в файле /etc/libvirt/libvirtd.conf строку:
    access_drivers = [ "polkit" ]
    
  2. Перезапустить libvirt:
    # systemctl restart libvirtd
    
  3. Создать файл /etc/polkit-1/rules.d/100-libvirt-acl.rules (имя произвольно) следующего вида:
    polkit.addRule(function(action, subject) {
      if (action.id == "org.libvirt.unix.manage" &&
          subject.user == "test") {
          return polkit.Result.YES;
      }
    });
    
    polkit.addRule(function(action, subject) {
    // разрешить пользователю test действия с доменом "alt-server"
    if (action.id.indexOf("org.libvirt.api.domain.") == 0  &&
       subject.user == "test")
        {
            if (action.lookup("domain_name") == 'alt-server')
            {
                return polkit.Result.YES;
            }
            else
            {
                return polkit.Result.NO;
            }
        }
    else {
    // разрешить пользователю test действия с
    //подключениями, хранилищем и прочим
            if (action.id.indexOf("org.libvirt.api.") == 0 &&
            subject.user == "test")
            {
                polkit.log("org.libvirt.api.Yes");
                return polkit.Result.YES;
            }
            else
            {
                return polkit.Result.NO;
            }
        }
    })
    
  4. Перелогиниться.
  5. Проверить видимость машины alt-server, выполнив команду (от пользователя test):
    $ virsh --connect qemu:///system list --all
     ID   Имя          Состояние
    ------------------------------
     4    alt-server   работает
    
В результате выполненных действий пользователю test видна только машина alt-server видна.
 Права можно настраивать более тонко, например, разрешив пользователю test запускать ВМ, но запретить ему все остальные действия с ней, для этого надо разрешить действие org.libvirt.api.domain.start:
polkit.addRule(function(action, subject)
{
    // разрешить пользователю test только запускать ВМ в
    // домене "alt-server"
    if (action.id. == "org.libvirt.api.domain.start") &&
    subject.user == "test")
    {
        if (action.lookup("domain_name") == 'alt-server')
        {
           return polkit.Result.YES;
        }
        else
        {
            return polkit.Result.NO;
        }
    }
});
Предоставить право запускать ВМ, только пользователям группы wheel:
if (action.id == "org.libvirt.api.domain.start")
{
    if (subject.isInGroup("wheel"))
    {
        return polkit.Result.YES;
    }
    else
    {
        return polkit.Result.NO;
    }
};
Предоставить право останавливать ВМ, только пользователям группы wheel:
if (action.id == "org.libvirt.api.domain.stop")
{
    if (subject.isInGroup("wheel"))
    {
        return polkit.Result.YES;
    }
    else
    {
        return polkit.Result.NO;
    }
};
Можно также вести файл журнала, используя правила polkit. Например, делать запись в журнал при старте ВМ:
if (action.id.match("org.libvirt.api.domain.start"))
{
    polkit.log("action=" + action);
    polkit.log("subject=" + subject);
    return polkit.Result.YES;
}
Запись в журнал при останове ВМ:
if (action.id.match("org.libvirt.api.domain.stop"))
{
    polkit.log("action=" + action);
    polkit.log("subject=" + subject);
    return polkit.Result.YES;
}