Подтвердить что ты не робот

Получение уникального идентификатора из unix-подобной системы

Я хочу получить из любой Unix-подобной системы (если это возможно) уникальный идентификатор, который будет постоянным каждый раз, когда мое приложение будет работать на одном компьютере. Если это возможно, я хочу получить тот же идентификатор из Linux или FreeBSD или Solaris и т.д. Я не хочу генерировать новый идентификатор для каждой машины, но получить уже существующий идентификатор, и я предпочитаю этот идентификатор поступают из операционной системы, и я не предпочитаю использовать что-то вроде MAC-адреса.

Если нет другой доступной опции, я могу использовать MAC в сочетании с чем-то другим, например, id может быть хешем md5 комбинации MAC-адреса и чего-то еще.

Я хотел бы выслушать ваши предложения.

Если это полезно, мое приложение написано на C/С++.

Цель всего этого - запретить пользователю запускать мое приложение два или более раз. Я хочу запустить только один раз.

4b9b3361

Ответ 1

Как насчет UUID корневой файловой системы? Вы можете получить корневое файловое устройство с /etc/fstab, либо вручную разобрав файл, либо используя getfsent (3) или getfsfile (3). После того, как у вас есть устройство, вы можете получить UUID, либо проверив ссылки в /dev/disk/by-uuid, либо из команды blkid.

Ответ 2

Оба Solaris и Linux предоставляют утилиту hostid (1)

Ответ 3

Лучший способ, как обычно, - увидеть, как другие люди уже решили одну и ту же проблему.

FLEXlm также использует идентификатор хоста для своих node -блокированных лицензий. Самым распространенным идентификатором хоста, который он использует, является MAC-адрес Ethernet для одного из ваших сетевых интерфейсов, разбитый вместе без разделителя.

Он также может использовать (в Windows) серийный номер тома диска C: (снова разбитый без каких-либо разделителей), а на Solaris - вывод команды hostid (IIRC, на компьютерах Sun, это число фактически уникальным и расположен на небольшой съемной EEPROM на системной плате).

В то время как MAC-адрес чрезвычайно легко подделать, он является почти универсальным идентификатором в настоящее время (почти все новые компьютеры имеют по крайней мере один Ethernet-порт, и для них очень часто приходится находиться на борту) и на самом деле должны быть глобальными (на самом деле, протоколы Ethernet зависят от этой уникальности). Основные проблемы, которые вы имели бы с этим подходом:

  • Некоторые компьютеры имеют несколько адресов Ethernet; некоторые из них находятся на основной плате, некоторые из них находятся на отдельных съемных карточках.
  • Они очень легко подделать (и некоторые протоколы зависят от возможности их изменения).
  • Некоторые виртуализированные среды генерируют случайные адреса Ethernet для каждой загрузки (но обычно они имеют способ принудительного фиксированного значения).

Ответ 4

Другим вариантом является использование информации, полученной из dmidecode, команды, присутствующей в Linux. Эта информация декодируется из /dev/mem, поэтому требуется доступ root.

Известно, что чтение информации dmidecode ошибочно, так как некоторые производители материнских плат лежат или подделывают некоторые из полей.

Ответ 5

Нет общего и надежного способа получить то, что вы хотите.

Ответ 6

Я не думаю, что это возможно. Самое близкое, что вы можете получить, - создать очень длинную случайную строку (например, MS с GUID) и сохранить ее где-нибудь в вашей системе.

Ответ 7

Вы должны учитывать, что многие настройки могут создать образ файловой системы и клонировать на многие машины, а не настраивать их отдельно. В других случаях машина может переустанавливаться многократно. Другими словами, все, что предоставлено ОС, нельзя доверять.

Однако ЦП сохраняет уникальный серийный номер, но доступ к нему должен быть различным в разных системах.

Ответ 8

Вы не указываете, насколько стабильным должен быть уникальный идентификатор - всегда ли вы хотите, чтобы один и тот же хост выдавал одинаковый идентификатор каждый раз, когда ваш код запускается?

Если нет, то fuzymonk предлагает uuidgen то, что вы хотите.

Если да, то вам нужно решить, что составляет "то же самое", что и принимающий. Один из способов был бы таким, как вы предполагаете, суммой MD5 MAC-адреса первого интерфейса Ethernet и "чем-то". Для "чего-то" в этом случае я бы рассмотрел полное доменное имя, если ваше понятие о "том же хосте" не включает в себя изменение FQDN...

