desenv-web-rp.com

gerar ID único consistente da máquina

Podemos gerar um ID exclusivo para cada PC, algo como uuuidgen, mas ele nunca será alterado a menos que haja alterações de hardware? Eu estava pensando em mesclar CPUID e MACADDR e misturá-los para gerar uma identificação consistente, mas não tenho idéia de como analisá-los usando o script bash, o que sei é como obter o CPUID de

dmidecode -t 4 | grep ID

e

ifconfig | grep ether

então eu preciso combinar essas seqüências de caracteres hexadecimais e hash-las usando sha1 ou md5 para criar uma sequência hexadecimal de comprimento fixo.
Como posso analisar essa saída?

21
uray

Que tal esses dois:

$ Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g'
52060201FBFBEBBF
$ ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g'
0126c9da2c38

Você pode então combiná-los e hash-los com:

$ echo $(Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \
       $(ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g') | sha256sum 
59603d5e9957c23e7099c80bf137db19144cbb24efeeadfbd090f89a5f64041f  -

Para remover o traço à direita, adicione mais um tubo:

$ echo $(Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \
       $(ifconfig | grep eth1 | awk '{print $NF}' | sed 's/://g') | sha256sum |
  awk '{print $1}'
59603d5e9957c23e7099c80bf137db19144cbb24efeeadfbd090f89a5f64041f

Como @mikeserv aponta em sua resposta , o nome da interface pode mudar entre as botas. Isso significa que o que é eth0 hoje pode ser eth1 amanhã, portanto, se você desejar eth0, Poderá obter um endereço MAC diferente em botas diferentes. Meu sistema não se comporta dessa maneira, então não posso realmente testar, mas as soluções possíveis são:

  1. Grep for HWaddr na saída de ifconfig, mas mantenha todos eles, não apenas aquele que corresponde a uma NIC específica. Por exemplo, no meu sistema, tenho:

    $ ifconfig | grep HWaddr
    eth1      Link encap:Ethernet  HWaddr 00:24:a9:bd:2c:28  
    wlan0     Link encap:Ethernet  HWaddr c4:16:19:4f:ac:g5  
    

    Ao pegar os dois endereços MAC e passá-los através de sha256sum, Você poderá obter um nome único e estável, independentemente de qual NIC é chamado de:

    $ echo $(Sudo dmidecode -t 4 | grep ID | sed 's/.*ID://;s/ //g') \
         $(ifconfig | grep -oP 'HWaddr \K.*' | sed 's/://g') | sha256sum |
          awk '{print $1}'
    662f0036cba13c2ddcf11acebf087ebe1b5e4044603d534dab60d32813adc1a5    
    

    Observe que o hash é diferente dos acima, porque estou passando os dois endereços MAC retornados por ifconfig para sha256sum.

  2. Crie um hash com base nos UUIDs do (s) seu (s) disco (s) rígido (s):

    $ blkid | grep -oP 'UUID="\K[^"]+' | sha256sum | awk '{print $1}'
    162296a587c45fbf807bb7e43bda08f84c56651737243eb4a1a32ae974d6d7f4
    
22
terdon

Primeiramente, observe que o CPUID é definitivamente não um marcador de identificação comumente acessível de maneira única para qualquer sistema posterior a um Intel Pentium III. Embora o hash com endereços MAC possa levar a marcadores únicos, certamente, isso se deve apenas às qualidades únicas dos próprios MACs e o CPUID, nesse caso, nada mais é do que circunstancial. Além disso, o hash resultante provavelmente não será mais exclusivo que o UUID da placa-mãe, e isso é muito mais fácil de recuperar e o processo é muito menos propenso a erros. De wikipedia.org/wiki/cpuid :

EAX = 3 : Número de série do processador

Veja também: Pentium III § Controvérsia sobre questões de privacidade

Isso retorna o número de série do processador. O número de série do processador foi introduzido no Intel Pentium III, mas devido a questões de privacidade, esse recurso não é mais implementado em modelos posteriores (o bit do recurso PSN é sempre limpo). Os processadores Efficeon e Crusoe da Transmeta também fornecem esse recurso. As CPUs AMD, no entanto, não implementam esse recurso em nenhum modelo de CPU.

Você pode visualizar uma CPU analisada fazendo cat /proc/cpuinfo ou mesmo apenas lscpu.

Isso fornece a você todos os endereços MAC para as interfaces de rede reconhecidas pelo kernel do Linux, eu acho:

ip a | sed '\|^ *link[^ ]* |!d;s|||;s| .*||'

Pode ser necessário filtrar essa lista se ela incluir redes virtuais com MACs gerados aleatoriamente. Você pode fazer isso com sinalizadores na chamada para ip diretamente. Vejo ip a help para obter informações sobre como fazer isso.

Observe também que esse problema não é exclusivo de ip e também deve ser tratado se você usar ifconfig, mas que pode ser tratado de maneira mais confiável com ip - que faz parte do iproute2 suite de rede e é mantida ativamente - do que com ifconfig - que é membro do net-tools package e vi pela última vez um Linux lançado em 2001 . Devido à mudança de recursos no kernel desde seu último lançamento, ifconfig é conhecido por relata alguns sinalizadores de recursos de rede e seu uso deve ser evitado, se possível.

No entanto, entenda que a filtragem com nomes de interface do kernel como eth[0-9] não é um meio confiável de fazer isso, pois eles podem mudar com base em sua ordem de detecção paralela por udev durante o processo de inicialização. Consulte Nomes de rede previsíveis para obter mais informações.

Como dmidecode não está instalado no meu sistema, pensei inicialmente em fazer o hash de uma lista de séries de discos rígidos geradas como:

lsblk -nro SERIAL

Faz lsblk --help para algumas dicas sobre como refinar essa lista - por tipo de disco, digamos. Considere também lspci e/ou lsusb talvez.

Combiná-los é fácil:

{ ip a | sed ... ; lsblk ... ; } | #abbreviated... for brevity...
    tr -dc '[:alnum:]' | #deletes all chars not alphanumeric - including newlines
    sha256sum #gets your hash

Como você me informou, você está direcionando os recursos do usuário para seus IDs exclusivos, e não é possível confiar nos discos rígidos para existir, pensei em mudar de ideia.

Considerado isso, olhei novamente para o sistema de arquivos e encontrei o /sys/class/dmi/id pasta. Eu verifiquei alguns dos arquivos:

cat ./board_serial ./product_serial

###OUTPUT###
To be filled by O.E.M.
To be filled by O.E.M.

No entanto, este parece ser muito bom, mas não publicarei a saída:

Sudo cat /sys/class/dmi/id/product_uuid

Eu espero que seja onde dmidecode obtenha grande parte de suas informações de qualquer maneira e, de fato, se parece com isso . De acordo com man dmidecode você também pode simplificar bastante o uso dessa ferramenta especificando o argumento:

dmidecode -s system-uuid

Mais simples ainda, você pode apenas ler o arquivo. Observe que esse arquivo específico identifica especificamente uma placa-mãe. Aqui está um trecho do patch do kernel de 2007 que originalmente implementou essas exportações para o /sysfs sistema de arquivos virtual:

+DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,      0444, DMI_BIOS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_version,         0444, DMI_BIOS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(bios_date,        0444, DMI_BIOS_DATE);
+DEFINE_DMI_ATTR_WITH_SHOW(sys_vendor,       0444, DMI_SYS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(product_name,         0444, DMI_PRODUCT_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(product_version,   0444, DMI_PRODUCT_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(product_serial,    0400, DMI_PRODUCT_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(product_uuid,         0400, DMI_PRODUCT_UUID);
+DEFINE_DMI_ATTR_WITH_SHOW(board_vendor,         0444, DMI_BOARD_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(board_name,       0444, DMI_BOARD_NAME);
+DEFINE_DMI_ATTR_WITH_SHOW(board_version,     0444, DMI_BOARD_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(board_serial,         0400, DMI_BOARD_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(board_asset_tag,   0444, DMI_BOARD_ASSET_TAG);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_vendor,    0444, DMI_CHASSIS_VENDOR);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_type,         0444, DMI_CHASSIS_TYPE);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_version,   0444, DMI_CHASSIS_VERSION);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_serial,    0400, DMI_CHASSIS_SERIAL);
+DEFINE_DMI_ATTR_WITH_SHOW(chassis_asset_tag, 0444, DMI_CHASSIS_ASSET_TAG);

Você pode usar esses dados sozinho para identificar o sistema - se a placa-mãe for suficiente. Mas você pode combinar essas informações com os MACs do sistema da mesma maneira que demonstrei que você pode fazer com discos rígidos:

Sudo sh <<\CMD | tr -dc '[:alnum:]' | sha256sum
        ip a | sed '\|^ *link[^ ]* |!d;s|||;s| .*||'
        cat /sys/class/dmi/id/product_uuid 
CMD

O kernel do Linux também pode gerar UUIDs para você:

cat /proc/sys/kernel/random/uuid #new random uuid each time file is read

Ou:

cat /proc/sys/kernel/random/boot_id #randomly generated per boot

Concedido, é gerado aleatoriamente e você terá que repensar a atribuição de ID, mas é o mais fácil possível get pelo menos. E deve ser bastante sólido se você puder encontrar um meio de digitar isso.

Por fim, nos sistemas UEFI, isso se torna muito mais fácil - pois cada variável de ambiente de firmware EFI inclui seu próprio UUID. A variável de ambiente {Platform,}LangCodes-${UUID} deve estar presente em todos os sistemas UEFI, deve persistir reinicializações e até mais atualizações e modificações de firmware, e qualquer sistema Linux com o módulo efivarfs carregado pode listar um ou ambos os nomes simplesmente como:

printf '%s\n' /sys/firmware/efi/efivars/*LangCodes-*

A forma mais antiga - LangCodes-${UUID} aparentemente é agora descontinuado , e em sistemas mais recentes deve ser PlatformLangCodes-${UUID} mas, de acordo com as especificações, um ou outro deve estar presente em todos os sistemas UEFI. Com pouco esforço, você pode definir suas próprias variáveis ​​persistentes de reinicialização e talvez fazer mais uso do gerador UUID do kernel dessa maneira. Se estiver interessado, consulte efitools .

24
mikeserv

Muitas distribuições modernas enviam um arquivo /etc/machine-id contendo uma cadeia hexadecimal provavelmente exclusiva de 32 caracteres. É originário do systemd, onde ma página de manual possui mais informações e pode ser apropriada para seu objetivo.

21
XZS

Em muitas máquinas Linux, o arquivo /var/lib/dbus/machine-id Contém um ID exclusivo para cada distribuição Linux e pode ser acessado por uma chamada para dbus_get_local_machine_id(). Provavelmente é o mesmo que o /etc/machine-id Mencionado acima. Também funciona em instalações virtuais do Linux. Eu verifiquei nas distribuições atuais do Ubuntu, SuSE e CentOS.

6
rankeney

Você precisa que o ID da máquina mude quando o hardware muda? O ID da máquina está sendo usado para proteger alguma coisa? A melhor maneira que acredito ter um ID de máquina "consistente" é armazenando uma sequência aleatória em algum lugar do sistema e, dessa forma, se algum hardware mudar, o ID da máquina também não será alterado. Isso também é bom para sistemas virtualizados onde o acesso ao hardware é restrito e o ID MAC é 00: 00: 00: 00

Tente algo como este script sh para criar e obter o ID:

#!/bin/sh
FILE="/etc/machine-id"

if [ ! -f $FILE ]; then
    cat /dev/urandom|tr -dc A-Z0-9|head -c32 > $FILE;
fi

cat $FILE;
0
ub3rst4r

As outras respostas fornecem várias maneiras de extrair IDs do hardware. Você pode optar por usar um pedaço de hardware como identificador ou muitos. Isso é problemático se você precisar trocar ou substituir peças de hardware arbitrariamente.

Algumas pessoas podem armazenar uma identificação gerada em seu disco rígido (ou usar o UUID), mas os discos rígidos podem ser clonados.

Os módulos TPM e a inicialização segura podem fornecer um meio de vincular a placa-mãe e outro hardware com uma instalação em um disco rígido.

É sempre um pouco mais fácil nesses casos, se você fornecer mais informações sobre o que deseja realizar.

0
jgmjgm