cara menghasilkan alamat MAC acak dari baris perintah Linux

26

Bagaimana cara menghasilkan alamat MAC acak dari baris perintah Linux?

Saya mencari solusi yang hanya membutuhkan alat standar yang biasa ditemukan di baris perintah Linux.

Alamat MAC akan digunakan untuk KVM tamu.

Erik Sjölund
sumber

Jawaban:

46

saya menggunakan

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

Manfaat dari metode ini, lebih dari angka acak, adalah mungkin untuk mereproduksi alamat MAC dengan andal berdasarkan FQDN mesin, yang kadang-kadang bermanfaat bagi saya. Untuk 02oktet pertama hanya menetapkan bit "yang ditentukan secara lokal", yang membuatnya jelas bahwa itu bukan alamat MAC yang disediakan vendor, dan menjamin bahwa Anda tidak akan bertabrakan dengan alamat MAC NIC yang sebenarnya.

Jika Anda perlu membuat beberapa alamat MAC per host, saya biasa menggabungkan FQDN dengan nama jembatan untuk menghubungkan antarmuka ke; ini melakukan pekerjaan yang baik untuk menyebarkan berbagai hal untuk NIC yang berbeda.

womble
sumber
+1 untuk reproduktifitas; untuk aplikasi tertentu, itu membuatnya menjadi metode yang jauh lebih unggul untuk ditambang.
MadHatter mendukung Monica
Terima kasih banyak, saya suka ide itu direproduksi.
Erik Sjölund
Ditambah lagi tidak ada konflik alamat mac jika Anda tidak dapat secara acak menghasilkan mac yang sama dua kali
Petter H
3
Sebagai alternatif, Anda dapat menggunakantr -dc A-F0-9 < /dev/urandom | head -c 10 | sed -r 's/(..)/\1:/g;s/:$//;s/^/02:/'
ALex_hha
1
Ini hanya "alternatif" dalam arti bahwa ia menghasilkan hasil akhir yang sama sekali berbeda dari apa yang snippet saya lakukan ...
womble
8

Skrip yang diposting bagus, tapi saya ingin menambahkan peringatan: Mind the Birthday (paradoxon)!

Itu berasal dari fakta bahwa bahkan jika Anda hanya memiliki 23 orang, kesempatannya sudah 50% bahwa 2 dari mereka ulang tahun pada hari yang sama.

Itu tergantung pada skenario Anda bagaimana Anda menggunakannya, tetapi jika Anda menghasilkan MACS secara acak, sekitar 1 juta peluang Anda untuk bentrokan nomor mac adalah 40% pada 2 juta itu sudah 87%!

Jika Anda hanya membutuhkan pasangan ini tidak apa-apa, tetapi ketika Anda mengelola server pertanian dengan ratusan server, masing-masing dari mereka hosting puluhan mesin virtual, atau jika Anda menggunakan mac sebagai indeks dalam beberapa db untuk pembukuan dan Anda perlu unik hati-hati !

flolo
sumber
Terima kasih, untuk peringatan tentang paradoks Ulang Tahun! Dalam kasus saya, saya akan mengambil risiko karena saya akan menghasilkan sekitar 20 alamat MAC.
Erik Sjölund
3
Jika Anda menjalankan ratusan server yang masing-masing menampung puluhan mesin virtual semuanya pada domain broadcast yang sama, Anda memiliki masalah yang lebih besar daripada risiko tabrakan alamat MAC.
womble
1
" Itu berasal dari fakta bahwa bahkan jika Anda hanya memiliki 23 orang, kesempatannya sudah 50% bahwa 2 dari mereka ulang tahun pada hari yang sama. " Itu bahkan tidak benar. Ada kemungkinan sekitar 50% bahwa dua dari 23 orang memiliki ulang tahun yang sama, bukan ulang tahun yang sama.
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, Gergaji Tentara Swiss itu naik lagi. Dan dengan versi 0.2, saya tanpa malu-malu mencuri poin womble yang sangat baik tentang oktet pertama menjadi 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 mendukung Monica
sumber
Terima kasih Madatter, saya mencoba varian kedua Anda dan itu berhasil. Sangat bagus!
Erik Sjölund
5

Varian ini juga berfungsi.