Ответ 9

Вы можете получить UUID корневой файловой системы /, которая достаточно надежна, но не будет различать chroots и, возможно, vms, запущенные на том же диске.

Если вы в основном работаете с внутренним или статическим жестким диском, предназначенным для работы с конкретной ОС, вы должны иметь возможность использовать UUID корневой файловой системы для обнаружения системы.

Вы можете получить UUID корневого fs с чем-то вроде этого: alias sys_guid='sudo /sbin/blkid | grep "$(df -h / | sed -n 2p | cut -d" " -f1):" | grep -o "UUID=\"[^\"]*\" " | sed "s/UUID=\"//;s/\"//"'

Если вам нужно дополнительно различать версии ядра одной и той же ОС или разные ОС, запущенные на одном диске, вы можете использовать данные из uname и/или комбинировать их с UUID корня fs.

Ответ 10

Похоже, вы ищете UUID. Это общий универсально уникальный идентификатор (действительно, то же, что и GUID)

Существует много реализаций С++ этого в разных библиотеках, или вы можете использовать команду uuidgen и захватить вывод.

Ответ 11

Большинство unix-подобных машин имеют генератор случайных чисел, доступный через /dev/random. Вам понадобится что-то вроде MAC-адреса и время, чтобы дать подлинную уникальность генератору GUID (это то, что делает GUID-генератор в Windows). Кроме того, получение чего-либо из /dev/random даст вам достаточно хорошую конструкцию GUID-типа. На практике библиотеки UUID выполняют такие вещи за кулисами.

Если вам нужен только один номер на машину, возможно, будет достаточно MAC-адреса. Они управляются центральным органом, и можно разумно предположить, что никакие два MAC-адреса не будут одинаковыми. Однако, если вы пытаетесь использовать это, чтобы связать установку программного обеспечения с MAC-адресом, имейте в виду, что некоторые компоненты имеют программируемые MAC-адреса или программируемые компоненты MAC-адреса. Unix-подобные операционные системы, особенно с открытым исходным кодом, обычно не имеют жестких серийных номеров. Такой подход может также вызвать проблемы с запуском нескольких экземпляров программного обеспечения в виртуальных машинах.

Одним из вариантов может быть USB ключ,, который может быть получен от нескольких производителей. Другой вариант может быть сервером лицензий, где уникальный код предоставляется серверу. Опять же, несколько консервированных решений для этого доступны из разных источников.

Ответ 12

Вы упомянули, что в Windows вы используете некоторый GUID... У вас есть некоторые подробности о том, как он создан?

Кроме того, вы можете попробовать что-то вроде идентификатора CPU или идентификатора жесткого диска... Я полагаю, что эти изменения не могут быть изменены (но вы столкнулись с трудностями при замене неисправного жесткого диска).

Ответ 13

Ответы Джейсона Дэй и А.Данищевского кажутся на правильном пути, но не соответствуют вашим критериям любой "Unix-подобной системы", поскольку /sbin/blkid и /etc/fstab не существуют на OSX.

Единственным 100% -ным переносным подходом было бы выбрать стандартное местоположение для файла, создаваемого вашим собственным приложением, например. /etc/YOURAPP.cfg и сохраните там UUID, если он еще не существует.

Вдали от идеала, поскольку другой человек или приложение может удалить файл или изменить его, или если пользователь изменил корневую файловую систему, вы можете потерять идентификатор с текущего компьютера, или он может возникнуть на другом компьютере. Не говоря уже о проблемах с разрешениями на чтение и запись и т.д.

Но в конце нет такой вещи, как "одна и та же машина". Любой компьютер не больше и не меньше его компонентов + текущая конфигурация. Я не думаю, что вы можете сделать это лучше, чем это возможно.

Ответ 14

Вы можете использовать файл блокировки в таких местах, как:

  • /var/run/yourapp.pid(если программа выполняется от root)
  • $HOME/.yourapp.pid(если выполняется пользователем и локальной файловой системой)
  • $HOME/.yourapp. $(hostname -f).pid(home on nfs)

Когда ваша программа запущена, она должна сделать что-то вроде:

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

Если сбой сбоя, проверьте, все ли запущен процесс, а если нет: удалите файл и повторите попытку.