Cómo dejar que los scripts de Linux detecten que se están ejecutando en máquinas virtuales

Publicado: 2022-06-27
Dos manos, una sosteniendo una pastilla roja y la otra una pastilla azul.
diy13/Shutterstock.com

Las máquinas virtuales se esfuerzan mucho por convencer a sus sistemas operativos de que se ejecutan en hardware físico. Entonces, ¿puede saber desde la línea de comandos de Linux si la computadora es física o virtual?

Máquinas virtuales e hipervisores

Una computadora tradicional es un objeto físico. Es una colección de diferentes piezas de hardware que se conectan y unen para que pueda cargar un sistema operativo, instalar aplicaciones, iniciarlas y usarlas.

El hardware es caro. Estar restringido a un sistema operativo por computadora física significa que el costo de ejecutar varios sistemas operativos pronto se vuelve prohibitivo. Una mejor solución sería permitir que una sola computadora física ejecute una selección de sistemas operativos al mismo tiempo, con cada uno pensando que se está ejecutando en su propio hardware único.

¿Qué es un hipervisor de máquina virtual?
RELACIONADO ¿Qué es un hipervisor de máquina virtual?

Un hipervisor lo hace posible. Un hipervisor, también llamado administrador de máquina virtual o monitor de máquina virtual, es un software que le permite crear máquinas virtuales. Estos se comportan como si fueran computadoras físicas individuales, aunque se ejecutan en el mismo host físico, compartiendo su espacio en el disco duro, la memoria y los núcleos de la CPU.

Por supuesto, la computadora host debe ser lo suficientemente poderosa para hacer frente a las demandas de la colección de máquinas virtuales, pero, con suficiente memoria RAM y potencia de procesamiento en el host, las máquinas virtuales pueden ejecutarse a velocidades casi completas.

Desde el lanzamiento del kernel 2.6.20 en 2007, Linux ha tenido soporte integrado para máquinas virtuales basadas en el kernel. Linux tiene varios hipervisores disponibles, como VirtualBox, GNOME Boxes y QEMU-KVM. Hacen uso de la capacidad KVM nativa de Linux, basándose en la funcionalidad del kernel nativo al agregar interfaces de usuario y funcionalidades como la posibilidad de tomar una instantánea de una máquina virtual.

Las máquinas virtuales brindan ahorros de costos, eficiencias, implementaciones simplificadas y, si se aprovisionan correctamente, beneficios de seguridad. También facilitan la escalabilidad. Los nuevos servidores pueden activarse automáticamente a medida que aumenta la demanda de un servicio y apagarse cuando la demanda disminuye. Esto los hace muy populares tanto en la nube como en la infraestructura local.

Tal vez esté administrando de forma remota un servidor Linux y necesite saber si es una máquina virtual o una caja física. O tiene un script que necesita saber en qué tipo de plataforma se está ejecutando. Aquí hay varias formas en que puede detectar si la computadora en la que está trabajando es física o virtual.

El comando dmicode

El comando dmidecode admite una gran cantidad de opciones y modificadores. Interroga las tablas de la interfaz de administración de escritorio (DMI) e imprime la información en la ventana del terminal.

Cómo enumerar los dispositivos de su computadora desde la terminal de Linux
RELACIONADO Cómo enumerar los dispositivos de su computadora desde la terminal de Linux

Lo usaremos con la opción -s (mostrar una sola cadena) y solicitaremos el nombre del producto del sistema. Tenga en cuenta que debemos usar sudo .

Ejecutaremos el comando en una máquina virtual VirtualBox con Ubuntu 22.04.

 sudo dmidecode -s system-product-name 

El comando dmidecode que identifica correctamente una máquina virtual VirtualBox

La plataforma está correctamente identificada como VirtualBox.

En una máquina virtual QEMU-KVM que ejecuta Fedora 35, obtenemos este resultado.

 sudo dmidecode -s system-product-name 

El comando dmidecode que identifica correctamente una VM de GNOME Boxes

