Randomiserte MAC-adresser og 24-bits OUI-oppslag gir ukjente enheter i nettverksinventaret

Første skann hos en ny kunde ga 45 svarende verter og 44 enheter i basen. 52 av 57 enheter sto som «ukjent type». På mitt eget nett hadde 32 av 36 enheter produsent, men 13 hadde ingen type. Skanneren fungerer. Årsaken er to ting: MAC-adresser som ikke er ekte, og et produsentoppslag som bare ser på de første 24 bitene.
Randomisert MAC er standard på mobil
iOS 14 og Android 10 slo på privat WiFi-adresse som standard. Windows har funksjonen, men den er avslått med mindre noen har skrudd den på. En stor del av klientene på et vanlig kontornett oppgir derfor en adresse som ikke er tildelt av IEEE. De kjennes igjen på to bit i første oktett, og begge må sjekkes.
bit 1 (0x02) U/L 1 = lokalt administrertDen vanlige feilen er å sjekke bare
bit 0 (0x01) I/G 1 = multicast, 0 = unicast
randomisert = (b & 0x02) != 0 OG (b & 0x01) == 0& 0x02. Da flagges multicast-adresser med odde første oktett, altså 03:00:00:...-familien, som «randomisert klient». Utslaget er lite i praksis fordi multicast sjelden står i en ARP-tabell, men riktig sjekk koster ingenting ekstra.

Snarveien i hodet: se på andre hex-tegn i adressen. Er det 2, 6, A eller E, er adressen lokalt administrert og unicast.
def er_randomisert(mac: str) -> bool:Randomiserte adresser er stabile per SSID
b = int(mac.replace(":", "").replace("-", "")[:2], 16)
return bool(b & 0x02) and not (b & 0x01)
>>> er_randomisert("a6:3f:1c:8d:42:07")
True
>>> er_randomisert("03:00:5e:00:00:01") # multicast, ikke klient
False
Enheten lager én adresse første gang den ser et nettverk og beholder den ved gjentilkobling, ofte i måneder. De fungerer derfor som nøkler, men sier ingenting om produsent. Unntaket er MDM-styrte enheter som kan rotere daglig.
Et inventar bør beholde dem, men ikke varsle om at de er borte, ikke gjette type på dem og ikke telle dem med i «nye ukjente enheter». Vil du faktisk ha ekte MAC-adresser på firmanettet, er eneste løsning å slå av privat adresse via Intune eller Jamf for det SSID-et.
Produsentoppslaget må gå fra lengste prefiks og nedover
IEEE deler ut blokker i tre størrelser, og de ligger i hver sin fil.
Slår du opp 24 bit alene, treffer du blokka som IEEE selv har delt videre. Da får du navnet på registeret i stedet for navnet på produsenten. Det gjelder 358 av 24-bits-blokkene.
$ apt-get install ieee-dataFire tusen produsenter deler altså den ene 24-bits blokka. Riktig rekkefølge er 36 bit, så 28, så 24, og første treff vinner.
$ ls /usr/share/ieee-data/
iab.txt mam.txt oui36.txt oui.txt
$ grep "70B3D5" /usr/share/ieee-data/oui.txt
70B3D5 (base 16) IEEE Registration Authority
$ grep -c "^70-B3-D5" /usr/share/ieee-data/oui36.txt
4092

