dmag: RegEx: ipv6 kürzen

Guten Abend,

für ipv4 habe ich einen regulären Ausdruck zum "Schwärzen" des letzten IP-Blocks, bzw. 127.0.0.123 wird dabei zu 127.0.0

Nun tauchen auch ipv6 auf, wofür das Script jedoch nicht funktioniert. Auch wenn .[0-9]{1-3} stattdessen :\S{a-zA-Z0-9} verwendet, will preg_replace mir die IPv6 nicht kürzen.

Input: gewünschter Output
2001:f0d0:1002:0051:0000:0000:0000:0004 => 2001:f0d0:1002:0051:0000:0000:0000
2002:f0d0:1002:123::8 => 2002:f0d0:1002:123:
2003:f0d0:1002:2:: => 2003:f0d0:1002:2:

Im piwik und anderen php analytics finde ich auch keinen passendes reg. Ausdruck. Habt ihr eine Idee?

Gruesse

  1. Tach!

    Nun tauchen auch ipv6 auf, wofür das Script jedoch nicht funktioniert. Auch wenn .[0-9]{1-3} stattdessen :\S{a-zA-Z0-9} verwendet, will preg_replace mir die IPv6 nicht kürzen.

    Das ist ja auch nicht die Syntax, die du willst. Zeichenklassen stehen in [], nicht in {}. Außerdem fehlt der Multiplikator.

    Und nur einen Block zu kürzen ist nicht genug. Du bekommst einen eindeutigen Anschluss ja schon mit der ersten Hälfte der IP (64 Bit). Normalerweise sollen Provider sogar 48-Bit-Präfixe den Endkunden zuweisen.

    dedlfix.

  2. Moin!

    für ipv4 habe ich einen regulären Ausdruck zum "Schwärzen" des letzten IP-Blocks, bzw. 127.0.0.123 wird dabei zu 127.0.0

    Nun tauchen auch ipv6 auf, wofür das Script jedoch nicht funktioniert. Auch wenn .[0-9]{1-3} stattdessen :\S{a-zA-Z0-9} verwendet, will preg_replace mir die IPv6 nicht kürzen.

    Input: gewünschter Output
    2001:f0d0:1002:0051:0000:0000:0000:0004 => 2001:f0d0:1002:0051:0000:0000:0000
    2002:f0d0:1002:123::8 => 2002:f0d0:1002:123:
    2003:f0d0:1002:2:: => 2003:f0d0:1002:2:

    Im piwik und anderen php analytics finde ich auch keinen passendes reg. Ausdruck. Habt ihr eine Idee?

    Du hast mit IPv6 im Grunde 2 Probleme:

    Erstens kann einunddieselbe Adresse durchaus mehrere Schreibweisen haben, weil man auf zwei unterschiedliche Weisen Nullen weglassen kann. Es gibt allerdings nur genau eine Schreibweise in maximaler Länge, indem man alle weggelassenen Nullen hinzufügt, und diese Form passt dann auch besser zum zweiten Problem.

    Zweitens: IPv6 ist 128 Bit lang, die ersten 64 Bit sind der Netzwerkpräfix, und die hinteren 64 Bit sind der Teil, den sich das Interface in diesem Netzwerk nach bestimmten Regeln aussuchen darf:

    • Man kann den Teil fest zuweisen (z.B. für Server ganz nützlich - dann wird man vermutlich auch sehr viele Nullen verwenden, weil das insgesamt wenig zu tippen ist)
    • Es gibt die automatische Adresszuweisung mittels MAC-Adresse. So ein Suffix ist dann konstant und leider weltweit ziemlich eindeutig, weil die MAC des Netzwerkinterfaces eindeutig sein sollte (sind zwar nur 48 Bits aus der MAC, der Rest wird definiert aufgefüllt)
    • Oder mit Privacy-Extensions, da würfelt der Rechner für sein Interface im Prinzip Zufallsadressen (typischerweise dann auch mit wenigen Nullen, die man weglassen kann).

    Die Frage ist, warum bei IPv4 ein Teil der Adresse weggelassen wird. Wenn das irgendwie zum Schutz der Privatsphäre diente, dann muss man bei IPv6 definitiv deutlich mehr weglassen als einfach nur die letzten 64 Bit, denn der Internetanschluss wird im Prinzip durch die vorderen 64 Bit eindeutig identifiziert.

    Es scheint sich derzeit durchzusetzen, dass die Provider einem Kunden die vorderen 56 Bit fest zuweisen, den Rest bis 64 Bit kann der Kunde nach eigenem Ermessen frei verteilen - er hat also 8 Bit = 256 eigene Netzsegmente. Identifizierbar ist er also anhand der ersten 56 Bits seiner IPv6-Adresse - wenn man das vermeiden will, muss man mehr Bits weglassen.

    Die ersten Überlegungen gingen sogar davon aus, dass man dem Kunden 16 Bit zur freien Verfügung stellt, also nur 48 Bit fest vorgibt. Das wird dann und wann wohl sogar so geschehen, folglich sind sogar diese 48 Bit identifizierend für den Anschluss.

    Andererseits ist das 48-Bit-Szenario (oder auch nur das 56-Bit-Szenario) gleichzeitig geprägt von dem Anwendungsfall, dass durchaus schon mittlere und große Firmen mit vielen Rechnern solch einen Anschluss nutzen, mithin also den 64-Bit-Suffix durch die Privacy-Extensions intensiv mit zufälligen Adressanteilen belegen (allerdings zeitlich begrenzt), und eine Identifikation des einzelnen Users ziemlich unmöglich wird.

    Von der anderen Seite her, also vom vorderen Ende der IPv6-Adresse, ist festzuhalten, dass die ersten 16 Bit eigentlich zur Kennzeichnung des Adresstyps verwendet werden. "2001:" ist der Adressraum, in dem derzeit alle großen Provider 32-Bit-Präfixe bekommen. Man kann also den benutzen Großprovider anhand der ersten 32 Bit identifizieren. Die folgenden 16 Bit werden von großen Providern an kleine Provider vergeben - anhand der ersten 48 Bit identifiziert mal also im Prinzip auch nur den Provider, halt detaillierter. Der Raum zwischen 48 und 56 Bit konkretisiert mithin also den einzelnen Kunden des Providers.

    Und nun?

    Den 64-Bit-Hostanteil kann man unbesehen wegwerfen. Und dazu brauchts auch kein Regex, sobald man die Adresse in ihre Langform gewandelt hat, kann man die hinteren Zeichen einfach abschneiden.

    Wieviele Zeichen man außerdem noch abschneidet, ist die individuelle Frage, die sich an den Erfordernissen orientieren muss, die man mit der Aktion verfolgt.

    In PHP wird man sich was mit den Funktionen "inet_pton()" und "inet_ntop()" basteln können. Mit der einen parst man den String in eine Binärdarstellung. Bei der löscht man die genehme Anzahl von 1-Bits einfach (setzt sie auf Null), und wandelt dann zurück - fertig ist die gekürzte IPv6.

    - Sven Rautenberg

    1. Om nah hoo pez nyeetz, Sven Rautenberg!

      Du hast in diese Antwort viel Zeit investiert. Möchtest du noch ein paar Minuten deiner Zeit dran hängen, damit daraus ein Artikel für unser Blog werden könnte?

      Matthias

      --
      1/z ist kein Blatt Papier.