DiLi-Tech

Kleine Programmier-Übung: Der IP-Adressen-Logger

Manchmal kann es ganz sinnvoll sein, die eigene(n) IP-Adresse(n) zu kennen. Sei es um einen DynDNS-Dienst damit zu synchronisieren (siehe: DynDNS-Updater). Oder um sich bei unberechtigten Vorwürfen wehren zu können. Im letzteren Fall ist es hilfreich, zu einem bestimmten Zeitpunkt der Vergangenheit die damals aktuelle(n) IP-Adresse(n) zur Hand zu haben.
Kurz: wir wollen einen IP-Logger entwerfen, der sowohl IPv4- als auch IPv6-Adressen in einem Protokoll dokumentiert.

[Update:] Inzwischen hat sich gezeigt, dass das IP-Protokoll die letzten Zweifel beseitigen kann. Kürzlich bekam ich eine Abmahnung von einer Kanzlei "Krüger & Beck AG" in Form einer eMail. Man muss sagen: die werden immer besser! Der Name und die Anschrift sowie die eMail-Adresse sind korrekt. Es gibt keine Schreibfehler und das Juristenlatein klingt (fast) echt. Na jedenfalls muss man sich bremsen, um nicht den Anhang zu öffnen.

Sehr geehrte/r Dieter Liebl, der Anlass unserer Beauftragung ist eine von Ihrer Internetverbindung aus begangene Verletzung der Urheberrechte an dem Projekt "Das Beste aus Extrem 4 Blu-ray Disc". Unserer Mandantin "Sweetheart Film" steht das einzige Recht zu, dieses Werk zu vervielfältigen (§§ 16, 94 f. UrhG). Dieses Recht wurde durch das Streamen des betreffenden Werkes über Ihre Internetverbindung verletzt. Folgende Daten konnte die seitens unserer Mandantschaft beauftragter Ermittlungsfirma feststellen und beweissicher dokumentieren: Dieter Liebl Dachshof 7 59071 Hamm IP-Adresse: 77.21.104.??? Datum/Uhrzeit: 17.08.2018 23:12:00 Produktname: Das Beste aus Extrem 4 Blu-ray Disc Benutzerkennung: xxxxxxxxx Unserer Mandant hat daher vor dem Gericht Köln Ihren Internet-Service-Provider gemäß § 101 Abs. 9 UrhG auf Auskunft in Anspruch genommen. Das Landgericht hat für diesen Vorfall sowohl die Rechtsinhaberschaft als auch die ordnungsgemäße Erfassung der Rechtsverletzung und Funktionsweise der Ermittlungssoftware bejaht. In dem Beschluss mit dem Aktenzeichen xxxx-yyyy-zzz wurde Ihrem Internetserviceprovider die Herausgabe Ihrer Daten gestattet. Die beim Streamen des genannten Werkes technisch notwendige Zwischenspeicherung stellt ein Vervielfältigen nach § 16 UrhG dar und steht ausschließlich dem Urheber bzw. dem Rechteinhaber zu. Hierfür spielt es keine Rolle, ob das Werk dauerhaft oder nur vorübergehend gespeichert wird. Eine rechtmäßige Nutzung der Raubkopie (§ 44a UrhG) ist ohne Genehmigung des Urhebers nicht möglich (vgl. AG Leipzig, Urteil vom 21.12.2011 - Az. 200 Ls 390 Js 184/11). Eine erlaubte Vervielfältigung zum privaten Gebrauch (§ 53 UrhG) kommt hier von vornherein nicht in Betracht, da eine offensichtlich rechtswidrig hergestellte oder öffentlich zugänglich gemachte Vorlage verwendet worden ist. Daher hat unsere Mandantschaft gegen Sie einen Anspruch auf Unterlassung und Schadensersatz (§ 97 UrhG). Weiterhin hat unsere Mandantschaft gegen Sie den Anspruch auf Vernichtung aller bei Ihnen noch befindlichen rechtswidrigen Kopien (§ 98 UrhG). Schadenanspruch: 729,71 Euro Pauschale für Post und Telekommunikation: 31,38 Euro Aufwendung für Ermittlung der Rechtsverletzung - pauschal: 90,00 Euro Gegenstandwert: 42498,00 Euro Geschäftsgebühr §§ 13, 14: 278,59 Euro Die Beweisdaten, Unterlassungserklärung sowie die Bankdaten und unsere Kontaktdaten finden Sie in der beigefügten Datei. Mit freundlichen Grüßen Kanzlei Krüger & Beck AG


