Genereller Hinweis:
Das Ermitteln einer MAC-Adresse ist nur möglich, wenn sich Host und Client innerhalb
des gleichen Netzes befinden. Eine Nachfrage zur MAC-Adresse via das Internet ist nicht möglich.
Einführung
In einigen Webanwendungen ist es ggf. notwendig MAC-Adressen von einzelnen Hosts sicherzustellen.
Ein generelles Beispiel dafür ist ein “Captive Portal”. Captive Portals findet man z.B. bei kostenpflichtigen
Hotspots, dies sind die Webseiten auf die man geführt wird, sobald man sich auf einem kostenpflichtigen WLAN-Netz
eingewählt hat, wo man meist erst eine Webseite mit einem Loginformular erhält.
Nun gibt es verschiedene Verfahren wie sich eine Authentifizierung dessen realisieren lässt, dass
nur ein definiertes Gerät, welches die Authentifizierung bestanden hat in der Lage ist z.B. die WLAN-Verbindung
auch für das Internet zu nutzen. In der Regel ist es so, das auf einem solchen kostenpflichtigen Portal entsprechende
iptables regeln definiert sind die forwards über ein anderes interface nur dann zu lassen, wenn die entsprechende
MAC-Adresse whitelisted wurde.
Als erstes unabhängig von dem Zweck, müssen für das Ermitteln der MAC-Adressen eines Clients eine entsprechend
notwendige Installation besitzen. Für mein Testszenario sieht diese wie folgt aus:
– Vorhandene Linux Distribution (z.B. Debian)
– arping
– sudo
– Apache2 oder vergleichbarer Webserver
– PHP
[AdSense-A]
Begründung
arping
Arping wird für unser PHP-Script notwendig sein, dieses werden wir indirekt über ein definiertes Bashscript ansprechen um zu einem
Client die MAC-Adresse zu ermitteln. Theoretisch gesehen könnte man statt arping auch nur arp nutzen, allerdings ist davon abzuraten.
In der ARP-Tabelle erscheinen nur Geräte die der Host auch kennt. Wenn wie z.B. in einem WLAN-Netz oder gar VPN-Netz ein Client dem Netz
beitritt, kennt der host erst einmal nicht die MAC-Adresse dieses Gerätes. Mittels arping, erzwingen wir einen Ping zu dem Client, worunter
dann auch auch ein ARP-Request erfolgt. Arping pingt allerdings nicht nur den Host sondern ist auch in der Lage zu einer bestehenden IP-Adresse
mittels eines Reverse-ARP die MAC-Adresse zu ermitteln.
sudo
sudo werden wir verwenden um arping dem www-data user bekannt zu machen, da sich arping i.d.R. nicht direkt vom www-data user des Apache’s ausführen lässt.
root@server:/etc/network# su www-data $ arping 192.168.178.1 sh: 1: arping: not found
Ebenso ist es hierbei hilfreich innerhalb von sudo von in PHP ausgeführte shell executes zu limitieren bzw. die dafür vorgesehene Eingabemaske.
Bash-Script für MAC-Adressen ermitteln
In erster Linie sollten wir uns ein Bash-Script schreiben, welches auf unser elementare Linux-Software “arping” zugreift und die eingaben diesbzgl. von MAC-Adressen und IP-Adressen validiert.
#!/bin/bash # # Usage: # ./getMac.sh 192.168.178.1 eth0 # # Parameter 1 = IP-Adresse # Parameter 2 = Interface # ipaddress="$1" interface="$2" function valid_ip(){ local ip=$1 local stat=1 if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then OIFS=$IFS IFS='.' ip=($ip) IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]] stat=$? fi return $stat } if valid_ip $ipaddress; then result=$(/usr/sbin/arping -i $interface $ipaddress -c 2 | grep '('$ipaddress')' | grep index=1 | awk '{ print $4 }') echo $result; fi
Was tut dieses kleine Stückchen an Sourcecode?
1. Es validiert die angegebene IP-Adresse (Erster Parameter) auf die Gültigkeit.
2. es führt arping auf die angegeben IP-Adresse (zwei mal) aus zu einem entsprechenden mitgegebenen Interface (Parameter 2) wie z.B. eth0.
3. Das daraus resultierende Ergebniss, wird mit Grep auf die IP-Adresse durchsucht
4. Grep index=1 limitiert das ergebnis auf nur eine Zeile und zwar die Zeile mit dem Index 1, welches die zweite Zeile des Resultats bedeutet.
5. awk sucht den Wert der in der 4. Spalte der Ausgabe steht raus
damit gibt uns das Script die MAC-Adresse aus, die arping ermittelt.
Dieses Script speichern wir beispielsweise als getMAC unter /sbin/ sprich /sbin/getMAC.
Damit haben wir schon mal ein Bashscript geschaffen, worauf wir durch unser PHP-Script später zugreifen können.
Nun als nächsten Schritt müssen wir sudo bekannt geben, dass www-data unser Script was unter /sbin/getMAC hinterlegt ist,
vom www-data user ausgeführt werden darf. Dazu editieren wir folgende Datei /etc/sudoers
nano /etc/sudoers
und fügen unter die Zeile “#includedir /etc/sudoers.d” folgendes ein:
www-data ALL = NOPASSWD: /sbin/getMAC
Damit geben wir sudo bekannt, dass www-data das Script getMAC ohne eine Authentifizierung ausführen darf.
arping allgemein oder andere Software die via den User root ausgeführt werden darf, darf der www-data user damit noch lange nicht ausführen,
sondern wird begrenzt auf das Script getMAC.
zu guter letzt folgt unser simples PHP-Script zur Ermittlung von MAC-Adress Zugehörigkeiten zu einer IP-Adresse.
<?php $ipaddress = $_SERVER['REMOTE_ADDR']; $interface = "eth0"; $macaddr = `sudo /sbin/getMAC $ipaddress $interface`; if (preg_match('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', $macaddr)){ echo trim($macaddr); // Ausgabe der ermittelten MAC-Adresse }else{ echo "invalid MAC-Address"; } ?>
Quellen
http://www.linuxjournal.com/content/validating-ip-address-bash-script