Como permitir que scripts do Linux detectem que estão sendo executados em máquinas virtuais

Publicados: 2022-06-27
Duas mãos, uma segurando uma pílula vermelha e a outra uma pílula azul.
diy13/Shutterstock.com

As máquinas virtuais se esforçam muito para convencer seus sistemas operacionais de que estão sendo executados em hardware físico. Então, você pode dizer pela linha de comando do Linux se o computador é físico ou virtual?

Máquinas Virtuais e Hipervisores

Um computador tradicional é um objeto físico. É uma coleção de diferentes peças de hardware que são conectadas e aparafusadas para que você possa carregar um sistema operacional, instalar aplicativos, iniciá-los e usá-los.

Hardware é caro. Estar restrito a um sistema operacional por computador físico significa que o custo de executar vários sistemas operacionais logo se torna proibitivo. Uma solução melhor seria permitir que um único computador físico executasse uma seleção de sistemas operacionais ao mesmo tempo, com cada um pensando que está sendo executado em seu próprio hardware exclusivo.

O que é um hipervisor de máquina virtual?
RELACIONADO O que é um hipervisor de máquina virtual?

Um hipervisor torna isso possível. Um hipervisor — também chamado de gerenciador de máquina virtual ou monitor de máquina virtual — é um software que permite criar máquinas virtuais. Eles se comportam como se fossem computadores físicos individuais, embora sejam executados no mesmo host físico, compartilhando seu espaço no disco rígido, memória e núcleos de CPU.

É claro que o computador host precisa ser poderoso o suficiente para lidar com as demandas da coleção de máquinas virtuais, mas, com RAM e poder de processamento suficientes no host, as máquinas virtuais podem ser executadas em velocidades próximas ao bare-metal.

Desde o lançamento do kernel 2.6.20 em 2007, o Linux tem suporte a máquinas virtuais baseadas em kernel. O Linux tem vários hipervisores disponíveis para ele, como VirtualBox, GNOME Boxes e QEMU -KVM. Eles fazem uso do recurso KVM nativo do Linux, com base na funcionalidade nativa do kernel, adicionando interfaces de usuário e funcionalidades como a capacidade de tirar um instantâneo de uma máquina virtual.

As máquinas virtuais trazem economia de custos, eficiência, implantações simplificadas e – provisionadas corretamente – benefícios de segurança. Eles também facilitam a escalabilidade. Novos servidores podem ser ativados automaticamente à medida que a demanda por um serviço aumenta e desligados quando a demanda cai. Isso os torna extremamente populares tanto na nuvem quanto na infraestrutura local.

Talvez você esteja administrando remotamente um servidor Linux e precise saber se é uma máquina virtual ou uma caixa física. Ou você tem um script que precisa saber em que tipo de plataforma está sendo executado. Aqui estão várias maneiras de detectar se o computador em que você está trabalhando é físico ou virtual.

O comando dmidecode

O comando dmidecode suporta um grande número de opções e modificadores. Ele interroga as tabelas Desktop Management Interface (DMI) e imprime as informações na janela do terminal.

Como listar os dispositivos do seu computador a partir do terminal Linux
RELACIONADO Como listar os dispositivos do seu computador a partir do terminal Linux

Vamos usá-lo com a -s (exibir uma única string) e pedir o nome do produto do sistema. Observe que devemos usar sudo .

Executaremos o comando em uma VM do VirtualBox executando o Ubuntu 22.04.

 sudo dmidecode -s system-product-name 

O comando dmidecode identificando corretamente uma VM do VirtualBox

A plataforma está corretamente identificada como VirtualBox.

Em uma VM QEMU-KVM executando o Fedora 35, obtemos essa saída.

 sudo dmidecode -s system-product-name 

O comando dmidecode identificando corretamente uma VM do GNOME Boxes

Embora seja relatado como um PC padrão, é um PC virtual QEMU padrão, do tipo Q35. Portanto, a plataforma é reconhecida corretamente como uma máquina virtual.

Se executarmos o mesmo comando em um computador físico, obteremos algumas informações sobre o fabricante.

 sudo dmidecode -s system-product-name 

O comando dmidecode retornando informações sobre um computador físico

Este computador é uma construção personalizada baseada em uma placa-mãe Micro-Star International Company Limited, com o código de produto MS-7B86.

O comando lshw

O comando lshw lista os detalhes de uma ampla variedade de hardware de computador. Podemos escolher qual classe de hardware queremos que o lshw reporte.

Como usar lshw no Linux (com um exemplo prático)
RELACIONADO Como usar lshw no Linux (com um exemplo prático)

Vamos usar a opção -class com o modificador do system . Usar sudo com este comando garante que vejamos todos os detalhes.

Executaremos este comando em nossa VM Ubuntu VirtualBox.

 sudo lshw -class system 

O comando lshw relatando em uma VM do VirtualBox

  • O campo “descrição” tem uma entrada genérica de “computador”.
  • O campo “produto” nos diz que esta é uma máquina virtual rodando no VirtualBox.
  • O campo “fornecedor” contém o nome da empresa alemã que criou o VirtualBox, Innotek GmbH. A Innotek foi adquirida pela Oracle Corporation em 2010 como parte da aquisição da Sun Microsystems, Inc.

Tivemos que instalar o lshw no Fedora.

 sudo dnf install lshw 

Instalando o lshw no Fedora com o comando dnf

Vamos tentar esse comando em nosso Fedora VM rodando no GNOME Boxes.

 sudo lshw -class system 

O comando lshw relatando em uma VM do GNOME Boxes

  • Novamente, o campo “descrição” tem uma entrada genérica de “computador”.
  • O campo “produto” nos fornece as mesmas informações padrão do PC QEMU que vimos com o comando dmidecode .
  • O campo “fornecedor” contém “QEMU” que indica claramente que esta é uma máquina virtual.