Aber nun 'mal langsam! Per eMail? Juristische Schreiben kommen ganz sicher nicht per eMail sondern per (Schnecken-)Post! Weiter: ich soll unberechtigter Weise einen Film gestreamt haben: "Das Beste aus Extrem 4 Blu-ray Disc" Das ist erfundener Unsinn. Und das sei eine unberechtigte Vervielfältigung, wogegen der Rechteinhaber nun vorgehe. Rein rechtlich ist das Anschauen per Browser eine (sehr kurzzeitige) Vervielfältigung. Ja, das stimmt. Aber ich habe gedacht, dass solche "Peanuts" seitens der Gerichte nicht geahndet würden. Wegen des zu geringen Streitwertes. Und inzwischen ist doch die Abmahn-Bremse in Kraft...

Ich erinnere mich da an einen Fall, der seinerzeit durch alle Medien ging: da wurden Internet-Nutzer einer Porno-Seite auf eine fremde Webseite umgeleitet bzw. gelockt. Nur, um die echten(!) IP-Adressen der Nutzer abzufangen. Bei Gericht wurde die Herausgabe der Nutzerdaten zu diesen IP-Adressen beantragt. Dann gab es massenweise Abmahnungen... Das Ganze ging schließlich nach Hinten los und wurde zum totalen Rohrkrepierer für die Anwaltskanzlei. Letztere gibt es nun nicht mehr.

Damals wurden vom Gericht die Nutzerdaten herausgegeben. Das ist aktuell nicht mehr zulässig: die Vorratsdatenspeicherung wurde von der EU in Deutschland gestoppt! D.h., der Internetprovider darf / kann diese Daten nicht herausgeben...

Eine erste schnelle Recherche bei Google ergab:

Exakt gesucht: unbekannt! Und ein Schreibfehler des Namens im Anschreiben einer Kanzlei ist eher unwahrscheinlich!!

Die Suche ohne Anführungszeichen lieferte als 1. Eintrag die Seite von onlinewarnungen.de. Dort finden sich eine Kanzlei "Rechtsanwälte Dr. Krüger und Beck GmbH" und noch andere ähnlich klingende Rechtsanwälte - und die Warnung davor, den Anhang zu öffnen.

Der Anhang bestand aus einer .zip-Datei. Der Virenscan meiner PC-AntiVirensoftware fand nichts Auffälliges. Aber trotzdem: Vorsicht! Also habe ich einen Online-Virenscanner bemüht:

Der Online-Virenscan lieferte ein Ergebnis: von 61 bemühten Scannern lieferten immerhin 16 ein positives Ergebnis.
Interessant: 5 Stunden später waren es schon 21 !!

Das heißt immer noch Nichts. Virenscanner handeln nach dem Motto: lieber zu viel als zu wenig melden. Ich bin aber lieber vorsichtig und habe den Anhang ungeöffnet entsorgt...

Den letzten Zweifel ausgeräumt hat der Blick ins IP-Protokoll: nein, am besagten Tag war ich NICHT mit der aufgeführten IP-Adresse im Netz!!! Basta.

Nachsatz: Der juristische Schriftsatz ist nur Ablenkung. Es geht denen darum, Sie schnell zum Öffnen des Anhangs zu verleiten und Ihren Rechner zu infizieren. Mit gekaperten Rechnern werden Bot-Netze aufgebaut, die im Darknet für gut Geld an Dunkelmänner verkauft werden.

So, aber nun weiter mit Wichtigerem: [/Update]

