Cómo generar una dirección MAC aleatoria desde la línea de comandos de Linux

26

¿Cómo genero una dirección MAC aleatoria desde la línea de comandos de Linux?

Busco una solución que solo requiera herramientas estándar que se encuentran comúnmente en la línea de comandos de Linux.

La dirección MAC se usará para un KVM invitado.

Erik Sjölund
fuente

Respuestas:

46

yo suelo

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

El beneficio de este método, sobre un número completamente aleatorio, es que es posible reproducir de manera confiable la dirección MAC basada en el FQDN de la máquina, lo que a veces encuentro útil. El 02primer octeto solo establece el bit "asignado localmente", lo que hace obvio que no es una dirección MAC proporcionada por el proveedor, y garantiza que no colisionará con una dirección MAC de una NIC real.

Si necesita generar múltiples direcciones MAC por host, solía concatenar el FQDN con el nombre del puente para conectar la interfaz; esto hizo un buen trabajo al difundir las cosas para diferentes NIC.

womble
fuente
+1 para la reproducibilidad; para ciertas aplicaciones, eso lo convierte en un método muy superior al mío.
MadHatter apoya a Monica el
Muchas gracias, me gusta la idea de que sea reproducible.
Erik Sjölund
Además, no hay conflictos de direcciones de Mac en el improbable caso de que genere aleatoriamente la misma Mac dos veces
Petter H
3
Como alternativa puede usartr -dc A-F0-9 < /dev/urandom | head -c 10 | sed -r 's/(..)/\1:/g;s/:$//;s/^/02:/'
ALex_hha
1
Es solo una "alternativa" en el sentido de que produce un resultado final completamente diferente a lo que hace mi fragmento ...
womble
8

Los guiones publicados son buenos, pero quiero agregar una advertencia: ¡Cuidado con el cumpleaños (paradoja)!

Viene del hecho de que incluso si tiene solo 23 personas, la probabilidad de que 2 de ellos cumplan años el mismo día es ya del 50%.

Depende de su escenario cómo lo use, pero si genera el MACS al azar, con aproximadamente 1 millón, su probabilidad de un choque de números mac es del 40% a 2 millones, ¡ya es del 87%!

Si necesita solo un par, esto está bien, pero cuando mantiene una granja de servidores con cientos de servidores, cada uno de ellos aloja decenas de máquinas virtuales, o si usa los Mac como índice en alguna base de datos para la contabilidad y necesita exclusivos, tenga cuidado !

flolo
fuente
¡Gracias por la advertencia sobre la paradoja del cumpleaños! En mi caso, me arriesgaré, ya que generaré alrededor de 20 direcciones MAC.
Erik Sjölund
3
Si está ejecutando cientos de servidores, cada uno de los cuales aloja decenas de máquinas virtuales, todas en el mismo dominio de difusión, tiene mayores problemas que el riesgo de colisión de direcciones MAC.
womble
1
" Viene del hecho de que incluso si tienes solo 23 personas, la probabilidad ya es del 50% de que 2 de ellos cumplan años el mismo día " . Eso ni siquiera es remotamente cierto. Hay alrededor de un 50% de posibilidades de que dos de 23 personas tengan el mismo aniversario de cumpleaños, no el mismo cumpleaños.
Ron Maupin
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

Ah, la vieja motosierra del ejército suizo vuelve a montar. Y a través de la versión 0.2, estoy robando descaradamente el excelente punto de womble sobre el primer octeto que es 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 apoya a Monica
fuente
Gracias MadHatter, probé tu segunda variante y funcionó. ¡Muy agradable!
Erik Sjölund
5

Estas variantes también funcionan.

más:

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

o más corto:

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

El consumo de carga de ambas variantes es muy similar según la medición rápida con el tiempo.

Jaroslav Kucera
fuente
Hola Anthony, no veo otra variante que combine openssl rand y sed aquí, así que esta es una solución única en este tema.
Jaroslav Kucera
Es verdad. Él / ella usó en fold -w2|paste -sd: -lugar de sed. La sedsolución es probablemente más fácil de recordar, ya que utiliza una herramienta más familiar, aunque aprendí más de su respuesta.
Anthony G - justicia para Mónica
¡Creo que el primer comando no funcionará porque no establece que el primer bit sea par!
amrx
Hola @amrx, ¿estás seguro de que el primer bit de MAC debe ser parejo? Tengo NIC en uno de mis servidores, que comienza con ec11101100 en binario ...
Jaroslav Kucera
1
Hola @JaroslavKucera, las direcciones MAC de unidifusión nunca deben establecer el bit de lugar del 1 en el primer byte. Ese es el bit de "grupo" (multidifusión / difusión). Si crea su propia dirección MAC, se supone que debe establecer el bit de lugar de los 2 (el bit "administrado localmente") en el primer byte, para diferenciarlo de una dirección MAC global garantizada.
amrx
4

Sé que esta publicación es antigua, pero para futuros visitantes, si desea una dirección MAC pseudoaleatoria criptográficamente segura, sin limitarse a 0x02 como OUI, aquí hay un generador agnóstico de plataforma en su mayoría rápido:

$ 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'
Aaron Toponce
fuente
2

Aquí hay otro, basado en la respuesta de wombie:

macaddr=$(dd if=/dev/urandom bs=1024 count=1 2>/dev/null|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4:\5:\6/')
echo $macaddr
gucki
fuente
No es necesario ejecutar la salida urandom a través de md5sum; puedes usar od según la respuesta de Aaron Toponce.
womble
2

Aquí hay otras cinco opciones, todas las cuales usan bits aleatorios para el bit menos significativo del byte más significativo que indica si la dirección es unidifusión o multidifusión y para el segundo bit menos significativo del byte más significativo que indica si la dirección es administrada universal o localmente.

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-

jotviene con OS X y BSD pero no con la mayoría de las distribuciones de Linux. En jot -wcambia el formato, -scambia el separador y -rgenera números aleatorios.

odestá en POSIX pero hexdumpno lo está.

OS X od( /usr/bin/odabajo) usa un formato de salida diferente que 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

En las odopciones de OS X colocadas después de un argumento para un archivo de entrada se tratan como los nombres de los archivos de entrada, por lo que el comando en la respuesta de Aaron Toponce se lee /dev/urandomindefinidamente con OS X's od.

nisetama
fuente
1

Simplemente puede agregar un $ RANDOM después de $ FQDN y esto le daría direcciones MAC aleatorias cada vez que lo ejecute. Esto es especialmente útil para las personas que desean crear una copia de seguridad de vms utilizando instantáneas o clones de vms.

macaddr=$(echo $FQDN$RANDOM|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
Azogue
fuente
1
Tenga en cuenta que $ RANDOM está disponible en bash, pero puede no estar disponible en otros shells.
Michael Hampton
0

Yo suelo:

echo -n 02; od -t x1 -An -N 5 /dev/urandom | tr ' ' ':'
Jérôme Pouiller
fuente
0

Python one-liner:

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

Solo por diversión, aquí hay una versión de bash puro, probada contra Bash 4.4.12 (1) -lanzamiento:

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}"

La primera línea lee 6 caracteres de /dev/urandom; luego, utilizando el juego de caracteres C, imprima el valor hexadecimal lleno de 0 de cada carácter separado con dos puntos (la nueva línea es opcional pero útil para imprimir el valor).

La extracción del valor de un carácter usando printf se define en la documentación POSIX printf :

Si el carácter inicial es una comilla simple o una comilla doble, el valor será el valor numérico en el conjunto de códigos subyacente del carácter que sigue a la comilla simple o la comilla doble.

Thomas Guyot-Sionnest
fuente