Em primeiro lugar, observe que o CPUID definitivamente não é um marcador de identificação única comumente acessível 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. Em 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 apenas isso 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. Veja ip a help
para obter informações sobre como fazer isso.
Observe também que esse problema não é exclusivo ip
e também deve ser tratado se você o usar ifconfig
, mas que pode ser tratado com mais segurança ip
- que faz parte do iproute2
conjunto de redes e é mantido ativamente - do que com ifconfig
um membro. do net-tools
pacote e vi pela última vez um lançamento do Linux em 2001 . Devido à alteração dos recursos no kernel desde seu último lançamento, ifconfig
é conhecido por relatar mal 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 eth[0-9]
não é um meio confiável de fazê-lo, pois eles podem mudar com base na ordem de detecção em paralelo 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 um hash de uma lista de séries de disco rígido geradas como:
lsblk -nro SERIAL
Faça lsblk --help
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, pensei em mudar de ideia.
Considerando isso, olhei novamente para o sistema de arquivos e encontrei a /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
Espero que seja lá que dmidecode
consiga grande parte de suas informações e, de fato, pareça . De acordo com man dmidecode
você, 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 é tão fácil quanto conseguir 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é a maioria das atualizações e modificações de firmware, e qualquer sistema Linux com o efivarfs
módulo carregado pode listar um ou ambos os nomes da maneira mais simples:
printf '%s\n' /sys/firmware/efi/efivars/*LangCodes-*
A forma mais antiga - LangCodes-${UUID}
é, aparentemente, agora obsoleto , e em sistemas mais recentes deve ser PlatformLangCodes-${UUID}
, mas, de acordo com a especificação, um ou o 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, procure efitools .