Dieser Artikel soll aufzeigen, wie mit einfachen Mitteln ein IP-Logger zu programmieren ist. Gleichzeitig sollen grundlegende Web-Technologien erläutert werden. Das Beispiel soll in "PHP" gecodet werden. Zunächst zu den Grundlagen.

Die Abbildung zeigt die typischen Angaben bei einer Fritzbox bei "Dual-Stack" (DS): neben der althergebrachten IPv4-Adresse werden auch zwei IPv6-Angaben gemacht:
einmal die IPv6-Adresse, mit der die Box aus den Internet erreichbar ist - zur Konfiguration und um z.B. auf Freigaben (NAS) zuzugreifen. Damit kann man nicht auf Geräte hinter der Box zugreifen!

Bei IPv6 gibt es anders als bei IPv4 kein "NAT" (Network Adress Translation), auch schon 'mal "Port-Forwarding" genannt. Die Geräte hinter dem Router sind mit ihrer IPv6-Adresse direkt erreichbar - wenn freigeben. Diese Adressen beginnen mit dem sog. "Präfix".
Das ist die zweite IPv6-Angabe. Bei meinem Telekom DSL-Anschluss z.B. wird ein /56-Präfix geliefert: 56 Bit beschreiben den 1. Teil der Adresse. Dann folgt 1 Byte für das Subnet (hier: "00". Die nächsten 64 Bit komplettieren zur vollständigen IPv6-Adresse (128 Bit). Sie werden von der Box vergeben. Genau genommen sind es sogar zwei IPv6-Adressen pro Gerät - wenn Letzteres das unterstützt. Ist das Gerät ein Windows-PC, so wird dieser zwei IPv6-Adressen bekommen. Die erste ist die "normale", die zweite ist die "TEMP"-Adresse.

Mit der "normalen" Adresse ist der PC aus dem Internet erreichbar, die "TEMP"-IP wird verwendet, wenn der PC Kontakt nach Außen aufnimmt. Ein Webserver wird immer diese "TEMP"-Adresse des ansurfenden Users sehen. "TEMP" bedeutet, dass sich diese Adresse in kurzen Abständen ändert (beachte: das Präfix bleibt gleich!) und so die Nachverfolgung von Aktivitäten erschweren soll. Das gelingt mit den sog. "Privacy Extensions". Nicht alle Geräte unterstützen diese.

Zu alten Nur-IPv4-Zeiten wurde i.d.R. jeden Tag eine Zwangstrennung durchgeführt. Mit der Folge dass sich die IP (v4) täglich änderte. Damit war auch immer ein kurzer Zeitraum gegeben, innerhalb der die Box unerreichbar war - das Neuverbinden kostete Zeit. Seit der Einführung von Voice-over-IP-Telefonie wird sich ihr Router nur alle Jubeljahre neu einwählen und damit neue Adressen und ein neues Präfix bekommen. Tot-Zeiten beim Telefonieren sollen so vermieden werden.
Ständig wechselnde Adressen haben den Vorteil, dass die Anonymität leichter zu erreichen ist. Die "Privacy Extensions" sollen diesen Vorteil auch bei IPv6 gewährleisten. Aber: da sich das Präfix nicht ändert, lässt sich zwar nicht auf das Gerät (PC), wohl aber auf den Anschluss schließen (wenn die Länge des Präfix bekannt ist...)!

Kommen wir zurück zu unserer Aufgabe: die aktuelle IPv4- und IPv6-Adresse ermitteln und in eine Log-Datei schreiben. Zur Inspiration; versuchen Sie mal folgende Links: IPv4 ermitteln und IPv6 ermitteln. Und? Zweimal erfolgreich gewesen?
Ja? Dann sind Sie mit "Dual Stack" unterwegs, d.h., Sie haben sowohl eine IPv4-Adresse als auch eine IPv6-Adresse. Welche zum Tragen kommt hängt vom Gerät, dem Router, dem Provider und der Art, wie der angesurfte Webserver angebunden ist, ab. Schauen Sie doch 'mal hier.
Nein? Dann wird vermutlich IPv6 nicht unterstützt. Warum auch immer...

Für Lösung der Aufgabe auf die einfachste Art würde man auf diese beiden Links zurückgreifen. Also: die beiden URLs aufrufen und ins Log-File schreiben, wenn seit letztem Aufruf verändert. Fertig.

Eine weitere Lösung der Aufgabe bestünde darin, die Adressen direkt aus dem Router zu lesen. Also: einen Benutzer simulieren und sich durch die Menüs hangeln. So wie ich es beim SpeedPort gemacht habe: hier. Bei einer Fritzbox wird sich das nur recht umständlich machen lassen, da die Benutzerseiten von JavaScript erzeugt werden und die Seiten nicht linkbar sind. Bei anderen Routern mag das anders sein.

Wir entscheiden uns für die dritte Art. Wir wollen ja Grundsätzliches lernen. Also der Reihe nach.
Wir brauchen: einen Webserver, der sowohl über IPv4 als auch über IPv6 erreichbar ist. Diese, meine WebSite ist bei STRATO gehostet und erfüllt diese Bedingung. Dort wird ein PHP-Einzeiler platziert, der nicht anderes macht, als die IP des Benutzers zurück zu liefern: hier.
Und diese Seite wird zweimal aufgerufen, aber nicht über die URL, sondern über die IP-Adressen. Diese beiden (IPv4 und IPv6) Adressen besorgen wir uns direkt beim "DNS" (Domain Name Service)! Der "DNS" ist das Telefonbuch des Web. Man sucht nach Name und bekommt eine Nummer sprich IP.

Ein noch nicht erwähnter wichtiger Punkt ist, dass der Aufruf vom Router oder einem Gerät hinter dem Router ausgeführt werden muss. Und das immer wieder... Das könnte ein PC sein, der beim Starten den Aufruf macht. Oder - und so habe ich es realisiert - ein Rechner, der im (privatem) Netz ständig läuft, ruft z.B. alle 10 Minuten das Skript auf. Über die "Aufgabenplanung" von Windows. Apropos Skript. Unser PHP-Skript braucht noch ein wenig Infrastruktur an Bord: einen Webserver und die PHP-Umgebung. Ich verwende seit Jahren den Webserver von aprelium.com. Dort gibt es auch eine vorkonfigurierte PHP-Umgebung.

Weiter: dem DNS-Server sagen wir, dass wir den "DNS_A-Record" des o.g. Webservers haben wollen, auf dem der PHP-Einzeiler liegt. Darin liegt die IPv4-Adresse. Danach wollen wir noch den "DNS_AAAA-Record". Der liefert die IPv6.Adresse.

Der erste Teil der Aufgabe ist damit gelöst. Jetzt müssen wird mittels der gefundenen IPs jeweils eine Verbindung zum fernen Webserver aufbauen und dann per "GET" die Website aufrufen, die die eigene IP returniert. Schauen Sie sich dazu bitte den folgenden PHP-Quelltext an.


<?php

/*
****************************************************************
*
*       Logger für aktuelle IPv4- und IPv6-Adressen
*               (c) DiLi-Soft 30.06.2018
*
*       Aufruf über Windows-Taskplaner (z.B. alle 10 Min.)
*       z.B.: "C:\PHP\php-win.exe" "c:\batch\IP_logger.php"
*
*       Benötigt PHP-Einzeiler auf fernem Server:
*       <?=$_SERVER['REMOTE_ADDR']?>
*
****************************************************************
*/


function get_last_IP() {                     // letzte, gemerkte IPs holen
   
global $IP_filename;

   
$IP=array();
   
$hd=@fopen($IP_filename,'r');
   if (
$hd===FALSE)
      return(
FALSE);

   
$zeile=fgets($hd);
   
$IP[0]=rtrim($zeile);
   
   
$zeile=fgets($hd);
   
$IP[1]=rtrim($zeile);
   
   
fclose($hd);
return(
$IP);                                 // IPs oder FALSE
}


function 
put_IP($IP) {                       // aktuelle IPs sichern
   
global $IP_filename;

   if (!
is_array($IP))
      return(
FALSE);
   if (
count($IP) != 2)
      return(
FALSE);
   
   
$hd=@fopen($IP_filename,'w');
   
$len=@fwrite($hd$IP[0] . "\r\n");
   
$len+=@fwrite($hd$IP[1] . "\r\n");
   @
fclose($hd);
   
return(
$len);                                // Anz. geschriebener Zeichen
}


function 
get_myIP($server_ip) {              // IPv4 oder IPv6 über "http://www.dieterliebl.de/show_my_ip.php" holen
   
$sock = @fsockopen($server_ip80$errno$errstr15);  // 15 Sek, TimeOut
   
if (!$sock)                                               // IPv6-Adresse in [] !!!!!
      
return(FALSE);
   
   
fwrite($sock"GET /show_my_ip.php HTTP/1.0\r\n");        // jeweils mit "\r\n" abschließen !
   
fwrite($sock"Host: dieterliebl.de\r\n");
   
fwrite($sock"Accept: */*\r\n");
   
fwrite($sock"Connection: Close\r\n");
   
fwrite($sock"\r\n");

   
$headers "";                            // 1. Leerzeile suchen = Trennner Header - Body
   
while ($str trim(fgets($sock4096)))
      
$headers .= "$str\n";
      
   
$body ""
   while (!
feof($sock))                      // bis eof = Body
      
$body .= fgets($sock4096);
   
$body trim($body);
   
   
fclose($sock);
   
return(
trim($body));                         // IPv4 oder IPv6-Adresse
}



function 
get_praefix($ip6) {
   
$arr=array();
   
$arr=explode(":"$ip6);
   if (!
$arr)
      return (
FALSE);

return ( 
sprintf("%s:%s:%s:%s::/56"$arr[0], $arr[1], $arr[2], $arr[3]) );
//           z.B. 2345:a1:12ab:6400::/56
}



function 
write_log($IP="") {                 // Log-File schreiben
   
global $IP_logfile;
   
   
$hd=fopen($IP_logfile"a");
   if (
$hd===FALSE)
      return(
FALSE);

   
fwrite($hddate("d.m.Y H:i:s") . " : ");
   
   if (
count($IP) ==) {                    // beide IPs ausgeben
      
fwrite($hd"neue IP:\r\n");
      
      if (
$IP[0] == FALSE)
          
$IP[0] = "Fehler";
       
      if (
$IP[1] == FALSE)
          
$IP[1] = "Fehler";
      
      
fwrite($hd"               IPv4 : " $IP[0] . "\r\n");
      
fwrite($hd"               IPv6 : " $IP[1] . "\r\n\r\n");
   }
   
   if (
count($IP) == 1)                     // 1x Fehlertext ausgeben
      
fwrite($hd$IP[0] . "\r\n\r\n");

   
fclose($hd);
   
return;
}



# --------------------------- Main() : -------------------------------- #



   
$IP_filename=".\last_IP.log";       // enthält letzte, gemerkte IPs
   
$IP_logfile=".\IP_logger.log";      // Logfile
   
   
$last_IP=get_last_IP();             // letzte, gemerkte IPs holen
   
   
   
$dns4 = @dns_get_record('www.dieterliebl.de'DNS_A);
// var_dump($dns4);

   
if ($dns4)                          // DNS-V4-Records
      
$ip4 $dns4['0']['ip'];         // IPv4 ohne [] !
   
else
      
$ip4 "";
   
   
$dns6 = @dns_get_record('www.dieterliebl.de'DNS_AAAA);
// var_dump($dns6);
   
   
if ($dns6)                          // DNS-V6-Records
      
$ip6 "[" $dns6['0']['ipv6'] . "]";    // IPv6 in [] !!!!!
   
else
      
$ip6 "";
   
// echo "\nServer-IPv4: ", $ip4, "\nServer-IPv6: ", $ip6, "\n";
   
   
if ($ip4 == "" and $ip6 == "") {
      
write_log(array("Fehler bei beiden DNS-Aufrufen"));   // ins logfile schreiben
      
exit;                            // nur bei 2 Fehlern: raus!
   
}
   
// Format: $akt_IP = array("123.234.12.34", 
//                         "2345:a1:12ab:6400:5dea:ccf:13f8:b155");   

   
if ($ip4 !="")
      
$akt_IP[0] = get_myIP($ip4);     // eigene (!) IPv4-Adresse holen
   
else
      
$akt_IP[0] = FALSE;
   
   if (
$ip6 !="")
      
$akt_IP[1] = get_myIP($ip6);     // - " - IPv6-Adresse
   
else
      
$akt_IP[1] = FALSE;
   
   if (
$akt_IP[1] != FALSE)
      
$akt_IP[1] = get_praefix($akt_IP[1]);  // Präfix /56 bei IPv6 holen
      

   
if ($akt_IP[0] == FALSE or $akt_IP[1] == FALSE) {
      
write_log($akt_IP);              // bei mind. 1 Fehler: ins logfile schreiben
      
exit;                            // und raus    
   
}  
   
// echo "\neigene IPv4: ", $akt_IP[0], "\neigene IPv6: ", $akt_IP[1], "\n";

   
if ($akt_IP == $last_IP)            // eigene IPs sind fehlerfrei bestimmt und unverändert
      
exit;
   
   
put_IP($akt_IP);                    // sonst: geänderte, aktuelle IPs merken
   
write_log($akt_IP);                 // und ans Protokoll anhängen

   
exit;

?>


Das Skript ist absichtlich prozedural und nicht objektorientiert formuliert. Abstrakte Methoden und Eigenschaften der objektorientierten Ansätze sind für die Erstellung von Programmen sehr bequem und erleichtern das Programmieren enorm, fördern aber nicht das Verständnis. Der Aha-Effekt bleibt meist aus.

Interessant wird es beim Programmstart weiter unten unterhalb von # --- Main() : ---.
Da wird zunächst der IPv4-Record des fernen Webservers per DNS geholt:
$dns4 = @dns_get_record('www.dieterliebl.de', DNS_A);
Anschließend der IPv6-Record:
$dns6 = @dns_get_record('www.dieterliebl.de', DNS_AAAA);.
Die Funktionsaufrufe liefern eine Array-Struktur - ruhig 'mal mit var_dump() anschauen! Die gewünschte IP steckt dann irgendwo im Array...
(Nur) die IPv6-Adresse wird abschließend in eckige Klammern [...] gesetzt - sehr wichtig !!

Hinweis: Sie können das Programm starten, indem Sie das Skript im Browser öffnen.

Mit den gefundenen Adressen erfolgen dann schließlich die Aufrufe meiner Funktion get_myIP($server_ip) im ersten Drittel des Quelltextes oben. Das Ergebis der IPv6-Adresse wird auf das Präfix gekürzt und am Schluss werden die gefundenen Werte ins Protokoll geschrieben - wenn sich eine Änderung gegenüber dem letzten Aufruf ergeben hat.

Meine Funktion get_myIP($server_ip) müssen wir uns jetzt ganz genau anschauen:
$sock = @fsockopen($server_ip, 80, $errno, $errstr, 15);
Damit wird eine sog. Socket-Verbindung geöffnet Zwischen unserem Socket-Client und dem fernen Server. Über solch einen Kommunikationskanal lassen sich einfache Zeichenketten senden und empfangen. Im TCP/IP-Modell ist die Socket-Verbindung so eine Art Zwischenschicht zwischen der Anwendungsschicht und der Transportschicht. Anwendungsschicht sind Protokolle wie "HTTP", "FTP", "SMTP" oder "POP3". Damit uns der Webserver versteht, muss nun auf Basis dieser Socket-Verbindung das HTTP-Protokoll implementiert werden.
Ja, genau: wir basteln uns hier das HTTP-Protokoll !
Im Folgenden kommt es auf (fast) jedes Zeichen an! Wir müssen uns exakt an die Vorschriften halten:

fwrite($sock, "GET /show_my_ip.php HTTP/1.0\r\n");
fwrite($sock, "Host: dieterliebl.de\r\n");
fwrite($sock, "Accept: */*\r\n");
fwrite($sock, "Connection: Close\r\n");
fwrite($sock, "\r\n");

Diese Instruktionen sagen dem Webserver, was wir von ihm wollen: Mittels der "GET"-Methode die angegebene Seite abrufen in der HTTP-Version 1.0. Vom angegebenen Host. Wir tun so, als wären wir ein Browser, der alle Rückantworten verarbeiten kann (*/*). Nach der Lieferung der Daten soll die Verbindung geschlossen werden (Close).
Nach jeder Zeile kommt eine Zeilenende-Kennung.
Zur Erläuterung: "\r" steht (nicht nur) in PHP für "CR" (= "Carriage Return", in HEX: 0x0D) und "\n" steht für "LF" (= "Line Feed", in HEX: 0x0A).
Seltsamerweise ist vereinbart, für das Zeilenende "\r\n" (= "CRLF", in HEX: 0x0D0A) zu senden. Das ist das Zeilenende, wie es Windows verwendet. In der UNIX-Welt ist das unüblich: es wird lediglich "\n"(= "LF") gesendet!
Ganz zum Schluss wird eine leere Zeile gesendet (sehr wichtig !!).

Anschließen werden mit fgets($sock, 4096) solange die eintrudelnden Zeichenketten empfangen, bis die erste Leerzeile (!) erkannt wird. Damit ist der Empfang des sog. "HTTP-Headers" abgeschlossen. Darin stehen Statusinformationen, z.B. ob der Request korrekt war oder ein Fehler aufgetreten ist. Und die "Cookies"...

Schauen Sie sich den empfangenen "HTTP-Header" 'mal an, indem Sie echo $headers; einfügen.

Nach der Leerzeile ist vereinbart, dass der sog. "HTTP-Body" versendet wird. Da stehen die gewünschten Nutzdaten drin. Z.B. der HTML-Code einer Webseite, in unserem Fall: die IP-Adresse. Mit
while (!feof($sock))
   $body .= fgets($sock, 4096);

wird dann solange gelesen, bis das Ende ("EOF" = End of File) erreicht ist: der Body ist komplett gelesen. Auch hier schauen Sie sich das Ergebnis an, indem Sie wieder echo $body; einfügen.

Und zum Schluss verändern Sie bitte den PHP-Code, indem Sie einen Fehler provozieren. Lassen Sie 'mal "\r" (= "CR") weg, oder die leere Zeile (= "\r\n") am Schluss. Der Server wird statt mit "200 OK" mit "400 Bad Request" im Header antworten: er versteht Sie nicht. Die Nummer ist die HTTP-Fehler-Nummer. Sie kennen vermutlich bereits die Fehlernummer 404...

Es folgen noch ein wenig Fehlerbehandlung und das Schreiben des Log-Files.

Das war ein Ausflug in die Tiefen des "HTTP"-Protokolls. Hier nun das Ergebnis unserer Bemühungen: es folgt ein Beispiel des Protokolls


10.06.2018 10:31:04 : neue IP:
               IPv4 : 123.234.12.34
               IPv6 : 2345:a1:12ab:6400::/56

10.06.2018 11:11:07 : Fehler bei beiden DNS-Aufrufen

10.06.2018 11:21:08 : neue IP:
               IPv4 : 123.234.12.35
               IPv6 : 2345:a1:12ab:6500::/56

21.06.2018 12:41:05 : neue IP:
               IPv4 : Fehler
               IPv6 : 2345:a1:12ab:6600::/56

21.06.2018 12:51:04 : neue IP:
               IPv4 : 123.234.12.36
               IPv6 : 2345:a1:12ab:6700::/56

30.06.2018 08:21:07 : neue IP:
               IPv4 : 123.234.12.37
               IPv6 : Fehler

30.06.2018 08:31:06 : neue IP:
               IPv4 : 123.234.12.38
               IPv6 : 2345:a1:12ab:6800::/56

nach ganz oben

     Kommentieren Sie hier!