ralphi: IP-Cam forward - warum muss htaccessuser/camuser gleich sein?

Hi all,

ich möchte gerne eine IP-Cam über einen ext. Webserver erreichbar machen.
In den "meisten" Apps kann ich:
URL: http://htaccessuser:htaccesspass@cam.meinedomain.de
camuser, campass
port
eingeben und den Stream abgreifen (oder andere Befehle).

Dabei sendet die App zB:

url/videostream.cgi?rate=11&user=camuser&pwd=campass

eine Sammlung der Commands: IPCAM CGI SDK 2.1

Auf meinem Webserver-> index.php
lese ich nun die URI aus und setze sie an die Weiterleitung drann.

<?php
    // log zum kucken
    function logger($uri,$mod){
        $ref = $_SERVER['HTTP_REFERER'];
        $ip = $_SERVER['REMOTE_ADDR'];
        $txt = date("Y-m-d H:i:s")."\t".$mod."\t".$ip."\t".$ref."\t".$uri."\n";
        $handle = fopen ("test.txt","a");
            fwrite($handle,$txt);
        fclose($handle);
    }
    
    $uri = $_SERVER['REQUEST_URI']; // $uri enthält command
    if (isset($_GET['user']) &&  isset($_GET['pwd'])) { // kucken ob reguläre Anfrage
        $user = $_GET['user'];
        $pass = $_GET['pwd'];
            
        $port = 32154;
        $handle = fopen ("ip.txt","r"); // meine IP holen (dyndns) - Datei wird extern aktualisiert
            $myip = fgets($handle);
        fclose($handle);
        logger($uri,"ok");    // schreiben das OK
        $link = "Location: http://".trim($myip).":".$port. $uri;
        header($link);
    }else{ // wenn user pass
        logger($uri,"nix");
    }    
    exit();
?>

Das ganze funktioniert allerdings nur, wenn camuser, campass = htaccessuser, htaccesspass ist, als wenn die Cam auch htaccess hätte.
Ich nutze zu Zeit die LogiLink WC0030A (42,-€ bei Pollin) zum testen.
Einsetzen möchte ich später die Axis M3004-V

Mein Strato htaccess schaut so aus:

#######################################################################
#     Diese .htaccess wurde vom STRATO-Webservermanager erstellt      #
#######################################################################
RewriteEngine On
AuthUserFile /mnt/rid/31/42/54113142/htdocs/.htuser
AuthName "Gesicherter Bereich"
AuthType Basic

require user htaccessuser 
RewriteBase /cams/

RewriteCond %{REQUEST_URI} !^/(index\.php)?$ [NC]
RewriteRule ^.*$ /index.php [L]

Kennt jemand das Problem?

Viele Grüße aus LA
ralphi