Filene er ikke nøkkel-verdi-tabeller på 7 eller 9 hex-tegn. mam.txt og oui36.txt bruker fortsatt det samme 24-bits OUI-et som nøkkel, og angir så et intervall over de siste 24 bitene:
$ head -6 /usr/share/ieee-data/oui36.txtEt oppslag må derfor slå opp OUI-et og sjekke om resten av adressen faller innenfor intervallet. Det krever noen linjer mer kode.
OUI Organization
OUI-36/MA-S Range Organization
Address
8C-1F-64 (hex) ALISONIC SRL
C16000-C16FFF (base 16) ALISONIC SRL
ENTRY = re.compile(r"^([0-9A-F-]{8})\s+\(hex\)\s+(.+?)\s*$")Kjørt mot de fire filene:
RANGE = re.compile(r"^([0-9A-F]{6})-([0-9A-F]{6})\s+\(base 16\)")
def vendor(mac, mas, mam, mal):
h = re.sub(r"[^0-9A-Fa-f]", "", mac).upper()
oui, rest = h[:6], int(h[6:12], 16)
for tabell in (mas, mam): # 36 bit, så 28 bit
for o, lo, hi, navn in tabell:
if o == oui and lo <= rest <= hi:
return navn
return mal.get(oui) # 24 bit til slutt
70:B3:D5:06:00:1A -> RCH SPA (MA-S, 36 bit)Databasen er eldre enn utstyret ditt
C8:5C:E2:71:23:45 -> SYNERGY SYSTEMS AND SOLUTIONS (MA-M, 28 bit)
00:1B:21:00:00:01 -> Intel Corporate (MA-L, 24 bit)
Debian-pakka ieee-data har versjon 20240722. Tildelinger gjort etter 22. juli 2024 finnes ikke i noen av filene. To eksempler fra eget nett: 90:74:ae og 30:76:f5 gir null treff i alle fire filer.
Tom produsent er da riktig svar. Å falle tilbake på nærmeste prefiks gir feil navn på ny maskinvare, og i et inventar som styrer varsling er feil navn verre enn tomt felt. Vil du ha ferske data, må du hente registrene direkte fra IEEE i stedet for fra pakkebrønnen.
Hva du klassifiserer på når MAC ikke holder
Et vanlig discovery-skann har ingen portdata. Uten produsent blir da alt «ukjent», og det var det som skjedde med de 52 enhetene. Signalene som skiller enheter fra hverandre, rangert etter treffsikkerhet:
- DHCP option 55, altså parameterlista klienten ber om. Antall og rekkefølge skiller godt mellom enheter. Option 60 er upålitelig.
- mDNS-tjenestetyper. De er gratis å hente.
- Portsett. Krever et dypere skann, men er entydig for infrastruktur.
- Produsent fra OUI.
- Vertsnavn med regex, som siste utvei.
$ avahi-browse -art | grep -E "_ipp|_googlecast|_hap|_esphomelib"Bruk kun de entydige tjenestetypene til å sette type.
+ eth0 IPv4 skriver-kontor _ipp._tcp
+ eth0 IPv4 stue-tv _googlecast._tcp
+ eth0 IPv4 garasje-sensor _esphomelib._tcp_ipp._tcp er printer, _googlecast._tcp er mediespiller, _hap._tcp er husautomasjon, _esphomelib._tcp er IoT, _afpovertcp._tcp er lagring. Generiske typer som _workstation._tcp sier for lite, og _services._dns-sd._udp alene sier ingenting.
Portsignaturene som har holdt i praksis:
9100 + 515 + 631 printer (9100/JetDirect er sterkeste enkeltsignal)To fallgruver: vertsnavn må sjekkes før produsent, ellers blir en elbillader klassifisert som «Espressif» fordi den har en ESP-brikke. Og enkelte produsenter bør holdes helt utenfor fallbacken. Apple og Intel sier ingenting om hva enheten er, og feil type er verre enn ukjent når fraværsvarslingen behandler mobil annerledes enn infrastruktur.
554 + 80 + 8000, TTL 64 IP-kamera
62078 iOS-enhet
161 managed infrastruktur, prøv SNMP
445 + 139 uten 3389 NAS eller filserver
22 + 3389 server eller arbeidsstasjon
8006 hypervisor
8123 husautomasjon
IP er aldri identitet
DHCP gjenbruker adresser, så enheter som ble kastet for to år siden ser fortsatt «levende» ut. Vertsnavn er nesten like ustabilt. MAC er eneste brukbare nøkkel, men heller ikke den holder alene, av grunner som ikke har med randomisering å gjøre:
- Med dokkingstasjon eller USB-Ethernet følger MAC-en docken. To ansatte som bytter plass ser ut som at samme enhet byttet eier. Denne feilkilden blir oftest oversett i kontornett.
- Verter med flere nettkort svarer på samme IP fra flere adresser.
- Utenfor eget broadcast-domene får du bare IP og ingen MAC. Der kollapser identiteten helt, og enheter «flytter» seg mellom kunder med like IP-planer hvis du ikke merker slike observasjoner som svakere.
Matching med rangert tillit fungerer: eksakt MAC gir høy, vertsnavn kombinert med samme produsent og samme L2-segment gir middels, og en fingeravtrykk-hash av portsett, mDNS og produsent gir lav. Den siste skal aldri brukes som primærnøkkel. To like printere gir identisk hash.
Fingerbank, som lenge var standardsvaret på klassifisering, er ikke lenger åpent. Det eies av Akamai og er API-gated. Det finnes speil av gamle PacketFence-dumper på GitHub. Maskinlæring på slike data når publisert rundt 81 prosent på 27 enheter med 276 features. Det er ikke bedre enn et gjennomtenkt regelsett, og langt dyrere å drifte.
Manuell overstyring må feste seg. Setter noen type på en enhet, skal neste skann aldri overskrive den. Typefeltet må derfor kunne låses.


