2008-11-30 9 views
21

Quiero obtener desde cualquier sistema tipo Unix (si es posible) una identificación única que será persistente cada vez que mi aplicación se ejecute en la misma máquina. Si es posible, quiero obtener el mismo ID de Linux o FreeBSD o Solaris, etc ... No quiero generar un nuevo ID para cada máquina, pero obtengo una identificación ya existente, y prefiero esta identificación a vienen del sistema operativo y no prefiero usar algo como la dirección MAC.Obteniendo una identificación única de un sistema unix

Si no hay otra opción disponible, puedo usar MAC en combinación con otra cosa, por ejemplo, la identificación puede ser el hash md5 de la combinación de la dirección MAC y algo más.

Me gustaría escuchar sus sugerencias.

Si es útil, mi aplicación está escrita en C/C++.

El objetivo de todo esto es evitar que un usuario ejecute mi aplicación dos o más veces. Quiero correr solo una vez

+0

Encuentro esto poco claro. ¿Qué quieres identificar? ¿El hardware con el que te estás ejecutando? ¿El usuario? ¿¿Algo más?? Y único sobre qué alcance? – dmckee

+0

Tengo que estar de acuerdo. ¿Por qué todas las restricciones? –

+0

He tenido una lluvia de ideas. Creo que quiere ayuda para implementar un mecanismo de restricción de copia. Eso lo convierte en el hardware, y la respuesta de Uzhin es razonable. – dmckee

Respuesta

2

No creo que sea posible. Lo más cercano que puede obtener es crear una cadena aleatoria muy larga (como MS do con GUIDs) y almacenarla en algún lugar de su sistema.

+0

+1 para cancelar la votación. Esto fue mejor de lo que Blue podría haber esperado al principio. – dmckee

+0

Los GUID no son aleatorios, per se. Sin embargo, cómo los genera la MS no lo dicen. Supuestamente no se repiten en la máquina en la que se generan. –

11

Tanto Solaris y Linux ofrecen la hostid (1) utilidad

+10

En Linux glibc, gethostid() (que es lo que usa el hostid) devuelve un valor basado en la dirección IP, que no es único ni inalterable. – CesarB

+0

Eso depende de la aplicación. –

+4

Acabo de probar 'hostid' en 3 computadoras diferentes (pero la misma distribución): devuelve el mismo valor para todas ellas. – picrap

1

que tener en cuenta que una gran cantidad de configuraciones puede haber creado una imagen de sistema de archivos y clonado a muchas máquinas, en vez de hacerlo de forma individual. En otros casos, una máquina podría volver a configurar muchas veces. En otras palabras, cualquier cosa que el sistema operativo proporcione no puede ser confiable.

Sin embargo, la CPU mantiene un número de serie único, pero el acceso a él debe ser diferente en diferentes sistemas.

+0

Eso depende del tipo de CPU que tenga. Hace un tiempo, Intel comenzó a implementar un número de serie en procesadores Pentium que podría obtener con las instrucciones de cpuid, pero obtuvieron un gran revés de los grupos de privacidad al respecto. No estoy seguro de que todavía lo hagan. ¿Qué pasa si la computadora tiene 2 procs? –

0

Parece que está buscando UUID. Esta es una identificación única universalmente común (realmente, lo mismo que un GUID)

Existen muchas implementaciones C++ de esto en bibliotecas diferentes, o puede usar el comando uuidgen y capturar el resultado.

+1

Err, no, un UUID es diferente cada vez que se genera: "identificación única que será persistente cada vez que mi aplicación se ejecuta en la misma máquina" – user23167

1

No menciona qué tan estable debe ser el identificador único: ¿siempre desea que el mismo host produzca el mismo ID cada vez que se ejecuta su código?

Si no, entonces la sugerencia de fuzzymonk de uuidgen es lo que quiere.

En caso afirmativo, debe decidir qué constituye "lo mismo" en lo que concierne al host. Una manera sería la que sugiera, la suma MD5 del MAC de la primera interfaz ethernet y "algo". Para "algo" en ese caso, consideraría el FQDN, a menos que su noción de "mismo host" incluya el FQDN cambiando ...

0

La mayoría de las máquinas unix tienen un generador de números aleatorios accesible a través del /dev/random. Necesitará algo así como una dirección MAC y una hora para dar una originalidad única al generador GUID (esto es lo que hace el generador GUID en Windows). Además de esto, obtener algo de/dev/random te dará un constructo tipo GUID razonablemente bueno. En la práctica, las bibliotecas de UUID hacen este tipo de cosas detrás de escena.

Si solo necesita un número por máquina, entonces una dirección MAC probablemente sea suficiente. Estos son administrados por un organismo central y uno puede suponer razonablemente que no habrá dos direcciones MAC iguales.Sin embargo, si está intentando usar esto para vincular una instalación de software a una dirección MAC, tenga en cuenta que algunos componentes tienen direcciones MAC programables o componentes programables de la dirección MAC. Los sistemas operativos tipo Unix, particularmente los de código abierto, tienden a no tener números de serie cableados. Este enfoque también puede causar problemas con la ejecución de varias instancias del software en las máquinas virtuales.

Una opción podría ser un USB dongle, que se puede obtener de varios fabricantes. Otra opción podría ser un servidor de licencias, donde el código único se suministra al servidor. Nuevamente, varias soluciones enlatadas para esto están disponibles de diferentes fuentes.

+0

Necesito un número por máquina, que será persistente. Sé todo esto sobre las direcciones MAC y porque pueden cambiar, son mi última solución. – Blue

9

La mejor manera es, como de costumbre, ver cómo otras personas ya han resuelto el mismo problema.

