como gerar um endereço MAC aleatório a partir da linha de comando do Linux

26

Como faço para gerar um endereço MAC aleatório a partir da linha de comando do Linux?

Eu procuro uma solução que requer apenas ferramentas padrão comumente encontradas na linha de comando do Linux.

O endereço MAC será usado para um KVM convidado.

Erik Sjölund
fonte

Respostas:

46

eu uso

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

A vantagem desse método, em relação a um número completamente aleatório, é que é possível reproduzir de forma confiável o endereço MAC com base no FQDN da máquina, que às vezes acho útil. O 02primeiro octeto define apenas o bit "atribuído localmente", o que torna óbvio que não é um endereço MAC fornecido pelo fornecedor e garante que você não colidirá com o endereço MAC de uma NIC real.

Se você precisar gerar vários endereços MAC por host, eu costumava concatenar o FQDN com o nome da ponte à qual conectar a interface; isso fez um bom trabalho em espalhar as coisas para diferentes placas de rede.

mulher
fonte
+1 para a reprodutibilidade; para certas aplicações, isso o torna um método muito superior ao meu.
MadHatter apoia Monica
Muito obrigado, gosto da ideia de reproduzi-lo.
Erik Sjölund
Além disso, há conflitos de endereços MAC no caso improvável de que você gerar aleatoriamente o mesmo mac duas vezes
Petter H
3
Como alternativa, você pode usartr -dc A-F0-9 < /dev/urandom | head -c 10 | sed -r 's/(..)/\1:/g;s/:$//;s/^/02:/'
ALex_hha
1
É apenas uma "alternativa", no sentido de que produz um resultado final completamente diferente do que meu snippet faz ...
womble
8

Os scripts publicados são bons, mas quero acrescentar um aviso: Cuidado com o aniversário (paradoxon)!

Isso se deve ao fato de que, mesmo que você tenha apenas 23 pessoas, a chance já é de 50% de que 2 deles tenham aniversário no mesmo dia.

Depende do seu cenário, como você o usa, mas se você gerar o MACS aleatoriamente, em aproximadamente 1 milhão de chances de um confronto com o número de mac será de 40% a 2 milhões, já será de 87%!

Se você precisar de apenas alguns, tudo bem, mas quando você mantém um farm de servidores com centenas de servidores, cada um hospedando dezenas de máquinas virtuais, ou se você usa os macs como índice em alguns bancos de dados para contabilidade e precisa de cuidados especiais !

flolo
fonte
Obrigado, pelo aviso sobre o paradoxo do aniversário! No meu caso, assumirei o risco, pois gerarei cerca de 20 endereços MAC.
Erik Sjölund
3
Se você estiver executando centenas de servidores, cada um hospedando dezenas de máquinas virtuais no mesmo domínio de broadcast, você terá problemas maiores que o risco de colisão de endereço MAC.
womble
1
" Isso se deve ao fato de que, mesmo que você tenha apenas 23 pessoas, a chance já é de 50% de que dois deles tenham aniversário no mesmo dia. " Isso não é nem remotamente verdade. Há cerca de 50% de chance de duas das 23 pessoas terem o mesmo aniversário de aniversário, não o mesmo aniversário.
Ron Maupin 29/07
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, a velha serra elétrica do exército suíço volta a andar. E, na versão 0.2, estou descaradamente roubando o excelente argumento de womble sobre o primeiro octeto ser 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 apoia Monica
fonte
Obrigado MadHatter, tentei sua segunda variante e funcionou. Muito agradável!
Erik Sjölund
5

Essas variantes também funcionam.

mais longo:

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

ou mais curto:

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

O consumo de carga de ambas as variantes é muito semelhante, de acordo com a medição rápida com o tempo.

Jaroslav Kucera
fonte
Olá Anthony, não vejo nenhuma outra variante combinando openssl rand e sed aqui, portanto essa é uma solução exclusiva neste tópico.
Jaroslav Kucera
Isso é verdade. Ele / ela usou em fold -w2|paste -sd: -vez de sed. A sedsolução é provavelmente mais fácil de lembrar, pois usa uma ferramenta mais familiar - embora eu tenha aprendido mais com a resposta dele / dela.
Anthony G - justice para Monica
Acho que o primeiro comando não funcionará porque não define o primeiro bit para ser par!
Amrx
Oi @amrx, você tem certeza que o primeiro bit do MAC deve ser par? Eu tenho NIC em um dos meus servidores, que começa com ectão 11101100 em binário ...
Jaroslav Kucera
1
Olá @JaroslavKucera, os endereços MAC Unicast nunca devem definir o bit de 1 no primeiro byte. Esse é o bit "group" (multicast / broadcast). Se você criar seu próprio endereço MAC, deverá definir o bit de lugar do 2 (o bit "administrado localmente") no primeiro byte, para diferenciá-lo de um endereço MAC garantido globalmente exclusivo.
Amrx
4

Sei que este post é antigo, mas para futuros visitantes, se você quiser um endereço MAC pseudo-aleatório criptograficamente seguro, sem se limitar a 0x02 como OUI, aqui está um rápido gerador independente de plataforma:

$ 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
fonte
2

Aqui está outro, baseado na resposta do 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
fonte
Não há necessidade de executar a saída urandom através do md5sum; você pode usar od de acordo com a resposta de Aaron Toponce.
womble
2

Aqui estão cinco outras opções, que usam bits aleatórios para o bit menos significativo do byte mais significativo que indica se o endereço é unicast ou multicast e para o segundo bit menos significativo do byte mais significativo que indica se o endereço é administrado universal ou 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-

jotvem com OS X e BSDs, mas não com a maioria das distribuições Linux. Em jot -waltera o formato, -smuda o separador, e -rgera números aleatórios.

odestá no POSIX, mas hexdumpnão está.

OS X od( /usr/bin/odabaixo) usa um formato de saída diferente do 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

Em OS X odopções colocadas após um argumento para um arquivo de entrada são tratados como os nomes dos arquivos de entrada, de modo que o comando na resposta por Aaron Toponce lê /dev/urandomindefinidamente com OS X do od.

nisetama
fonte
1

Você pode apenas adicionar um $ RANDOM após $ FQDN e isso fornecerá endereços MAC aleatórios toda vez que você o executar. Isso é especialmente útil para pessoas que desejam criar vms de backup usando instantâneos ou clones de vms.

macaddr=$(echo $FQDN$RANDOM|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
Mercúrio
fonte
1
Observe que $ RANDOM está disponível no bash, mas pode não estar disponível em outros shells.
Michael Hampton
0

Eu uso:

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

One-liner do Python:

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

Apenas por diversão, aqui está uma versão pura do bash, testada com o lançamento do 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}"

Primeira linha lê 6 caracteres /dev/urandom; em seguida, usando o conjunto de caracteres C, imprima o valor hexadecimal preenchido com 0 de cada caractere separado por dois pontos (a nova linha é opcional, mas útil para imprimir o valor).

A extração do valor de um caractere usando printf é definida na documentação do POSIX printf :

Se o caractere principal for uma aspas simples ou aspas duplas, o valor será o valor numérico no conjunto de códigos subjacente do caractere após a aspas simples ou aspas simples.

Thomas Guyot-Sionnest
fonte