comment générer une adresse MAC aléatoire à partir de la ligne de commande Linux

26

Comment générer une adresse MAC aléatoire à partir de la ligne de commande Linux?

Je recherche une solution qui ne nécessite que des outils standard couramment trouvés sur la ligne de commande Linux.

L'adresse MAC sera utilisée pour un KVM invité.

Erik Sjölund
la source

Réponses:

46

j'utilise

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

L'avantage de cette méthode, par rapport à un nombre complètement aléatoire, est qu'il est possible de reproduire de manière fiable l'adresse MAC en fonction du FQDN de la machine, ce que je trouve parfois utile. Le 02premier octet positionne simplement le bit "assigné localement", ce qui rend évident qu'il ne s'agit pas d'une adresse MAC fournie par le fournisseur et garantit que vous ne heurterez pas l'adresse MAC réelle d'une carte réseau.

Si vous devez générer plusieurs adresses MAC par hôte, j'ai utilisé pour concaténer le nom de domaine complet avec le nom du pont auquel connecter l'interface; cela a bien réussi à répartir les choses entre les différentes cartes réseau.

womble
la source
+1 pour la reproductibilité; pour certaines applications, cela en fait une méthode bien supérieure à la mienne.
MadHatter prend en charge Monica
Merci beaucoup, j'aime l'idée de la reproduire.
Erik Sjölund
De plus, aucun conflit d'adresse mac dans le cas improbable où vous généreriez au hasard le même mac deux fois
Petter H
3
Comme alternative, vous pouvez utilisertr -dc A-F0-9 < /dev/urandom | head -c 10 | sed -r 's/(..)/\1:/g;s/:$//;s/^/02:/'
ALex_hha
1
Ce n'est qu'une "alternative" dans le sens où elle produit un résultat final complètement différent de ce que fait mon extrait de
code
8

Les scripts publiés sont bons, mais je veux ajouter un avertissement: Mind the Birthday (paradoxon)!

Cela vient du fait que même si vous n'avez que 23 personnes, il y a déjà 50% de chances que 2 d'entre elles fêtent leur anniversaire le même jour.

Cela dépend de votre scénario, de la façon dont vous l'utilisez, mais si vous générez le MACS au hasard, à environ 1 million, votre chance pour un conflit de numéros mac est de 40% à 2 millions, c'est déjà 87%!

Si vous n'avez besoin que de quelques, c'est correct, mais lorsque vous gérez une batterie de serveurs avec des centaines de serveurs, chacun d'entre eux hébergeant des dizaines de machines virtuelles, ou si vous utilisez les macs comme index dans une base de données pour la comptabilité et que vous avez besoin d'uniques, soyez prudent !

flolo
la source
Merci pour l'avertissement concernant le paradoxe anniversaire! Dans mon cas, je prendrai le risque car je générerai environ 20 adresses MAC.
Erik Sjölund
3
Si vous exécutez des centaines de serveurs hébergeant chacun des dizaines de machines virtuelles sur le même domaine de diffusion, vous avez des problèmes plus importants que le risque de collision d'adresses MAC.
womble
1
" Cela vient du fait que même si vous n'avez que 23 personnes, il y a déjà 50% de chances que 2 d'entre elles fêtent leur anniversaire le même jour. " Ce n'est même pas vrai à distance. Il y a environ 50% de chances que deux des 23 personnes aient le même anniversaire, pas le même anniversaire.
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 vieille tronçonneuse de l'armée suisse chevauche à nouveau. Et par le biais de la version 0.2, je vole sans vergogne l'excellent point de womble sur le premier octet étant 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 soutient Monica
la source
Merci MadHatter, j'ai essayé votre deuxième variante et cela a fonctionné. Très agréable!
Erik Sjölund
5

Ces variantes fonctionnent également.

plus long:

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

ou plus court:

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

La consommation de charge des deux variantes est très similaire selon une mesure rapide avec le temps.