--
"Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
  1. Hi all,

    ich möchte gerne eine IP-Cam über einen ext. Webserver erreichbar machen.
    In den "meisten" Apps kann ich:
    URL: http://htaccessuser:htaccesspass@cam.meinedomain.de

    Bastelei. Sende einen Authorization Header, hier lies nach, wie das gemacht wird.

    1. Tach!

      Bastelei. Sende einen Authorization Header,

      Wohin? Er setzt doch in seinem gezeigten Code gar keinen Request per Script ab.

      dedlfix.

    2. Hi
      DynDNS Server wird nur bei einigen Stratopaketen angeboten.
      Einen Client in php hab ich (glaub ich 2013) hier im Forum schon veröffentlicht.
      Geht aber auch so ganz gut – entweder per GET oder per FTP Upload
      Zum ermitteln meiner IP hab ich mir vor Zeiten schon (myip.php):

      <?php
          echo getenv("REMOTE_ADDR");
      ?>
      

      auf den Strato gelegt ;-)
      Viele Grüße aus LA
      ralphi

      --
      "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
      1. Mein Artikel beschreibt, wie ein Authorization Header auszusehen hat. Womit user:pass im Request-Header übertragen werden anstatt im URI.

        Das Problem was Du hast:

        1. user:pass im URI war noch nie Standard und funktioniert demzufolge nur bedingt
        2. user:pass im URI kann als Link weitergegben werden und ist eine Sicherheitslücke

        Insbesondere freuen sich Suchmaschinen über (2) und das ist auch der Grund dafür, dass private Webcams, die mit mit speziellen Suchbegriffen gefunden wurden, einfach zu 'hacken' sind, weils Passwort schon eingebaut ist.

        1. Tach!

          Mein Artikel beschreibt, wie ein Authorization Header auszusehen hat. Womit user:pass im Request-Header übertragen werden anstatt im URI.

          Inwieweit hilft das jetzt beim Problem des OP? Die Kamera arbeitet nicht mit HTTP-Auth, die braucht die Zugangsdaten unbedingt in der URL, laut der verlinkten Doku. Dass das sicherheitstechnisch nicht besonders toll ist, steht auf einem anderen Blatt. Lediglich das selbst geschriebene Quasi-Proxy-Script ist mit HTTP-Auth abgesichert (zumindest war das der anscheinend nicht funktionierende Plan), und da erledigt der Browser die Authentifizierung. An welcher Stelle soll er denn nun zu Fuß HTTP-Auth verwenden?

          dedlfix.

  2. Tach!

        if (isset($_GET['user']) &&  isset($_GET['pwd'])) { // kucken ob reguläre Anfrage
            $user = $_GET['user'];
            $pass = $_GET['pwd'];
                
            $port = 32154;
            $handle = fopen ("ip.txt","r"); // meine IP holen (dyndns) - Datei wird extern aktualisiert
                $myip = fgets($handle);
            fclose($handle);
            logger($uri,"ok");    // schreiben das OK
            $link = "Location: http://".trim($myip).":".$port. $uri;
            header($link);
        }else{ // wenn user pass
    

    Du kopiert dir die Variable $_GET['user'] in die Variable $user, aber verwendest weder die eine noch die andere. Beim Passwort genauso.

    Das ganze funktioniert allerdings nur, wenn camuser, campass = htaccessuser, htaccesspass ist, als wenn die Cam auch htaccess hätte.

    Definiere "funktioniert"! Was exakt und aus der Sicht eines Programmierers und nicht nur eines Anwenders soll erreicht werden und was passiert stattdessen?

    Kennt jemand das Problem?

    Ich nicht, du hast es zu ungenau beschrieben. Es wird wohl eher nicht an der Kamera und deren Software liegen.

    dedlfix.

    1. Hi dedlfix,

      Du kopiert dir die Variable $_GET['user'] in die Variable $user, aber verwendest weder die eine noch die andere. Beim Passwort genauso.

      user und pass sind in der $uri
      die wiederum in dem Link zur Cam ist

      $link = "Location: http://".trim($myip).":".$port. $uri;
      

      Ich nicht, du hast es zu ungenau beschrieben. Es wird wohl eher nicht an der Kamera und deren Software liegen.

      USER bei der CAM anlegen (admin, operator, visitor)
      Default (und Pflicht) ist bei der Cam der User
      admin (admin)
      dazu hab ich noch
      ralphi (admin)
      irgendwer (operator)
      und eben
      htaccessuser (admin)
      angelegt.

      Wenn ich nun (auch im Browser):

      http://htaccessuser:htaccesspass@url/videostream.cgi?rate=11&user=ralphi&pwd=meinpass
      

      eingebe - kommt 'auth-error'
      nur bei:

      http://htaccessuser:htaccesspass@url/videostream.cgi?rate=11&user=htaccessuser&pwd=htaccesspass
      

      kommt das Bild/Stream (bei den Apps genauso)
      Viele Grüße aus LA
      ralphi

      --
      "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
      1. Tach!

        Du kopiert dir die Variable $_GET['user'] in die Variable $user, aber verwendest weder die eine noch die andere. Beim Passwort genauso.

        user und pass sind in der $uri

        Das Testen, ob in den beiden Parametern Werte enthalten sind, ist ja o.k. Aberwarum kopierst du dann die Variablen in andere Variablen, wenn du das gar nicht brauchst?

        Wenn ich nun (auch im Browser):

        http://htaccessuser:htaccesspass@url/videostream.cgi?rate=11&user=ralphi&pwd=meinpass
        

        eingebe - kommt 'auth-error'

        Was genau rufst du denn da auf? Die Kamera-Seite oder dein Script? Und welche Komponente bringt die Fehlermeldung? Kommt die mit einem 40x-Fehler? Hast du den Netzwerkverkehr mit den Entwicklertools des Browsers untersucht? Hast du dein Script soweit untersucht, dass zum Beispiel in allen Variablen das drinsteht, was du dir vorgestellt hast?

        dedlfix.

        1. Hi,

          Was genau rufst du denn da auf? Die Kamera-Seite oder dein Script? Und welche Komponente bringt die Fehlermeldung? Kommt die mit einem 40x-Fehler? Hast du den Netzwerkverkehr mit den Entwicklertools des Browsers untersucht? Hast du dein Script soweit untersucht, dass zum Beispiel in allen Variablen das drinsteht, was du dir vorgestellt hast?

          der Link verweist direkt auf die Cam daheim (portforward im Router).
          ich hab auch schon

          $link = "Location: http://".$user.":".$pass."@".trim($myip).":".$port. $uri;  
          

          ausprobiert - mit $user = admin (die $_GET vars)
          da kommt der Fehler: '500 Internal Error'

          Viele Grüße aus LA
          ralphi

          --
          "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
          1. Tach!

            da kommt der Fehler: '500 Internal Error'

            Von welcher Komponente kommt diese Meldung? Ich kann mich nur wiederholen, dass du da genauer analysieren musst. Du hast ja nicht nur ein System, sondern eine ganze Menge Beteiligte und Kommunikation zwischen ihnen in deinem Fall. Hellsehen kann keiner. Fehlersuche ist akribische Arbeit, die dir keiner in einem Forum abnehmen kann, wenn das Problem nicht anderenorts nachvollziehbar ist.

            dedlfix.

            1. Hi all,
              mit einem Browser geht jetzt alles, auch mit anderen CamUsern.
              sorry - war ein Tippfehler gepaart mit dem Port-change von 80 auf xxxxx.

              Das Problem sind die Apps - die wollen nicht mit htaccess :-( arbeiten.
              Ich werd jetzt auf htaccess verzichten und nur 'einfach' sichern.

              Hintergrund war eigentlich die etlichen Reportagen im TV, die zeigten wie DynDNS Webcams gescannt und gehacked werden, was ja relativ einfach ist.

              <?php
              
                  $uri = $_SERVER['REQUEST_URI']; // $uri enthält command
                  $passwd = array("pass1", "pass2", "pass3");
                  
                  if (isset($_GET['user']) ||  isset($_GET['pwd'])) {
                      $user = $_GET['user'];
                      $pass = $_GET['pwd'];
                      if (!in_array ($pass, $passwd)) {exit();}
              
                      $handle = fopen ("ip.txt","r"); // aktuelle ip einlesen
                          $myip = fgets($handle);
                      fclose($handle);
                      $link = "Location: http://".trim($myip). $uri;
                  }else{ // wenn pass falsch
                      $link = "Location: http://meinedomain.eu";
                  }    
                  header($link);
                  exit();
              ?>
              

              Viele Grüße aus LA
              ralphi

              --
              "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.
              1. Nimm Dir einfach mal ein bischen mehr Zeit. Dann lernst Du auch, solche Probleme selbst zu lösen. Das haben Andere schließlich auch geschafft.

  3. Hallo,

    ich möchte gerne eine IP-Cam über einen ext. Webserver erreichbar machen.

    nein, das weiter unten gezeigte Script lässt erkennen, dass der "ext. Webserver" nur die aktuelle passende IP-Adresse nachschlägt und dann eine Weiterleitung dorthin macht. Ergo: Der Client fragt bei deinem Strato-Server bloß nach dem Weg und verbindet sich dann im zweiten Schritt selbst mit der Kamera.
    "Über einen ext. Webserver erreichbar" suggeriert dagegen eher, dass dieser Server als eine Art Proxy zur Kamera arbeitet. Das ist aber offenbar nicht der Fall.

    In den "meisten" Apps kann ich:
    URL: http://htaccessuser:htaccesspass@cam.meinedomain.de
    camuser, campass
    port
    eingeben und den Stream abgreifen (oder andere Befehle).

    Diese Notation (http://user:passwed@example.org) ist aber in HTTP nicht erlaubt. Viele Clients weisen das als fehlerhaft ab; ein paar wenige akzeptieren das, setzen es aber intern um, bevor sie einen Request mit einem korrekten AUTH-Header an den Server absetzen.

    Dabei sendet die App zB:

    url/videostream.cgi?rate=11&user=camuser&pwd=campass
    

    Soso.

    <?php
        $uri = $_SERVER['REQUEST_URI']; // $uri enthält command
        if (isset($_GET['user']) &&  isset($_GET['pwd'])) { // kucken ob reguläre Anfrage
            $user = $_GET['user'];
            $pass = $_GET['pwd'];
                
            $port = 32154;
            $handle = fopen ("ip.txt","r"); // meine IP holen (dyndns) - Datei wird extern aktualisiert
                $myip = fgets($handle);
            fclose($handle);
            logger($uri,"ok");    // schreiben das OK
            $link = "Location: http://".trim($myip).":".$port. $uri;
            header($link);
        }else{ // wenn user pass
            logger($uri,"nix");
        }    
        exit();
    ?>
    

    Tja, wie dedlfix schon sagte: Die aus den GET-Parametern kopierten Werte $user und $pwd verwendest du nie wieder. Sie müssen einfach nur da sein, ganz gleich, mit welchem Wert.

    Das ganze funktioniert allerdings nur, wenn camuser, campass = htaccessuser, htaccesspass ist, als wenn die Cam auch htaccess hätte.

    Und hat sie?

    Wie sieht denn genau der Request aus, den dein Browser nach dem Redirect abschickt? Wiederholt er etwa die Zugangsdaten und die AUTH-Header des ursprünglichen Requests?

    So long,
     Martin

    --
    Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
    - Douglas Adams, The Hitchhiker's Guide To The Galaxy
    1. Hi Martin,

      nein, das weiter unten gezeigte Script lässt erkennen, dass der "ext. Webserver" nur die aktuelle passende IP-Adresse nachschlägt und dann eine Weiterleitung dorthin macht. Ergo: Der Client fragt bei deinem Strato-Server bloß nach dem Weg und verbindet sich dann im zweiten Schritt selbst mit der Kamera.
      "Über einen ext. Webserver erreichbar" suggeriert dagegen eher, dass dieser Server als eine Art Proxy zur Kamera arbeitet. Das ist aber offenbar nicht der Fall.

      da könnts dran liegen - zumindest kenn ich mich zuwenig aus.
      da ja die Apps alle möglichen Dateien aufrufen möchten:
      zB. snapshot.cgi, videostream.cgi
      hab ich einfach alles auf index.php umgeleitet.

          RewriteEngine On
          RewriteCond %{REQUEST_URI} !^/(index\.php)?$ [NC]
          RewriteRule ^.*$ /index.php [L]
      

      ohne zu wissen, was ich da eigentlich tue :-0

      Diese Notation (http://user:passwed@example.org) ist aber in HTTP nicht erlaubt. Viele Clients weisen das als fehlerhaft ab; ein paar wenige akzeptieren das, setzen es aber intern um, bevor sie einen Request mit einem korrekten AUTH-Header an den Server absetzen.

      Stimmt - manche Apps wollen das gar nicht.

      Tja, wie dedlfix schon sagte: Die aus den GET-Parametern kopierten Werte $user und $pwd verwendest du nie wieder. Sie müssen einfach nur da sein, ganz gleich, mit welchem Wert.

      GET user und pass könnt ich der Vollständigkeit natürlich noch auf Richtigkeit prüfen.
      Dadurch könnte ich das Problem auch umgehen, indem ich immer mit htaccessuser den Link zur Cam aufrufe und die Prüfung ausschließlich in der index.php stattfindet. Ist aber weder elegant noch logisch.

      Wie sieht denn genau der Request aus, den dein Browser nach dem Redirect abschickt? Wiederholt er etwa die Zugangsdaten und die AUTH-Header des ursprünglichen Requests?

      Ich tausch eigentlich nur die IP!?

      Viele Grüße aus LA
      ralphi

      --
      "Nicht alles was einfach ist, ist genial, aber alles was genial ist, ist einfach" - Albert E.