Шифрование образов дисков виртуальных машин

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

Хотя шифрование дисков не защитит запущенные виртуальные машины, администратор может зашифровать образы дисков выключенных виртуальных машин и требовать пароль или ключ для запуска виртуальной машины, использующей эти диски. Без шифрования дисков можно легко извлечь данные из файла образа диска.

Qemu поддерживает несколько типов образов дисков. "Родным" и наиболее гибким типом является qcow2, который поддерживает сжатие, шифрование и создание снапшотов виртуальных машин. Наиболее простым - raw, который проще всего конвертировать в другие типы для разных средств виртуализации (VirtualBox, VMware, Hyper-V). Для того, чтобы не привязываться к конкретному типу образов, используем стандартные средства шифрования для Linux-систем (LUKS).

Шифрование всего раздела жесткого диска, на котором хранятся файлы образов дисков виртуальных машин, производится с использованием драйвера уровня ядра dm-crypt и утилиты cryptsetup для шифрования обычных разделов диска или логических разделов LVM. Хранилище файлов образов дисков LVM предоставляет большую гибкость в управлении (например изменение размера раздела), чем использование простых разделов диска.

В качестве операционной системы под Qemu+KVM будем использовать RHEL-Server-6.2 x86_64. Для создания зашифрованного логического раздела требуется:

  1. установить на хосте пакет cryptsetup-luks;

  2. убедиться, что в системе есть минимум 10Гб свободного пространства;

  3. создать новый логический раздел, например:

    # lvcreate -L 10G -n guest01-crypt VolGroup

    Logical volume "guest01-crypt" created

  4. зашифровать созданный раздел, используя команду cryptsetup luksFormat. Эта команда предложит ввести пароль, который будет использоваться для расшифровки раздела:

    # cryptsetup luksFormat /dev/VolGroup/guest01-crypt

    WARNING!

    ========

    This will overwrite data on /dev/VolGroup/guest01-crypt irrevocably.

    Are you sure? (Type uppercase yes): YES

    Enter LUKS passphrase:

    Verify passphrase:

    Command successful.

  5. используя команду cryptsetup luksDump, проверить, что раздел успешно зашифрован:

    # cryptsetup luksDump /dev/VolGroup/guest01-crypt

  6. для открытия раздела и создания в нем нужного устройства требуется использовать команду cryptsetup luksOpen:

    # cryptsetup luksOpen /dev/VolGroup/guest01-crypt guest01-img

    Enter LUKS passphrase for /dev/VolGroup/guest01-crypt:

    key slot 0 unlocked.

    Command successful

  7. устройство можно использовать. Для получения полной информации об устройстве можно использовать команду dmsetup info:

    # dmsetup info guest01-img

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

Перенос существующего образа диска (rhel6) в новое зашифрованное устройство (/dev/VolGroup/guest01-crypt) можно произвести следующим образом:

  1. выключите виртуальную машину;

    # virsh shutdown rhel6

  2. проверьте, что машина перестала функционировать:

    # virsh list

    Id Name State

    ----------------------------------

  3. проверьте текущее местоположение образа диска. Для этого можно использовать команду virsh dumpxml:

    # virsh dumpxml rhel6

    .......

    <devices>

      <emulator>/usr/libexec/qemu-kvm</emulator>

      <disk type=’file’ device=’disk’>

        <driver name=’qemu’ type='qcow2' cache=’none’ />

        <source file=’/var/lib/libvirt/images/rhel6.img’ />

        <target dev=’hda’ bus=’ide’/>

      </disk>

    .......

  4. используйте команду qemu-img info для получения информации о формате и размере файла;

    # qemu-img info /var/lib/libvirt/images/rhel6.img

    image: /var/lib/libvirt/images/rhel6.img

    file format: qcow2

    virtual size: 10G (10737418240 bytes)

    disk size: 10G

  5. перенесите копию диска в созданное устройство, используя утилиту dd:

    # dd if=/var/lib/libvirt/images/rhel6.img  of=/dev/mapper/guest01-img bs=4k

    2621440+0 records in

    2621440+0 records out

    10737418240 bytes (11 GB) copied, 159.602 seconds, 67.1 MB/s

  6. используя команду virsh edit измените конфигурацию виртуальной машины в соответствии с измененным местоположением образа диска:

    <devices>

      <emulator>/usr/libexec/qemu-kvm</emulator>

      - <disk type=’file’ device=’disk’>

      + <disk type=’block’ device=’disk’>

      <driver name=’qemu’ type='qcow2' cache=’none’ />

      - <source file=’/var/lib/libvirt/images/rhel6.img’ />

      + <source dev=’/dev/mapper/guest01-img’ />

      <target dev=’hda’ bus=’ide’ />

      </disk>

    </devices>
  7. Запустите виртуальную машину командой virsh start:

    # virsh start rhel6

    Domain rhel6 started

При создании новой виртуальной машины, которая должна использовать защищенное хранилище с образами дисков, требуется указать libvirt, где будет находиться образ диска. Например, при использовании команды virt-install, потребуется сначала открыть предварительно созданный раздел командой cryptsetup luksOpen, после чего создавать виртуальную машину:

# virt-install --name guest01 --ram 512 --accelerate \

--location /mnt/rhel6-u2/ \

--extra-args "console=tty0 console=ttyS0,115200n8" \

--os-type linux --os-variant rhel5 \

--disk path=/dev/mapper/guest01-img,bus=ide,device=disk \

--disk path=/root/RHEL6.2-Server-x86_64-DVD.iso,bus=ide,device=cdrom \

--network network:default --nographics

Starting install...

...

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

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

  1. выключить виртуальную машину командой virsh shutdown:

    # virsh shutdown rhel6

    Domain rhel6 is being shutdown

  2. проверить, что не осталось работающих виртуальных машин, использующих образы дисков, которые будут закрыты:

    # virsh list

    Id Name State

    ----------------------------------

  3. закрыть зашифрованное устройство:

    # cryptsetup luksClose guest01-img

120