Este é o resultado da execução do mesmo comando em nosso computador físico.

 sudo lshw -class system 

O comando lshw relatando em um computador físico

Podemos ver que este é um computador hardware, com uma placa-mãe Micro-Star.

  • O hardware é identificado como um computador desktop.
  • O campo “produto” nos dá o tipo de placa-mãe, MS-7B86.
  • O campo “fornecedor” contém o nome do fabricante.

O comando hostnamectl

Este comando tem a vantagem de que você não precisa ter privilégios sudo para executá-lo. No entanto, está disponível apenas em distribuições habilitadas para systemd . A maioria das distribuições modernas usa systemd .

Esta é a resposta da execução do comando em nossa VM Ubuntu VirtualBox.

 hostnamectl 

A saída do comando hostnamectl em uma VM do VirtualBox com a linha de virtualização destacada

  • O campo “icon-name” tem “-vm” anexado a ele.
  • O campo “Chassis” contém “vm”.
  • O campo “Virtualização” contém “oráculo”.
  • O campo "Fornecedor de hardware" contém "innotek GmbH".
  • O campo “Modelo de Hardware” contém “VirtualBox”.

A saída em nossa Fedora VM dentro do GNOME Boxes é muito semelhante.

 hostnamectl 

A saída do comando hostnamectl em uma VM do GNOME Boxes com a linha de virtualização realçada

  • O campo “icon-name” tem “-vm” anexado a ele.
  • O campo “Chassis” contém “vm”.
  • O campo “Virtualização” contém “kvm”.
  • O campo “Fornecedor de Hardware” contém “QEMU”
  • O campo “Modelo de hardware” contém “PC padrão (Q35 + ICH9, 2009)”.

Se usarmos o comando hostnamectl em nossa área de trabalho física, a saída não conterá uma linha de “Virtualização”.

 hostnamectl 

A saída do comando hostnamectl em um computador físico, sem informações de "Virtualização"

Se não houver um campo de “Virtualização”, você deve estar executando em bare metal.

O comando systemd-detect-virt

Se você deseja obter uma resposta o mais curta possível, systemd-detect-virt é provavelmente o que você está procurando. Novamente, isso requer uma distribuição equipada com systemd , mas não requer privilégios sudo . Isso - e sua saída concisa - o tornam adequado para uso em scripts.

Este é o resultado da execução do comando em nossa VM Ubuntu VirtualBox.

 systemd-detect-virt 

Identificando uma VM do VirtualBox com systemd-detect-virt

Nossa cópia do Fedora rodando no GNOME Boxes é relatada como usando virtualização KVM.

 systemd-detect-virt 

Identificando uma VM do GNOME Boxes com systemd-detect-virt

A execução systemd-detect-virt em nossa máquina de hardware resulta em “none” sendo impresso no terminal.

 systemd-detect-virt 

Um computador físico sendo corretamente identificado como não tendo virtualização

Um script sensível à plataforma

Para dar a um script a capacidade de detectar se ele está sendo executado em um ambiente virtualizado ou em hardware físico, podemos usar o comando systemd-detect-virt e usar instruções case Bash para lidar com as opções.

Este é o script que usaremos. Copie este texto e salve-o em um arquivo chamado “platform.sh”.

 #!/bin/bash

shopt -s nocasematch

case $(systemd-detect-virt) em

  Nenhum)
    echo "Hardware Físico"
    ;;

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

O script usa shopt para escolher a correspondência que não diferencia maiúsculas de minúsculas. O comando systemd-detect-virt é usado na instrução case . A saída desse comando é comparada com cada uma das cláusulas case no corpo da instrução case até que uma correspondência seja encontrada. Qualquer coisa que não seja correspondida é capturada pela cláusula padrão “*)”.

Como usar instruções de caso em scripts Bash
RELACIONADO Como usar instruções de caso em scripts Bash

A maneira mais simples é testar se a resposta do systemd-detect-virt é “nenhuma”. Se for, o script está sendo executado em hardware físico. Para todos os outros casos, o script deve ser executado em uma máquina virtual.

Antes de podermos executar o script, devemos torná-lo executável, usando chmod .

 chmod +x plataforma.sh 

Tornando o script da plataforma executável com chmod

Ele identifica corretamente nossa VM Ubuntu VirtualBox como uma máquina virtual.

 ./platform.sh 

Usando o script platform.sh em uma VM do VirtualBox

Ele também detecta corretamente a VM do GNOME Boxes executando o Fedora.

 ./platform.sh 

Usando o script platform.sh em uma VM do GNOME Boxes

O script também detecta corretamente quando está sendo executado em uma máquina física.

 ./platform.sh 

Usando o script platform.sh em um computador físico

As diferentes cláusulas case podem definir variáveis ​​que foram verificadas em outro lugar no script para executar diferentes tipos de processamento ou podem chamar funções específicas em seu script.

Se seu script precisasse detectar e acomodar diferentes tipos de ambientes virtuais, você poderia adicionar mais cláusulas case , procurando as diferentes strings que systemd-detect-virt pode retornar. Podemos ver a lista completa de respostas possíveis usando a opção --list . Para facilitar a visualização de todos de uma vez, canalizaremos a saída por meio do comando column .

 systemd-detect-virt --list | coluna 

O conjunto completo de respostas que o systemd-detect-virt pode retornar

Tome a pílula vermelha

Essas técnicas permitem que seus scripts saibam quando estão sendo executados em hardware nu e quando estão dentro de uma máquina virtual.

Como Neo na Matrix, eles saberão o que é real e o que não é.