gerar ID exclusivo de máquina consistente em programação c

gerar ID exclusivo de máquina consistente em programação c

É possível gerar um ID exclusivo que não mude com o tempo, a menos que haja alterações de hardware. O hardware deve ser gerado com programa ac.

Isso também seria ótimo se fosse robusto contra falsificação, como falsificação de endereço MAC ou número de série do disco rígido. Mas isso não é um requisito absoluto.

Preciso desse ID para coletar dados de software para estatísticas de vários computadores diferentes.

Já li muitos posts semelhantes, como este: gerar ID exclusivo de máquina consistente; mas eles não atendem às minhas necessidades.

Preciso que este programa seja executado como usuário normal, então não posso usar comandos como "dmidecode" e outros. Mesmo que eu não tenha outras soluções além de usar endereços MAC, não quero que o UUID mude se o usuário mudar de Wifi para Ethernet, então apenas usar o primeiro endereço MAC pode ser problemático. Além disso, o UUID deve permanecer idêntico, mesmo que instalem um VMware ou VPN. Portanto, pegar todos os endereços MAC não é uma opção porque as ferramentas anteriores geram mais interfaces de rede e, portanto, mais endereços MAC, alterando assim o UUID.

Também quero que funcione na máquina virtual, o uuid do convidado gerado deve ser diferente do host.

Eu nem sei se existe tal solução para esse problema. Mas o que pensei seria pegar apenas os endereços MAC de todas as interfaces de hardware físicas existentes lendo em sys/class/net/*/addresses. Em seguida, anexe todos os endereços MAC e faça hash deles com sha1 para gerar o UUID. Mas como posso filtrar os repertórios para selecionar apenas um? E posso ter certeza de que o pedido deles não será trocado, alterando assim a string anexada e, portanto, o UUID.

Caso contrário, posso recuperar o número de série do disco rígido sem privilégios de root e ferramentas de terceiros? (Se eu conseguir encontrar a fonte do software de terceiros, tudo bem)

Quaisquer outras soluções também seriam muito bem-vindas.

PS: Deve ser compatível com qualquer versão do Linux com kernel 2.6 ou superior

Responder1

Resposta curta

De todas as minhas pesquisas e tentativas, eu diria que não é possível fazer um programa que gere um ID único respeitando as seguintes restrições.

  • O ID deve ser sempre o mesmo se gerado no mesmo computador.
  • O ID deverá ser diferente se gerado em computadores diferentes.
  • O programa deve ser executado como usuário.
  • O programa deve ser compatível com qualquer distribuição Linux com versão de kernel 2.6 ou superior
  • O ID pode ser diferente se o computador for modificado (por exemplo: substituição de hardware)
  • O programa não deve depender de ferramentas de terceiros que devem ser instaladas no computador

Resposta longa

Aqui apresentarei minha tentativa com os endereços mac.

O objetivo aqui era encontrar uma maneira de recuperar os endereços de todas as interfaces de rede física. Como usuário normal, percebi que a maneira mais fácil de encontrar endereços MAC seria ler os arquivos do sistema no diretório “/sys”. Esses arquivos estão disponíveis desde o Linux 2.6, então é perfeito.

Minha pesquisa me levou a esses conjuntos de regras: https://www.kernel.org/doc/Documentation/sysfs-rules.txt

O uso da biblioteca udev conforme recomendado nessas regras não é possível porque ela deve ser adicionada externamente. Então mergulhei na fonte que pode ser encontrada aqui:http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev

O que aprendi com isso é que para recuperar os endereços mac você deve procurar por "sys/subsystem", se estiver presente, procure um diretório "net" dentro dele e encontrará diretórios com cada interface de rede. Se não houver uma pasta "subsistema", você deverá procurar nas pastas "sys/class", "sys/bus" e "sys/block" o diretório "net". Na verdade, sempre os encontrei na “classe”, mas as regras diziam que isso não deveria ser esperado.

Acima eu disse que na pasta "net" você encontrará os diretórios da rede, isso não é totalmente verdade. No linux 2.6 (usei RHEL 4), são diretórios e dentro você encontrará, entre outros, o arquivo "address" contendo o endereço mac, um link simbólico direcionado a um diretório em "sys/devices". Se estiver em uma versão Linux superior, será diretamente um link simbólico para um diretório em "/sys/devices", onde você encontrará o arquivo "address". (Experimentei RHEL 6, Debian 7, Debian 8, Ubuntu 15 e Ubuntu 15 com kernel atualizado para Linux 4.3)

Nunca vi o diretório "/sys/subsystem" mesmo na nova versão do Linux (4.3).

Novo layout do sysfs( >= linux 3): Para diferenciar a interface física da virtual, eu queria dar uma olhada no devpath do dispositivo. O link simbólico que tenho em "/sys/class/net" direciona para estes diretórios:

  • "/sys/devices/pci0000:00/0000:00:11.0/0000:02:01.0/net/eth0"
  • "/sys/dispositivos/virtual/net/eth1"

A eth1 foi uma placa de rede virtual fictícia que criei seguindo este tópico:Como posso criar uma interface Ethernet virtual em uma máquina sem adaptador físico?

Então você pode ver que os virtuais estão em uma pasta "virtual", então essa seria a forma de diferenciá-los.

Layout antigo do sysfs(Linux 2.6):

A interface de rede virtual não possui um link simbólico de "dispositivo" em seus diretórios.

Você encontrará "/sys/class/net/eth0/device -> /sys/devices...." Mas se houvesse uma eth1 virtual, não haverá tal link simbólico em "/sys/class/net/eth1" .


Resumindo, usando "opendir", "readdir", "access('...',F_OK)", "fopen".. você pode recuperar os endereços MAC apenas de interfaces físicas.

Em seguida, basta classificá-los, para ter certeza de que virão na mesma ordem, anexar tudo em um buffer e usar um SHA1 do openssl, fazer uma pequena análise para fazer com que pareça um UUID e pronto.

Mas a questão é que eu não queria confiar no fato de que haveria uma pasta "virtual" em qualquer lugar do caminho de desenvolvimento de um dispositivo de rede. Nunca é dito nas regras, vinculadas acima, que este seria sempre o caso. Portanto, o problema não pode ser respondido desta forma.

Espero que todas as minhas pesquisas ajudem alguém.

informação relacionada