Назад | Перейти на главную страницу

как сгенерировать случайный MAC-адрес из командной строки Linux

Как сгенерировать случайный MAC-адрес из командной строки Linux?

Я ищу решение, для которого требуются только стандартные инструменты, которые обычно можно найти в командной строке Linux.

MAC-адрес будет использоваться для гостевого KVM.

я использую

macaddr=$(echo $FQDN|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')

Преимущество этого метода по сравнению с полностью случайным числом заключается в том, что можно надежно воспроизвести MAC-адрес на основе полного доменного имени машины, что иногда мне кажется полезным. В 02 для первого октета просто устанавливается бит «назначенного локально», что делает очевидным, что это не MAC-адрес, предоставленный производителем, и гарантирует, что вы не столкнетесь с MAC-адресом реального сетевого адаптера.

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

Опубликованные скрипты хороши, но хочу добавить предупреждение: помните день рождения (парадоксон)!

Это происходит из-за того, что даже если у вас всего 23 человека, вероятность того, что у двоих из них день рождения в один и тот же день, составляет 50%.

Это зависит от вашего сценария, как вы его используете, но если вы генерируете MACS случайным образом, примерно при 1 миллионе ваш шанс на конфликт номеров Mac составляет 40%, при 2 миллионах это уже 87%!

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

Эти варианты тоже работают.

дольше:

openssl rand -hex 6 | sed 's/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1:\2:\3:\4:\5:\6/'

или короче:

openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/:$//'

Согласно быстрому измерению во времени, потребление нагрузки обоих вариантов очень похоже.

myserver% perl -e 'for ($i=0;$i<6;$i++){@m[$i]=int(rand(256));} printf "%X:%X:%X:%X:%X:%X\n",@m;'
55:C2:A5:FA:17:74

Ах, старый Швейцарская армейская бензопила снова едет. А в версии 0.2 я беззастенчиво краду отличное замечание womble о том, что первым октетом является 02:

myserver% perl -e 'for ($i=0;$i<5;$i++){@m[$i]=int(rand(256));} printf "02:%X:%X:%X:%X:%X\n",@m;'
02:8E:94:A3:47:26

Я знаю, что этот пост старый, но для будущих посетителей, если вам нужен криптографически безопасный псевдослучайный MAC-адрес, не ограничиваясь 0x02 в качестве OUI, вот быстрый, в основном независимый от платформы генератор:

$ printf '%02x' $((0x$(od /dev/urandom -N1 -t x1 -An | cut -c 2-) & 0xFE | 0x02)); od /dev/urandom -N5 -t x1 -An | sed 's/ /:/g'

Вот еще один, основанный на ответе вомби:

macaddr=$(dd if=/dev/urandom bs=1024 count=1 2>/dev/null|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4:\5:\6/')
echo $macaddr

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

jot -w%02X -s: -r 6 1 256
openssl rand -hex 6|fold -w2|paste -sd: -
od -N6 -tx1 -An /dev/random|awk '$1=$1'|tr \  :
god -N6 -tx1 -An /dev/random|cut -c2-|tr \  :
hexdump -n6 -e'/1 ":%02X"' /dev/random|cut -c2-

jot поставляется с OS X и BSD, но не с большинством дистрибутивов Linux. В jot -w меняет формат, -s меняет разделитель, и -r генерирует случайные числа.

od находится в POSIX, но hexdump не является.

OS X od (/usr/bin/od ниже) использует другой формат вывода, чем GNU od:

$ /usr/bin/od -N6 -tx1 -An /dev/random|tr ' ' :
:::::::::::d9::b9::d7::da::5f::96::::::::::::::::::::::::::::::::::::::::
$ god -N6 -tx1 -An /dev/random|tr ' ' :
:f5:6d:0a:3b:39:f9

В OS X od параметры, помещенные после аргумента для входного файла, обрабатываются как имена входных файлов, поэтому команда в ответе Аарона Топонсе читает из /dev/urandom бесконечно с OS X od.

Я использую:

echo -n 02; od -t x1 -An -N 5 /dev/urandom | tr ' ' ':'

Вы можете просто добавить $ RANDOM после $ FQDN, и это даст вам случайные MAC-адреса при каждом запуске. Это особенно полезно для пользователей, которые хотят создавать резервные виртуальные машины, используя моментальные снимки или клоны виртуальных машин.

macaddr=$(echo $FQDN$RANDOM|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')

Однострочный Python:

python3 -c 'import os; print(":".join(["{:02x}".format(x) for x in b"\02x" + os.urandom(5)]))'

Ради удовольствия, вот чистая версия bash, протестированная против выпуска Bash 4.4.12 (1):

read -N6 b </dev/urandom
LC_ALL=C printf "%02x:%02x:%02x:%02x:%02x:%02x\n" "'${b:0:1}" "'${b:1:1}" "'${b:2:1}" "'${b:3:1}" "'${b:4:1}" "'${b:5:1}"

Первая строка читает 6 символов из /dev/urandom; затем, используя набор символов C, напечатайте заполненное 0 шестнадцатеричное значение каждого символа, разделенное двоеточием (новая строка является необязательной, но полезна для вывода значения).

Поскольку вы можете печатать прямо в переменную с помощью printf -v myvar для захвата результата не требуется вилки / подоболочки.

Извлечение значения символа с помощью printf определено в POSIX. printf документация:

Если ведущий символ - это одинарная или двойная кавычка, значение должно быть числовым значением в базовом кодовом наборе символа, следующего за одинарной или двойной кавычкой.

NB: read не будет блокировать /dev/urandom, поэтому он может вернуться раньше, в результате чего все последние байты MAC будут нулевыми. Это будет особенно заметно при запуске в бедренном цикле или если другое приложение одновременно выполняет тяжелые чтения из /dev/urandom.