Aunque se informa como una PC estándar, es una PC virtual QEMU estándar, de tipo Q35. Entonces la plataforma se reconoce correctamente como una máquina virtual.

Si ejecutamos el mismo comando en una computadora física, obtenemos información sobre el fabricante.

 sudo dmidecode -s system-product-name 

El comando dmidecode que devuelve información sobre una computadora física

Esta computadora es una construcción personalizada basada en una placa base Micro-Star International Company Limited, con el código de producto de MS-7B86.

El comando lshw

El comando lshw enumera los detalles de una amplia gama de hardware informático. Podemos elegir sobre qué clase de hardware queremos que lshw informe.

Cómo usar lshw en Linux (con un ejemplo práctico)
RELACIONADO Cómo usar lshw en Linux (con un ejemplo práctico)

Vamos a usar la opción -class con el modificador del system . Usar sudo con este comando asegura que veamos todos los detalles.

Ejecutaremos este comando en nuestra máquina virtual Ubuntu VirtualBox.

 sudo lshw -sistema de clases 

El comando lshw que informa sobre una máquina virtual VirtualBox

  • El campo "descripción" tiene una entrada genérica de "computadora".
  • El campo "producto" nos dice que se trata de una máquina virtual que se ejecuta en VirtualBox.
  • El campo "proveedor" contiene el nombre de la empresa alemana que creó VirtualBox, Innotek GmbH. Innotek fue adquirido por Oracle Corporation en 2010 como parte de su adquisición de Sun Microsystems, Inc.

Tuvimos que instalar lshw en Fedora.

 sudo dnf instalar lshw 

Instalar lshw en Fedora con el comando dnf

Probemos ese comando en nuestra VM de Fedora ejecutándose en GNOME Boxes.

 sudo lshw -sistema de clase 

El comando lshw informa sobre una VM de GNOME Boxes

  • Nuevamente, el campo "descripción" tiene una entrada genérica de "computadora".
  • El campo "producto" nos brinda la misma información de PC QEMU estándar que vimos con el comando dmidecode .
  • El campo "proveedor" contiene "QEMU", lo que indica claramente que se trata de una máquina virtual.

Este es el resultado de ejecutar el mismo comando en nuestra computadora física.

 sudo lshw -sistema de clase 

El comando lshw informando en una computadora física

Podemos ver que se trata de una computadora de hardware, con una placa base Micro-Star.

  • El hardware se identifica como una computadora de escritorio.
  • El campo "producto" nos da el tipo de placa base, MS-7B86.
  • El campo "proveedor" contiene el nombre del fabricante.

El comando hostnamectl

Este comando tiene la ventaja de que no necesita tener privilegios de sudo para ejecutarlo. Sin embargo, solo está disponible en distribuciones habilitadas para systemd . La mayoría de las distribuciones modernas usan systemd .

Esta es la respuesta al ejecutar el comando en nuestra máquina virtual Ubuntu VirtualBox.

 hostnamectl 

La salida del comando hostnamectl en una máquina virtual VirtualBox con la línea de virtualización resaltada

  • El campo "icon-name" tiene "-vm" adjunto.
  • El campo "Chasis" contiene "vm".
  • El campo "Virtualización" contiene "oracle".
  • El campo "Proveedor de hardware" contiene "innotek GmbH".
  • El campo "Modelo de hardware" contiene "VirtualBox".

El resultado de nuestra VM Fedora dentro de GNOME Boxes es muy similar.

 hostnamectl 

La salida del comando hostnamectl en una VM de GNOME Boxes con la línea de virtualización resaltada

  • El campo "icon-name" tiene "-vm" adjunto.
  • El campo "Chasis" contiene "vm".
  • El campo "Virtualización" contiene "kvm".
  • El campo "Proveedor de hardware" contiene "QEMU"
  • El campo "Modelo de hardware" contiene "PC estándar (Q35 + ICH9, 2009)".

Si usamos el comando hostnamectl en nuestro escritorio físico, la salida no contiene una línea de "Virtualización".

 hostnamectl 