FLEXlm también utiliza un identificador de host para sus licencias de nodo bloqueado. El identificador de host más común que utiliza es la dirección MAC de Ethernet para una de sus interfaces de red, unidas sin ningún separador.

También puede usar (en Windows) el número de serie del volumen de la unidad C: (otra vez aplastado sin separadores) y en Solaris la salida del comando hostid (IIRC, en computadoras Sun, este número es en realidad único, y ubicado en una pequeña EEPROM removible en la placa del sistema).

Si bien la dirección MAC es extremadamente fácil de falsificar, en la actualidad es un identificador casi universal (casi todas las computadoras nuevas tienen al menos un puerto Ethernet, y es muy común que estén a bordo), y realmente pretende ser globalmente único (de hecho, los protocolos de Ethernet dependen de esta singularidad). Los principales problemas que tendría con este enfoque:

  • Algunas computadoras tienen varias direcciones de Ethernet; algunos de ellos están en el tablero principal, algunos están en tarjetas removibles separadas.
  • Son extremadamente fáciles de falsificar (y algunos protocolos dependen de poder cambiarlos).
  • Algunos entornos virtualizados generan direcciones de Ethernet aleatorias en cada arranque (pero generalmente tienen una forma de forzar un valor fijo).
+0

+1 - Iba a mencionar que si hubiera una forma confiable de identificar un sistema linux, flexlm lo usaría, pero se conformarían con la dirección MAC. – JimB

3

No hay una manera general y confiable de obtener lo que desea.

5

Otra opción es utilizar información derivada de dmidecode, un comando presente en Linux. Esta información se decodifica desde/dev/mem, por lo tanto, requiere acceso a la raíz.

La información que dmidecode lee es defectuosa, ya que algunos fabricantes de placas base mienten o falsifican algunos de los campos.

+0

dmidecode no está disponible en todos los sistemas Linux. Por ejemplo, sistemas IBM POWER con SLES instalados en ellos. – woverton

0

Mencionó que en Windows usa algunos GUID ... ¿Tiene algunos detalles sobre cómo se crea?

Aparte de eso, podría intentar algo como la ID de la CPU, o la identificación del disco duro ... Supongo que no se pueden cambiar (pero se encontrará con problemas si se reemplaza un disco duro defectuoso).

+0

Esta respuesta en SO lo explica para Windows: http://stackoverflow.com/a/23584584/139793 – wasatchwizard

-2

Se puede utilizar un fichero de bloqueo en lugares como:

  • /var/run/yourapp.pid (si el programa ejecuta root)
  • $ HOME/.yourapp.pid (si se ejecuta por el usuario y sistema de archivos local)
  • $ HOME/.yourapp. $ (nombre de host -f).pid (casa en NFS)

Cuando se ejecuta el programa, se deberá hacer algo como:

lock = open(filename, O_CREAT | O_EXCL); 
dprintf(lock, "%u", getpid()); 

Si la apertura falla, compruebe si el proceso todavía está en marcha y si no es: eliminar el archivo e intenta de nuevo.

27

¿Qué hay del UUID del sistema de archivos raíz? Puede obtener el dispositivo del sistema de archivos raíz desde /etc/fstab, ya sea analizando manualmente el archivo o usando getfsent (3) o getfsfile (3). Una vez que tenga el dispositivo, puede obtener el UUID revisando los enlaces en /dev/disk/by-uuid o desde el comando blkid.

+0

¿Es único para todas las computadoras? –

+0

@spartacus sí, UUID es un identificador único universal. –

+0

http://tools.ietf.org/html/rfc4122 - Esta especificación define un espacio de nombres de nombre de recurso uniforme para UUID (Universally Unique IDentifier), también conocido como GUID (Globally unique IDentifier). Un UUID tiene 128 bits de longitud y puede garantizar singularidad en el espacio y el tiempo. –

1

Puede obtener el UUID del sistema de archivos raíz /, que es bastante confiable, aunque no diferenciará entre chroots y posiblemente vms que se ejecutan en el mismo disco.

Si se trata principalmente de discos duros internos o estáticos que están dedicados a ejecutar un sistema operativo en particular, entonces debería ser capaz de utilizar el UUID del sistema de archivos raíz para detectar el sistema.

Usted puede obtener el UUID de los fs raíz con algo como esto: alias sys_guid='sudo /sbin/blkid | grep "$(df -h/| sed -n 2p | cut -d" " -f1):" | grep -o "UUID=\"[^\"]*\" " | sed "s/UUID=\"//;s/\"//"'

Si necesita diferenciar aún más entre las versiones del núcleo del mismo sistema operativo, o diferentes sistemas operativos que se ejecutan en el mismo disco puede utilizar los datos desde uname y/o combínelos con el UUID raíz fs.

0

Las respuestas de Jason Day y A.Danischewski parecen estar en el camino correcto, pero no cumplen sus criterios de ningún "sistema tipo Unix" ya que /sbin/blkid y /etc/fstab no existen en OSX.

El único enfoque 100% portátil sería elegir una ubicación estándar para un archivo que creará su propia aplicación, p. /etc/YOURAPP.cfg y almacena un UUID allí si todavía no existe uno.

Lejos de ser ideal, ya que otra persona o aplicación podría eliminar el archivo o cambiarlo, o si el usuario cambió el sistema de archivos raíz podría perder la ID de la máquina actual o podría aparecer en otra máquina . Por no mencionar los problemas con los permisos de lectura y escritura, etc.

Pero al final no existe la "misma máquina". Cualquier computadora no es más ni menos que sus componentes + configuración actual. No creo que puedas hacer nada mejor que esto, de forma portátil.

Cuestiones relacionadas