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


26

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

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

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

Ответы:


46

я использую

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

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

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


+1 за воспроизводимость; для определенных применений это делает его намного лучшим методом по сравнению с моим.
MadHatter поддерживает Монику

Большое спасибо, мне нравится идея воспроизводимости.
Эрик Шёлунд

Кроме того, нет никаких конфликтов MAC-адресов в маловероятном случае, когда вы случайно сгенерируете один и тот же Mac дважды
Petter H

3
В качестве альтернативы вы можете использоватьtr -dc A-F0-9 < /dev/urandom | head -c 10 | sed -r 's/(..)/\1:/g;s/:$//;s/^/02:/'
ALex_hha

1
Это всего лишь «альтернатива» в том смысле, что она дает совершенно иной конечный результат, чем мой фрагмент ...
womble

8

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

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

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

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


Спасибо за предупреждение о парадоксе Дня Рождения! В моем случае я рискну, так как сгенерирую около 20 MAC-адресов.
Эрик Шёлунд

3
Если вы используете сотни серверов, на каждом из которых размещены десятки виртуальных машин в одном и том же широковещательном домене, у вас больше проблем, чем риск конфликта MAC-адресов.
womble

1
« Это связано с тем, что даже если у вас всего 23 человека, вероятность того, что у 2 из них будет день рождения в один и тот же день, уже составляет 50% ». Это даже отдаленно не верно. Существует около 50% вероятности того, что два из 23 человек имеют одинаковую годовщину, а не один и тот же день рождения.
Рон Мопин

5
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, я без стеснения краду отличную мысль Уомбла о том, что первый октет - 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

Спасибо MadHatter, я попробовал ваш второй вариант, и он сработал. Очень хорошо!
Эрик Шёлунд

5

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

больше:

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

или короче:

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

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


Привет Энтони, я не вижу другого варианта, объединяющего openssl rand и sed здесь, так что это уникальное решение в этой теме.
Ярослав Кучера

Это правда. Он / она использовал fold -w2|paste -sd: -вместо sed. sedРешение, вероятно , легче запомнить , как он использует более привычный инструмент - хотя я узнал больше от его / ее ответа.
Энтони Дж. - правосудие для Моники

Я думаю, что первая команда не будет работать, потому что она не устанавливает первый бит равным!
amrx

Привет @amrx, ты уверен, что первый бит MAC должен быть четным? У меня есть NIC на одном из моих серверов, который начинается с ec11101100 в двоичном виде ...
Ярослав Кучера

1
Привет @JaroslavKucera, MAC-адреса Unicast никогда не должны устанавливать бит 1 в первом байте. Это бит группы (многоадресная / широковещательная передача). Если вы создаете свой собственный MAC-адрес, вы должны установить бит места 2 («локально управляемый» бит) в первом байте, чтобы отличить его от гарантированного глобально уникального MAC-адреса.
AMRX

4

Я знаю, что этот пост старый, но для будущих посетителей, если вы хотите криптографически безопасный псевдослучайный 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'

2

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

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

Нет необходимости запускать выход urandom через md5sum; Вы можете просто использовать od согласно ответу Аарона Топонсе.
womble

2

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

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вариантах помещены после того, как аргумент для входного файла рассматриваются как имена входных файлов, так что команда в ответе Аарона Toponce читает на /dev/urandomнеопределенное время с OS иксов od.


1

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

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

1
Обратите внимание, что $ RANDOM доступен в bash, но может быть недоступен в других оболочках.
Майкл Хэмптон


0

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

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

0

Просто для удовольствия, вот чистая версия 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 определено в документации по POSIX printf :

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.