Как сгенерировать случайный 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
.