ubuntuusers.de

Apache Config, Dateien außerhabl DocumentRoot

Status: Ungelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

Pille456

Anmeldungsdatum:
24. März 2007

Beiträge: 194

Hio! Hab hier zu Hause einen apache2 Server laufen, der soweit auch funktioniert. Nun möchte ich auf Dateien außerhalb des DocumentRoot zugreifen, d.h. konkret einen Ordner per PHP durchsuchen und die Dateien entsprechend verlinken. Das Durchsuchen mit PHP klappt soweit gut und ohne Probleme, nur kann ich die Dateien nie runterladen, da sie laut apache2 nicht vorhanden sind. Die Ordnerstruktur sieht dabei so aus: DocumentRoot /media/Daten/WWW Dateien die ich hosten möchte sind unter /media/Daten /media/Daten als DocumentRoot zu nutzen kommt nicht in Frage, da dort auch Dateien als lokale Freigabe liegen, ich will schon eine strenge Regelung zwischen den Internet-Dateien unter ../WWW und /media/Daten, d.h. auf die Dateien unter /media/Daten soll man nur per PHP/HTML zugreifen können. Hab schon einen entsprechenden Eintrag in der /etc/apache2/sites-available/default geändert, aber ohne Erfolg. Hier mal die Datei:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#...
<VirtualHost *:80>
        #...

        DocumentRoot /media/Daten/WWW

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>

        <Directory /media/Daten/WWW>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>
        Alias /Download/ /media/Daten

        <Directory /media/Daten>
               Options None
               AllowOverride None
              Order deny,allow
              allow from all
        </Directory>
#...

Ah, Edit: Ich kann den Zugriff nun soweit steuern, dass der User auf Daten wie /media/Daten/Share/test.doc runterladen können, aber keinen Zugriff auf die Ordner einzeln haben - also soweit das was ich möchte. Nun kann man, wie nicht anders zu erwarten, die Dateien auch per Direkteingabe in den Browser herunterladen. Gibt es da auch eine Möglichkeit das zu Unterbinden? Also, dass man Dateien jeglicher Art nur über die Seite sehen und herunterladen kann? Hier mal meine /sites-available/default:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Alias /test/ /media/Daten/
        <Directory /media/Daten>
                Options None
                AllowOverride None
                Order Deny,Allow
                # Hatte erst das hier versucht, aber ohne Erfolg
                # deny from all
                # all from localhost
                allow from all
        </Directory>

frabron

Anmeldungsdatum:
11. Februar 2007

Beiträge: 151

An deiner Stelle würde ich das komplett mittels PHP realisieren anstatt den Apache so zu verbiegen und direkten Zugriff auf die Dateien zu gewähren. Evt. findest du ja auch schon eine Anwendung die deinen Ansprüchen genügt - ist ja nun nix neues was du willst ☺

Oder du benutzt sowas wie WebDAV.

Achso, und wenn es nur innerhalb des Hausnetzwerks funktionieren soll, würde ich auf einen anderen Dienst setzen (Samba?). Eigentlich könnte man das sogar mittels ssh realisieren und einen Dateimanager benutzen, der das Protokoll unterstützt, unter Windows gibts da auch einige, WinSCP z.B.

Dakuan

Avatar von Dakuan

Anmeldungsdatum:
2. November 2004

Beiträge: 6503

Wohnort: Hamburg

Das Durchsuchen mit PHP klappt soweit gut und ohne Probleme, nur kann ich die Dateien nie runterladen, da sie laut apache2 nicht vorhanden sind.

Ich denke mal das ist so gewollt und sollte auch so bleiben. Ich vermute mal das du die Datei als Link in einem HTML Dokument anbieten möchtest. Wenn das ginge, wäre das nicht gut, da jeder aus dem Link einen Teil der Verzeichnisstruktur ablesen könnte und dann einfach nach diesem Muster eigene GET Abfragen basteln kann.

Die einzige Möglichkeit besteht darin die Datei direkt von PHP senden zu lassen. Allerdings must du dann auch den Content Header selber erzeugen.

frabron

Anmeldungsdatum:
11. Februar 2007

Beiträge: 151

Mittels PHP hat man normalerweise keine Probleme, Dateien ausserhalb des Webroots zu lesen. So kann man sich mit ein paar Funktionen und dem richtigen Header auch einen Downloadservice basteln. Das hat aber auch einiges an Risikopotential, deshalb sollte man da schon wissen, was man macht.

r4z1eL

Anmeldungsdatum:
7. Juni 2007

Beiträge: 22

http://de.php.net/manual/de/function.header.php#83384

Ist ein Beispiel aber musste abändern.

Übergebe nicht den Pfad zur Datei über GET oder POST. Sowas ist manipulierbar. Verschlüssel den Pfad oder sowas. Ich übergebe das z.B unteranderem über die $_SESSION Variable.

Pille456

(Themenstarter)

Anmeldungsdatum:
24. März 2007

Beiträge: 194