Jaroslav Kucera
la source
Salut Anthony, je ne vois aucune autre variante combinant openssl rand et sed ici, c'est donc une solution unique dans ce sujet.
Jaroslav Kucera
C'est vrai. Il / elle a utilisé fold -w2|paste -sd: -au lieu de sed. La sedsolution est probablement plus facile à retenir car elle utilise un outil plus familier - même si j'ai appris plus de sa réponse.
Anthony G - justice pour Monica
Je pense que la première commande ne fonctionnera pas car elle ne définit pas le premier bit pour être pair!
amrx
Salut @amrx, êtes-vous sûr que le premier bit de MAC doit être pair? J'ai une carte réseau dans l'un de mes serveurs, qui commence par ecdonc 11101100 en binaire ...
Jaroslav Kucera
1
Bonjour @ JaroslavKucera, les adresses MAC Unicast ne doivent jamais définir le bit de place du 1 dans le premier octet. C'est le bit "groupe" (multidiffusion / diffusion). Si vous créez votre propre adresse MAC, vous êtes censé définir le bit de place 2 (le bit «administré localement») dans le premier octet, pour le différencier d'une adresse MAC garantie globalement unique.
amrx
4

Je sais que ce message est ancien, mais pour les futurs visiteurs, si vous voulez une adresse MAC pseudo-aléatoire sécurisée cryptographiquement, sans être limitée à 0x02 en tant qu'OUI, voici un générateur agnostique rapide pour la plupart des plateformes:

$ 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
la source
2

En voici un autre, basé sur la réponse 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
la source
Il n'est pas nécessaire d'exécuter la sortie urandom via md5sum; vous pouvez simplement utiliser od selon la réponse d'Aaron Toponce.
womble
2

Voici cinq autres options, qui utilisent toutes des bits aléatoires pour le bit le moins significatif de l'octet le plus significatif qui indique si l'adresse est unicast ou multicast et pour le deuxième bit le moins significatif de l'octet le plus significatif qui indique si l'adresse est universellement ou localement administré.

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-

jotest livré avec OS X et BSD mais pas avec la plupart des distributions Linux. Dans jot -wchange le format, -schange le séparateur et -rgénère des nombres aléatoires.

odest en POSIX mais hexdumpne l'est pas.

OS X od( /usr/bin/odci-dessous) utilise un format de sortie différent de 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

Dans de OS X odoptions placées après un argument pour un fichier d'entrée sont traités comme les noms des fichiers d'entrée, de sorte que la commande dans la réponse par Aaron Toponce lit à partir /dev/urandomindéfiniment avec OS X de od.

nisetama
la source
1

Vous pouvez simplement ajouter un $ RANDOM après $ FQDN et cela vous donnera des adresses mac aléatoires à chaque fois que vous l'exécuterez. Ceci est particulièrement utile pour les personnes qui souhaitent créer des vms de sauvegarde en utilisant des instantanés ou des clones de vms.

macaddr=$(echo $FQDN$RANDOM|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
Mercure
la source
1
Notez que $ RANDOM est disponible dans bash, mais peut ne pas être disponible dans d'autres shells.
Michael Hampton
0

J'utilise:

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

Une doublure en Python:

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

Juste pour le plaisir, voici une version pure bash, testée contre Bash 4.4.12 (1) -release:

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 première ligne lit 6 caractères /dev/urandom; puis en utilisant le jeu de caractères C, imprimez la valeur hexadécimale remplie de 0 de chaque caractère séparé par deux points (la nouvelle ligne est facultative mais utile pour imprimer la valeur).

L'extraction de la valeur d'un caractère à l'aide de printf est définie dans la documentation POSIX printf :

Si le caractère de début est un guillemet simple ou un guillemet double, la valeur doit être la valeur numérique dans le jeu de codes sous-jacent du caractère suivant le guillemet simple ou le guillemet double.

Thomas Guyot-Sionnest
la source