lebih lama:

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

atau lebih pendek:

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

Konsumsi beban kedua varian sangat mirip menurut pengukuran cepat dengan waktu.

Jaroslav Kucera
sumber
Halo Anthony, saya tidak melihat varian lain menggabungkan openssl rand dan sed sini, jadi ini adalah solusi unik dalam topik ini.
Jaroslav Kucera
Itu benar. Dia menggunakan fold -w2|paste -sd: -alih-alih sed. The sedsolusi adalah mungkin lebih mudah untuk diingat karena menggunakan alat yang lebih akrab - meskipun aku belajar lebih banyak dari jawaban / nya.
Anthony G - keadilan untuk Monica
Saya pikir perintah pertama tidak akan berhasil karena tidak mengatur bit pertama menjadi genap!
amrx
Hai @ amx, Anda yakin bit MAC pertama harus genap? Saya memiliki NIC di salah satu server saya, yang dimulai dengan ec11101100 dalam biner ...
Jaroslav Kucera
1
Hai @JaroslavKucera, alamat MAC Unicast tidak boleh mengatur bit tempat 1 pada byte pertama. Itulah bit "group" (multicast / broadcast). Jika Anda membuat alamat MAC Anda sendiri, Anda harus menetapkan bit tempat 2 (bit "yang dikelola secara lokal") pada byte pertama, untuk membedakannya dari alamat MAC yang unik secara global.
amrx
4

Saya tahu posting ini sudah tua, tetapi untuk pengunjung di masa depan, jika Anda ingin alamat MAC pseudorandom aman secara cryptographically aman, tanpa terbatas pada 0x02 sebagai OUI, berikut adalah generator agnostik platform cepat:

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

Ini satu lagi, berdasarkan jawaban 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
sumber
Tidak perlu menjalankan output urandom melalui md5sum; Anda bisa menggunakan od sesuai jawaban Aaron Toponce.
womble
2

Berikut adalah lima opsi lain, yang semuanya menggunakan bit acak untuk bit paling signifikan dari byte paling signifikan yang menunjukkan apakah alamatnya unicast atau multicast dan untuk bit paling tidak signifikan kedua dari byte paling signifikan yang menunjukkan apakah alamatnya adalah dikelola secara universal atau lokal.

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-

jothadir dengan OS X dan BSD tetapi tidak dengan sebagian besar distribusi Linux. Dalam jot -wmengubah format, -smengubah pemisah, dan -rmenghasilkan angka acak.

oddalam POSIX tetapi hexdumptidak.

OS X od(di /usr/bin/odbawah) menggunakan format output yang berbeda dari 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

Dalam OS X odPilihan ditempatkan setelah argumen untuk file input diperlakukan sebagai nama-nama file input, sehingga perintah dalam jawaban oleh Aaron Toponce membaca dari /dev/urandomtanpa batas dengan OS X od.

nisetama
sumber
1

Anda bisa saja menambahkan $ ACAK setelah $ FQDN dan ini akan memberi Anda alamat mac acak setiap kali Anda menjalankannya. Ini sangat membantu untuk poeple yang ingin membuat backup vms menggunakan snapshot atau klon vms.

macaddr=$(echo $FQDN$RANDOM|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/')
Air raksa
sumber
1
Perhatikan bahwa $ RANDOM tersedia dalam bash, tetapi mungkin tidak tersedia di shell lain.
Michael Hampton
0

Saya menggunakan:

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

Python one-liner:

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

Hanya untuk bersenang-senang, di sini adalah versi bash murni, diuji terhadap Bash 4.4.12 (1) - rilis:

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

Baris pertama membaca 6 karakter dari /dev/urandom; kemudian menggunakan set karakter C cetak nilai hex diisi 0 dari setiap karakter yang dipisahkan dengan titik dua (baris baru opsional tetapi berguna untuk mencetak nilai).

Mengekstraksi nilai karakter menggunakan printf didefinisikan dalam dokumentasi POSIX printf :

Jika karakter utama adalah kuotasi tunggal atau kuotasi ganda, nilainya harus berupa nilai numerik dalam kumpulan kode yang mendasari karakter yang mengikuti kuotasi tunggal atau kuotasi ganda.

Thomas Guyot-Sionnest
sumber