Ahh, dass sind die Ansätze, die ich gebraucht habe - danke! Es war mir so nicht bewusst, dass man Dateien auch per PHP senden kann, hatte nur den "naiven" Ansatz gewählt und die Links mittels PHP erzeugt und dann als HTML ausgegeben. Also es soll ähnlich einem Intranet werden, aber auf ein Intranet kann man in vielen Fällen auch von woanders zugreifen, daher ja auch der Webserver. Sonst hätte bzw. habe ich ja auch hier für zu Hause einen Samba-Server laufen ☺ Aber denke mal wenn ich mich ein wenig in PHP einarbeite, dann wird das klappen - danke!

P.S: Ich habe gerade nochmal nachgeschaut, es gibt einen Eintrag in der php.ini, der steuert ob man mittels PHP auf Dateien außerhalb des DocumentRoot zugreifen darf, daher ist diese Funktion durchaus erwünscht und, wie in diesem Beispiel, auch sinnvoll

frabron

Anmeldungsdatum:
11. Februar 2007

Beiträge: 151

Ich habe das mal so realisiert

1
2
3
4
5
6
7
8
9
        if (is_file($file)) {
                if (function_exists('mime_content_type')) {
                        $mime = mime_content_type($file);
                        $filename = pathinfo($file, PATHINFO_BASENAME);
                        header('Content-type: '.$mime.' ');
                        header('Content-Disposition: attachment; filename='.str_replace(' ','_',$filename).'');
                        readfile($file);
                }
        }

In $file steht dann der komplette Pfad zur Datei. Ich würde mir einen Algorithmus ausdenken anhand dessen der Pfad zur Datei abgeleitet werden kann. Niemals frei wählbare Pfade erlauben, sondern nur fest definierte, die sich kombinieren lassen.

Also sowas wie

1
2
$maindir = '/downloads';
$subdirs = array('dir1','dir2');

und nur Kombinationen aus $maindir + $subdir erlauben. Immer prüfen, ob die Datei auch wirklich existiert und nicht doch noch auf /etc/passwords zeigt 😀 Man kann da leider nicht paranoid genug sein ...

Was in dem Beispiel oben noch fehlt, ist das Abfangen des Rückgabewertes von readfile und die entsprechende Reaktion im Skript darauf.

r4z1eL

Anmeldungsdatum:
7. Juni 2007

Beiträge: 22

Zur Zeit baue ich zufällig etwas ähnliches wie du. Eine Art webbasierender Filebrwoser. In der php.ini bräuchtest du nichts ändern eigentlich! Wie schon bereits erwähnt. "Verfummel" Apache bzw. PHP nicht so.

Wenn die Dateien z.B. sonst wo sind, aber nicht im RootDir von Apache ist es doch einfach, ein symbolischen Link zu setzten.

ln -s /media/Daten daten

Dann hab ich eine .htaccess in Daten erstellt mit der Anweisung alle zu sperren außer "localhost"...

1
2
3
 Order Deny,Allow
 Deny from All
 Allow from loalhost

...und greife einfach mit einer PHP Datei darauf zu, da diese als bzw. von "localhost" ausgeführt wird.

Das war für mich die einfachste Sache. Wie schon erwähnt übergebe ich die Pfade über die $_SESSION Variable. Weil damit der Client nichts zu tun hat. Hatte für mich den Sinn auch mich vor Linkklau zu schützen. Obendrauf verschlüssele ich die Zeit (ist dann immer ein anderer Wert) und den Pfad mit z.B. MD5 und übergebe das Ergebnis über POST und SESSION und wird in der andere PHP Datei auch gebildet und verglichen. Der User sieht nur sowas wie "getData.php?payload=f6767fefe925096e638ec1354ade28ae" und ist immer eine andere auch wenn es die gleiche Datei ist. ^^

Im Link den ich dir geschrieben habe ist noch was erwähnt:

1
2
3
4
5
6
7
$fpFile = fopen($filename, "r");
while(!feof($fpFile))
{
      echo @fread($fpFile, 65536);
      flush();
}
fclose($fpFile);

Das musst du so machen wenn du große Dateien herunterladen willst. Sonst hau sich PHP die Datei in den Magen und dann erst zum Clienten senden. Ergo beim Clienten passiert in der Zeit erst mal gar nichts und es braucht ne Zeit bis sein Downloadfenster öffnet.

Ist aber in meine Auge nur eine Lösung. Es gibt noch bestimmt andere bzw. bessere Lösungen.

(Darf ich sagen das PHP eine Sau geile Sprache ist?! 😉 )

melc

Anmeldungsdatum:
28. Dezember 2008

Beiträge: 181

Wohnort: Karlsruhe

r4z1eL schrieb:

Wenn die Dateien z.B. sonst wo sind, aber nicht im RootDir von Apache ist es doch einfach, ein symbolischen Link zu setzten.

ln -s /media/Daten daten

Dann hab ich eine .htaccess in Daten erstellt mit der Anweisung alle zu sperren außer "localhost"...

1
2
3
 Order Deny,Allow
 Deny from All
 Allow from loalhost

...und greife einfach mit einer PHP Datei darauf zu, da diese als bzw. von "localhost" ausgeführt wird.

Wenn du mit den PHP-Skripten nicht wieder über den Webserver auf die Dateien zugreifst, sondern direkt auf Dateisystem-Ebene, kannst du dir das sparen.

Antworten |