La salida del comando hostnamectl en una computadora física, sin información de "virtualización"

Si no hay un campo de "Virtualización", debe estar ejecutando en bare metal.

El comando systemd-detect-virt

Si desea obtener una respuesta lo más breve posible, systemd-detect-virt es probablemente lo que está buscando. Nuevamente, esto requiere una distribución equipada con systemd , pero no requiere privilegios de sudo . Esto, y su salida concisa, lo hacen muy adecuado para su uso en secuencias de comandos.

Este es el resultado de ejecutar el comando en nuestra máquina virtual Ubuntu VirtualBox.

 systemd-detectar-virt 

Identificación de una máquina virtual VirtualBox con systemd-detect-virt

Se informa que nuestra copia de Fedora que se ejecuta en GNOME Boxes utiliza la virtualización KVM.

 systemd-detectar-virt 

Identificación de una VM de GNOME Boxes con systemd-detect-virt

Ejecutar systemd-detect-virt en nuestra máquina de hardware da como resultado que se imprima "ninguno" en la terminal.

 systemd-detectar-virt 

Una computadora física que se identificó correctamente como que no tiene virtualización

Un script sensible a la plataforma

Para darle a una secuencia de comandos la capacidad de detectar si se está ejecutando en un entorno virtualizado o en hardware físico, podemos usar el comando systemd-detect-virt y usar sentencias Bash case para manejar las opciones.

Este es el script que usaremos. Copie este texto y guárdelo en un archivo llamado "platform.sh".

 #!/bin/bash

shopt -s nocasematch

caso $(systemd-detect-virt) en

  ninguna)
    echo "Hardware físico"
    ;;

  *)
    echo "Máquina virtual"
    ;;
esac

El script usa shopt para elegir coincidencias que no distinguen entre mayúsculas y minúsculas. El comando systemd-detect-virt se usa en la declaración del case . El resultado de este comando se compara con cada una de las cláusulas del case en el cuerpo de la declaración del case hasta que se encuentra una coincidencia. Todo lo que no coincida se captura mediante la cláusula predeterminada "*)".

Cómo usar declaraciones de casos en scripts Bash
RELACIONADO Cómo usar declaraciones de casos en secuencias de comandos Bash

La forma más sencilla es probar si la respuesta de systemd-detect-virt es "ninguna". Si es así, el script se está ejecutando en hardware físico. Para todos los demás casos, el script debe ejecutarse en una máquina virtual.

Antes de que podamos ejecutar el script, debemos hacerlo ejecutable, usando chmod .

 chmod +x plataforma.sh 

Hacer que el script de la plataforma sea ejecutable con chmod

Identifica correctamente nuestra máquina virtual Ubuntu VirtualBox como una máquina virtual.

 ./plataforma.sh 

Usando el script de plataforma.sh en una VM de VirtualBox

También detecta correctamente la máquina virtual GNOME Boxes que ejecuta Fedora.

 ./plataforma.sh 

Uso del script platform.sh en una VM de GNOME Boxes

El script también detecta correctamente cuando se está ejecutando en una máquina física.

 ./plataforma.sh 

Usando el script platform.sh en una computadora física

Las diferentes cláusulas de case podrían establecer variables que se verificaron en otra parte del script para realizar diferentes tipos de procesamiento, o podrían llamar a funciones específicas dentro de su script.

Si su secuencia de comandos necesitaba detectar y acomodar diferentes tipos de entornos virtuales, podría agregar más cláusulas de case , buscando las diferentes cadenas que systemd-detect-virt puede devolver. Podemos ver la lista completa de posibles respuestas usando la opción --list . Para que sea más fácil verlos todos a la vez, canalizaremos la salida a través del comando de column .

 systemd-detectar-virt --list | columna 

El conjunto completo de respuestas que systemd-detect-virt puede devolver

Toma la pastilla roja

Estas técnicas permiten que sus scripts sepan cuándo se están ejecutando en hardware desnudo y cuándo están dentro de una máquina virtual.

Como Neo en Matrix, sabrán qué es real y qué no.