Producto QVD 4.2 Virtual Deckard
Equipo QVD Docs <documentation@theqvd.com>
Aviso legal

Introducción

Esta guía explica el funcionamiento de USBIP en QVD 4.2. Esta funcionalidad solo está disponible en sistemas Linux.

1. Funcionalidad del cliente

1.1. Requisitos

  • Kernel con soporte USBIP habilitado

  • Módulo usbip_host disponible y cargado

  • Herramienta auxiliar qvd-client-slaveclient-usbip-aux instalada con permisos setuid

No hay requisitos especiales para el funcionamiento del cliente de QVD. La funcionalidad requerida está presente en kernels de Linux recientes y debería estar disponible en todas las distribuciones comunes.

1.2. Consideraciones de seguridad

La funcionalidad de USBIP solo está disponible a aplicaciones con acceso de root, así que es necesaria una herramienta auxiliar, qvd-client-slaveclient-usbip-aux con permisos de setuid para realizar las tareas requeridas.

Se recomienda precaución al conectar dispositivos de almacenamiento por USBIP, ya que esto da acceso completo a la máquina virtual al dispositivo, incluyendo la habilidad de modificar o eliminar cualquier información que contenga.

La herramienta qvd-client-slaveclient-usbip-aux se instala con permisos setuid por defecto. Carga el módulo usbip_host automáticamente y configura la compartición de dispositivos USB.

1.3. Configuración

El cliente muestra una lista de dispositivos USB y escribe las selecciones al archivo de configuración. En la mayoría de los casos no hace falta hacer modificaciones manuales.

La lista de dispositivos a compartir se escribe en el parámetro client.usb.share_list. El formato es fabricante:producto@serie. Por ejemplo, 0bda:58c2@1234 es una webcam de Realtek Semiconductor con el número de serie 1234. Múltiples dispositivos se separan con comas.

2. Funcionalidad del Servidor

2.1. Requisitos

  • Kernel con parches de QVD USBIP

  • Módulo vhci_hcd cargado.

  • Activar el uso de hubs VHCI en la configuración.

2.2. Parches de USBIP

La funcionalidad estándar de USBIP presente en el kernel no es suficiente para soportar la compartición de dispositivos con contenedores. Para facilitar esto, Qindel ha desarrollado un conjunto de parches del kernel. Los paquetes proporcionados en el repositorio de QVD ya vienen con ellos incluidos.

Los parches tienen el efecto de crear múltiples hubs virtuales, asignando un hub a un contenedor. Esto proporciona un grado de seguridad y aislamiento de posibles interferencias por parte de otros contenedores.

La presencia de un kernel con los parches puede ser verificada mirando en /sys/bus/platform/drivers/vhci_hcd. El directorio debería contener múltiples symlinks con nombres de vhci_hcd.NUMERO. Cada uno de estos será asignado a un contenedor. El número de hubs limita el número de contenedores que pueden usar dispositivos de USBIP a la vez. Si el kernel no incluye el parche, solo aparecerá vhci_hcd.0 en la lista. Si el directorio */sys/bus/platform/drivers/vhci_hcd no existe, el módulo vhci_hcd no está cargado.

2.3. Monitor de dispositivos

Cuando un dispositivo es conectado por USBIP, se conecta al servidor físico. Para que solo el contenedor correcto tenga acceso al dispositivo, qvd-hkd monitoriza los eventos de udev, determina que contenedor ha conectado el dispositivo y ajusta los permisos del grupo de cgroups correspondiente. La operación inversa se hace al desconectar el dispositivo.

2.4. Configuración de AppArmor

LXC usa AppArmor para aislar contenedores. En su configuración por defecto, AppArmor impide el acceso a /sys/devices/system/platform. QVD viene con una configuración modificada de AppArmor que permite este acceso.

2.5. Consideraciones de seguridad

En un entorno de contenedores, hay un único kernel corriendo en el servidor, que es compartido entre todos ellos. Esto significa que cuando un dispositivo USB es conectado por un usuario, el dispositivo es efectivamente conectado al servidor en sí.

QVD toma precauciones para aislar contenedores uno del otro todo lo posible. Los dispositivos solo pueden ser usados por el contenedor al que fueron conectados, lo que impide que otro contenedor obtenga acceso incluso si su usuario tiene acceso de root. No obstante, son necesarias algunas precauciones.

Es crucial el evitar cualquier software en el servidor físico que automáticamente monta o examina dispositivos de bloque. Este tipo de software puede interferir con la funcionalidad de compartir dispositivos, causar corrupción en los dispositivos conectados, y podría ser un problema de seguridad.

Conectar cualquier tipo de dispositivo USB acarrea cierto riesgo para el servidor, ya que podría permitir a un usuario malicioso explotar una vulnerabilidad del kernel. Los dispositivos que contienen sistemas de archivos son de particular importancia, ya que un sistema de archivos especialmente modificado podría usarse para atacar el kernel del servidor. En operación normal, esto es mitigado no permitiendo que los usuarios tengan acceso de root en sus contenedores, lo que impide montar sistemas de archivos.

2.6. Instalación en Ubuntu

apt-get install qvd-client-slaveclient-usbip linux-image-extra-$(uname -r)
qa4 config set key=vm.lxc.use_vhci_hubs,value=1,tenant_id=-1
echo "vhci_hcd" > /etc/modules-load.d/qvd.conf

2.7. Instalación en CentOS

yum install qvd-client-slaveclient-usbip kernel-4.15.0+
qa4 config set key=vm.lxc.use_vhci_hubs,value=1,tenant_id=-1
echo "vhci_hcd" > /etc/modules-load.d/qvd-usbip.conf

3. Imagen

3.1. Requisitos

QVD-VMA incluye todo lo necesario, pero ajustes menores podrían ser necesarios en algunos casos.

3.2. Creación de dispositivos

Dentro de un contenedor, el entorno no es exactamente idéntico al de una distribución de Linux. Normalmente, udev y el kernel funcionan cooperativamente — el kernel crea dispositivos en sistemas de archivos devtmpfs y udev pone permisos, crea symlinks e invoca programas auxiliares.

En un contenedor de QVD, /dev es un sistema tmpfs, en vez de devtmpfs. Esto significa que los dispositivos no son creados automáticamente, y no aparecen en contenedores, aunque si lo hagan en el host.

QVD-VMA instala un script llamado qvd-create-device que es llamado desde udev y que se hace cargo de crear dispositivos. Para que el usuario tenga acceso al dispositivo recién creado, establece una ACL sobre el dispositivo. Este comportamiento es controlado con el ajuste createdevice.acl.enable. La ACL se aplica a los usuarios que pertenecen al grupo createdevice.acl.group y establece los permisos que se encuentran en createdevice.acl.permissions.

Para que esto funcione correctamente, el usuario debe pertenecer al grupo createdevice.acl.group. Esto puede hacerse asegurándose de que vma.user.default.groups lo incluye en su lista.

Ejemplo de configuración:

# Cuando VMA crea una cuenta de usuario, se agrega al grupo de qvduser (este grupo debe existir en la imagen)
vma.user.default.groups=qvduser

# Activar el uso de ACLs
createdevice.acl.enable=1

# Agregar una ACL para los usuarios del grupo qvduser
createdevice.acl.group=qvduser

# Permitir lectura y escritura a los dispositivos compartidos para miembros del grupo qvduser
createdevice.acl.permissions=rw