Назад | Перейти на главную страницу

Ограничить доступ к виртуальным машинам KVM для определенных пользователей

На моем сервере у меня есть виртуальная машина KVM под названием «карты2». Он был создан путем выполнения (от имени root):

# virt-install --connect qemu:///system --virt-type kvm --name cards2 --ram 2048 --disk /var/kvm/cards2.qcow,size=3 --vcpus=8 --cdrom /var/kvm/debian-8.5.0-amd64-netinst.iso --vnc --os-type linux --network network=default

У изображения есть разрешения:

# ls -l /var/kvm/cards2.qcow 
-rwxr-xr-x 1 libvirt-qemu libvirt-qemu 3221225472 Aug 17 18:49 /var/kvm/cards2.qcow

Однако я заметил, что любой пользователь с доступом SSH может получить доступ к виртуальной машине, выполнив:

virt-viewer --connect qemu+ssh://username@hostname.example.com/system vmname

(Обратите внимание, эта команда выполняется удаленно, а не на сервере. Это подключается к гипервизору с помощью URI подключения. qemu+ssh://username@hostname.example.com путем туннелирования через SSH)

Пользователь username является только членом username группа. Когда SSH-соединение с username счету список виртуальных машин оказывается пустым:

$ virsh list --all
 Id    Name                           State
----------------------------------------------------

И я также не могу подключиться с помощью сокета при выполнении следующих действий по SSH:

$ virsh --connect qemu:///system list --all
error: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied

Я также пробовал удалить разрешения для всех /usr/bin/vir* файлы для пользователей не в kvm группа:

# chown root:kvm /usr/bin/vir*
# chmod o-rx /usr/bin/vir*
# ls /usr/bin/vir* -l
-rwxr-x--- 1 root kvm  321120 Jul  1 04:46 /usr/bin/virsh
-rwxr-x--- 1 root kvm   32184 Dec  7  2013 /usr/bin/virt-alignment-scan
-rwxr-x--- 1 root kvm   28128 Dec  7  2013 /usr/bin/virt-cat
-rwxr-x--- 1 root kvm    9774 Sep 29  2014 /usr/bin/virt-clone
-rwxr-x--- 1 root kvm   10277 Sep 29  2014 /usr/bin/virt-convert
-rwxr-x--- 1 root kvm     806 Dec  7  2013 /usr/bin/virt-copy-in
-rwxr-x--- 1 root kvm     808 Dec  7  2013 /usr/bin/virt-copy-out
-rwxr-x--- 1 root kvm   54584 Dec  7  2013 /usr/bin/virt-df
-rwxr-x--- 1 root kvm   33312 Dec  7  2013 /usr/bin/virt-edit
-rwxr-x--- 1 root kvm   54536 Dec  7  2013 /usr/bin/virt-filesystems
-rwxr-x--- 1 root kvm   30112 Dec  7  2013 /usr/bin/virt-format
-rwxr-x--- 1 root kvm   14656 Jul  1 04:46 /usr/bin/virt-host-validate
-rwxr-x--- 1 root kvm    7944 Sep 29  2014 /usr/bin/virt-image
-rwxr-x--- 1 root kvm   44696 Dec  7  2013 /usr/bin/virt-inspector
-rwxr-x--- 1 root kvm   36992 Sep 29  2014 /usr/bin/virt-install
-rwxr-x--- 1 root kvm    5338 Dec  7  2013 /usr/bin/virt-list-filesystems
-rwxr-x--- 1 root kvm    6686 Dec  7  2013 /usr/bin/virt-list-partitions
-rwxr-x--- 1 root kvm   53816 Dec  7  2013 /usr/bin/virt-ls
-rwxr-x--- 1 root kvm   18641 Dec  7  2013 /usr/bin/virt-make-fs
-rwxr-x--- 1 root kvm    9600 Jul  1 04:46 /usr/bin/virt-pki-validate
-rwxr-x--- 1 root kvm   36264 Dec  7  2013 /usr/bin/virt-rescue
-rwxr-x--- 1 root kvm 1322488 Dec  7  2013 /usr/bin/virt-resize
-rwxr-x--- 1 root kvm 1231256 Dec  7  2013 /usr/bin/virt-sparsify
-rwxr-x--- 1 root kvm 1289592 Dec  7  2013 /usr/bin/virt-sysprep
-rwxr-x--- 1 root kvm    8949 Dec  7  2013 /usr/bin/virt-tar
-rwxr-x--- 1 root kvm     804 Dec  7  2013 /usr/bin/virt-tar-in
-rwxr-x--- 1 root kvm     806 Dec  7  2013 /usr/bin/virt-tar-out
-rwxr-x--- 1 root kvm      55 Jul 12  2012 /usr/bin/virtualenv
-rwxr-x--- 1 root kvm  132400 May 28  2012 /usr/bin/virt-viewer
-rwxr-x--- 1 root kvm   23886 Dec  7  2013 /usr/bin/virt-win-reg
-rwxr-x--- 1 root kvm    3531 Jul  1 04:46 /usr/bin/virt-xml-validate

И хотя теперь я не могу получить доступ ни к одной из этих команд через обычное соединение SSH, я все же могу вызвать виртуальную машину, выполнив virt-viewer удаленно (как указано выше) через туннель SSH.

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

Редактировать:

Вот что появляется у меня /var/log/libvirt/qemu/cards2.log при запуске виртуальной машины, если это дает какие-либо указания:

LC_ALL = C PATH = / usr / local / sbin: / usr / local / bin: / sbin: / bin: / usr / sbin: / usr / bin QEMU_AUDIO_DRV = none / usr / bin / kvm -S -M pc-1.1 -enable-kvm -m 2048 -smp 8, sockets = 8, cores = 1, thread = 1 -name cards2 -uuid 70905b35-9df3-71c9-d5e9-f804a2826055 -no-user-config -nodefaults -chardev socket, id = charmonitor, путь = / var / lib / libvirt / qemu / cards2.monitor, сервер, nowait -mon chardev = charmonitor, id = monitor, mode = control -rtc base = utc -no-shutdown -device piix3-usb-uhci, id = usb, bus = pci.0, addr = 0x1.0x2 -drive file = / var / kvm / cards2.qcow, if = none, id = drive-ide0-0-0, format = raw -device ide-hd , bus = ide.0, unit = 0, drive = drive-ide0-0-0, id = ide0-0-0, bootindex = 1 -drive if = none, id = drive-ide0-1-0, readonly = on, format = raw -device ide-cd, bus = ide.1, unit = 0, drive = drive-ide0-1-0, id = ide0-1-0 -netdev tap, fd = 23, id = hostnet0 - устройство rtl8139, netdev = hostnet0, id = net0, mac = 52: 54: 00: c6: 14: 68, bus = pci.0, addr = 0x3 -chardev pty, id = charserial0 -device isa-serial, chardev = charserial0 , id = serial0 -vnc 127.0.0.1:3 -vga cirrus -device virtio-balloon-pci, id = balloon0 , шина = pci.0, адрес = 0x4

Изменить 2:

С другой стороны, это, похоже, проблема только для virt-viewer, а не для virsh.

Например, вот некоторые команды, выполняемые на удаленном клиенте:

$ virsh --connect qemu+ssh://unauthorized-user@server.com/system
error: failed to connect to the hypervisor
error: End of file while reading data: nc: unix connect failed: Permission denied: Input/output error

$ virsh --connect qemu+ssh://authorized-user@server.com/system
Welcome to virsh, the virtualization interactive terminal.

Type:  'help' for help with commands
       'quit' to quit

K Я понял. virt-viewer не взаимодействует с libvirtd - он подключается через ssh к хосту и настраивает туннель, чтобы разрешить доступ к виртуальным дисплеям ваших виртуальных машин на основе VNC (127.0.0.1:5903 в моем случае). Это сложно исправить, если не использовать брандмауэр VNC на 127.0.0.1. В противном случае обычные пользователи обычно могут свободно устанавливать TCP-соединения с localhost. Понятия не имею, как можно разрешить только root, возможно, есть способ.

Может быть, так поступает selinux?

Linux: Разрешить / ограничить разрешения на привязку IP-адресов пользователем

Так что проще всего было бы установить пароль VNC. Вы можете делать такие вещи, как ограничение пересылки и пересылки X11 в SSH, но это может быть не на 100% безопасным, а также может вызвать проблемы для root. И пользователи все еще могли получить доступ к 127.0.0.1/vnc после входа в систему.

Обновить

По словам Майка (другой ответ) и Майкла Хэмптона (комментарии), вы можете использовать TLS для связи с VNC, а не пароль, поэтому вы получите довольно приличную безопасность, если пароли вам не подходят. Я понятия не имел, что нужно им обоим.

http://wiki.libvirt.org/page/VNCTLSSetup

и

https://www.suse.com/documentation/sles11/book_kvm/data/sec_libvirt_connect_remote.html#sec_libvirt_connect_remote_tls

Вы пробовали использовать polkit для ограничения доступа пользователей? Я тоже хотел это сделать, поэтому получил такой результат:

  1. Назовите виртуальную машину как имя пользователя * vmname
  2. теперь в файле правил polkit отредактируйте правило, как показано ниже

    function myFunction(username, virtualmachine) {
        var arr = virtualmachine.split("*");
        if(arr[0]==username){
            return true;
        }
        else{
            return false;
        }
    }
    // Allow passwordless connection to qemu:///system
    polkit.addRule(function(action, subject) {
        if (action.id == "org.libvirt.unix.manage")
        {
            return polkit.Result.YES;
        }
    });
    // Give full access to 'vm'
    polkit.addRule(function(action, subject) {
        if (action.id.indexOf("org.libvirt.api.domain.") == 0 ) {
            if (action.lookup("connect_driver") == 'QEMU' &&  myFunction(subject.user, action.lookup("domain_name"))) {
                polkit.log("vm=" + action.lookup("domain_name") + "action =>"+myFunction(subject.user, action.lookup("domain_name")));
                polkit.log("subject=" + subject);
                polkit.log("ok");
                return polkit.Result.YES;
            } else {
                return polkit.Result.NO;
            }
        }
    });
    
  3. теперь только соответствующий пользователь сможет видеть только сам vm.

наслаждаться

Так как Ответ Райана выше сказано, что "virt-viewer не взаимодействует с libvirtd". libvirtd и VNC (к чему подключается virt-viewer) полностью отдельные методы аутентификации. VNC можно защитить с помощью

  • Аутентификация с одним паролем
  • SASL аутентификация
  • x509 сертификаты
  • Сертификаты комбинации и один из первых двух

Единые пароли

Если вы используете один пароль, это может быть глобальный пароль, хранящийся в вашем /etc/libvirt/qemu.conf файл или вы можете добавить пароль для виртуальной машины в конфигурацию виртуальной машины:

<graphics type='vnc' port='-1' autoport='yes' passwd='PASSWORD'/>

Учтите, что эти пароли должны храниться в виде обычного текста.

SASL аутентификация

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

x509 сертификаты

На самом деле это та часть, которая Я считаю прямо отвечает на вопрос (однако я его не тестировал). Благодаря этому вы можете ограничить, какой пользователь может подключаться к экземпляру VNC, аутентифицируясь с помощью сертификатов, хранящихся на сервере. Чтобы отозвать разрешения для определенного пользователя или группы, просто установите разрешения для общесистемного файла сертификата клиента так, чтобы этот пользователь не мог его прочитать. Вы также можете сгенерировать сертификаты для каждого пользователя и отозвать доступ.

К сожалению, это относительно сложно настроить. Это в первую очередь создание корневого ЦС на сервере, Создание сертификатов клиент / сервер x509, настройка сервера, настройка клиента и тестирование установки, а потом ограничение доступа.