padman
Goto Top

Dateien, Verzeichnis vor direktem Zugriff schützen, Zugfriff nur vom PHP-Script

Hallo,
ich habe eine sehr komplizierte Frage um diese Uhrzeit.

Szenario:
Ein Ordner bzw. dessen Dateien sollen vor einem direkten Zugriff geschützt werden. Es existiert ein PHP-Script, welches aber auf die Dateien zugreifen darf und dementsprechend dem Besucher auch ausliefern soll, nur eben nicht direkt.

Es geht um HLS, wo in einem Ordner .m3u8 wie auch .ts generiert werden, nur soll der direkte Zugriff per URL verhindert werden. Ursprünglich dachte ich am Apache (2.4) mit mindestens Auth Basic, wo die Zugangsdaten im PHP-Script enthalten sind, und sobald das Script aufgerufen wird, werden die Daten auch ausgeliefert. Würde ein Besucher die URL direkt aufrufen, käme der Anmelde-Dialog von Apache.

Unter Apache 2.4 könnte man in der .htaccess
Require all denied
einfügen, aber damit klappt die Auslieferung der Dateien auch nicht.

Es geht darum, dass kein unbefugter die Dateien direkt abgreifen kann sondern dass es nur per PHP-Script geht. Das PHP-Script ist so aufgebaut, das im switch/case
header header("Content-type: application/x-mpegURL; charset=utf-8");  
steht, wie auch #EXTM3Um #EXT-X-VERSION:4, #EXT-X-INDEPENDENT-SEGMENTS usw.. Die Ausgabe klappt damit perfekt und die passende .m3u8 samt ihren .ts-Dateien werden ausgegeben.

Für das komplizierte Szenario möchte ich mich entschuldigen.

Ich für meinen Teil wüsste nicht, wie die generierten Inhalte vor direktem Zugriff geschützt werden können, jedoch vom PHP-Script die Ausgabe ermöglicht werden könnte. Die Medienausgabe selber findet in einem Player statt, da das Script mit vielen Parametern aufgerufen werden muss, damit andere wie auch irgendwelche Crawler oder wer auch immer, nicht direkt zugreifen kann.

Vielen Dank und noch einen schönen Tag.

Content-Key: 61881172382

Url: https://administrator.de/contentid/61881172382

Printed on: May 5, 2024 at 07:05 o'clock

Member: StefanKittel
StefanKittel Aug 28, 2023 updated at 07:22:35 (UTC)
Goto Top
Moin,

Du könntest folgendes machen.

Die Dateien liegen nicht "im" Http-Basis-Verzeichnis sondern "darüber" oder "daneben".
Damit sind sie schonmal nicht per http direkt aufrufbar. Dein PHP-Skript kann aber mit file_get_contents darauf zugreifen.

z.B.
/var/www/html für Deien PHP-, HTML-, CSS- und JS-Dateien.
/var/www/data für Deine Daten-Dateien.

Dann verwendest Du ein Session-Login-System und einen GET-Parameter oder URL zum ausliefern der Dateien.

// Start the session
session_start();

if(!isset($_SESSION['username']))  
{
//show login form
die();
}
//deliver data

Stefan
Member: StefanKittel
StefanKittel Aug 28, 2023 updated at 07:25:14 (UTC)
Goto Top
Zusatz.
Mit einer ".htaccess" sagst Du dem Browser, dass jede URL durch Deine index.php laufen soll.
In der prüfst Du die URI, lädst die Daten und gibst diese aus.

Man kann natürlich auch ein https://www.firma.de/deliver.php?file=datei15.pdf ausliefern.

DirectoryIndex index.php

RewriteEngine on
RewriteBase /
RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Ich habe mit so etwas eine kleine Bild-Webseite erstellt.
Zuerst kommt der Login und danach kann man die Bilder sehen.
Member: lastcentral
lastcentral Aug 28, 2023 at 09:07:08 (UTC)
Goto Top
Wie @StefanKittel sagt, PHP kommt über das Dateisystem an die Dateien und nicht über den Webserver, daher diese Dateien über .htaccess verbieten oder, was noch besser ist, eben gleich ausserhalb des wwwroot ablegen.

Da die PHP Dateien erlaubt bleiben sollen, könntest Du über die Dateinamen gehen, und nur die entsprechenden Dateinamen-Erweiterungen verbieten, und das ist, glaube ich, die direkte Antwort auf Deine Frage:

<FilesMatch "\.(m3u8|ts)$">  
    Require all denied
</FilesMatch>

besser ist natürlich eine Whitelist und noch besser, wie @StefanKittel sagt, die Dateien in einem Pfad ausserhalb des wwwroot zu generieren (vielleicht ein eigenes tmp-Verzeichnis). Allerdings würde ich es einfach halten, RewriteRules können verwirrend sein und dann ändert man die später mal und denkt nicht dran, dass da Sicherheit dran hängt, aber das sind Details.
Member: PadMan
PadMan Aug 29, 2023 updated at 04:24:26 (UTC)
Goto Top
Vielen Dank für eure Vorschläge. Die kann ich erst später testen.

Wie erwähnt, sollen auf die generierten HLS-Dateien zugegriffen werden dürfen, aber nur eben dass es vom PHP-Script erlaubt ist.

Die generierten Dateien werden im Temp-Verzeichnis abgelegt, nur dass im Hauptverzeichnis ein verlinkter Ordner sich befindet.

Inwieweit file_get_contents funktionieren könnte, wäre noch eine gute Frage 😉

Das "PHP-Script" ist im Prinzip die "master.m3u8", die sucht für die passende Auflösung die andere .m3u8 raus, die ja generiert wird und die dazu generierten .ts-Dateien werden ja ausgegeben.

Ich probiere mich später mal durch.
Member: lastcentral
lastcentral Aug 29, 2023 at 14:46:09 (UTC)
Goto Top
Quote from @PadMan:

Vielen Dank für eure Vorschläge. Die kann ich erst später testen.

Wie erwähnt, sollen auf die generierten HLS-Dateien zugegriffen werden dürfen, aber nur eben dass es vom PHP-Script erlaubt ist.

Die generierten Dateien werden im Temp-Verzeichnis abgelegt, nur dass im Hauptverzeichnis ein verlinkter Ordner sich befindet.

Inwieweit file_get_contents funktionieren könnte, wäre noch eine gute Frage 😉

Das "PHP-Script" ist im Prinzip die "master.m3u8", die sucht für die passende Auflösung die andere .m3u8 raus, die ja generiert wird und die dazu generierten .ts-Dateien werden ja ausgegeben.

Ich probiere mich später mal durch.

mmm... Warum gibt es den verlinkten Ordner, wenn man da gar nicht rankommen soll? Den Vorschlag, den Link dann halt zu löschen, brauch ich Dir nicht geben, da wärst Du ja selbst drauf gekommen face-smile

Wenn das PHP Script so heißt, wie eine der Dateien, dann geht das Blocken über Erweiterung natürlich nicht so einfach face-smile

file_get_contents liest aus der Datei, also z.b. aus "/tmp/...../...../...m3u8", darauf hat das <FilesMatch "\.(m3u8|ts)$"> vom Webserver keinen Einfluss.
Member: PadMan
PadMan Aug 29, 2023 updated at 19:23:42 (UTC)
Goto Top
Zitat von @lastcentral:
mmm... Warum gibt es den verlinkten Ordner, wenn man da gar nicht rankommen soll? Den Vorschlag, den Link dann halt zu löschen, brauch ich Dir nicht geben, da wärst Du ja selbst drauf gekommen face-smile
Den verlinkten Ordner gab es vor dem PHP-Script 😇aber das Löschen des Links ist natürlich kein Problem 😁

Nein, das PHP-Script hat einen willkürlichen Namen und der passende Header wie auch das andere kann nur mit einem willkürlichen Parameter (switch/case) aufgerufen werden, die Parameter bestehen einfach aus zufällig generierten UUID's 😂, die generierte .m3u8 die von FFmpeg generiert wird, hat ebenfalls einen statischen, willkürlichen Namen, die .ts-Dateien haben lange, verschiedene Zahlen, die von DateTime zufällig generiert werden, in der Regel wäre nicht vorauszusehen, welchen Namen die nächsten .ts-Datei erhalten und nur die generierte .m3u8 kennt die richtige Reihenfolge 😂
Wenn das PHP Script so heißt, wie eine der Dateien, dann geht das Blocken über Erweiterung natürlich nicht so einfach face-smile
Das Script hat wie oben erwäht, einen anderen Namen 😉
file_get_contents liest aus der Datei, also z.b. aus "/tmp/...../...../...m3u8", darauf hat das <FilesMatch "\.(m3u8|ts)$"> vom Webserver keinen Einfluss.
OK...

Hier der Teil des Codes:
Momentan gibt es nur eine generierte .m3u8, die 1080 liefert...

.htaccess
RewriteRule <irgendeine-UUID>.m3u8 <irgendeine-UUID>.php [L,QSA]
Dateiname: <irgendeine-UUID>.php)
switch($_GET['<irgendeine-UUID>']) {  
case '<irgendeine-UUID>':  
header("Content-type: application/x-mpegURL; charset=utf-8");  
print '#EXTM3U  
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=4664000,AVERAGE-BANDWIDTH=4030400,CODECS="avc1.640029,mp4a.40.2",RESOLUTION=1920x1080,FRAME-RATE=25.000 
<irgendeine-UUID>/<irgendeine-UUID>-0.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2622400,AVERAGE-BANDWIDTH=2270400,CODECS="avc1.640029,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=25.000 
#
#EXT-X-STREAM-INF:BANDWIDTH=1601600,AVERAGE-BANDWIDTH=1390400,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=960x540,FRAME-RATE=25.000  
#
#EXT-X-STREAM-INF:BANDWIDTH=708400,AVERAGE-BANDWIDTH=620400,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=640x360,FRAME-RATE=25.000  
#
#EXT-X-STREAM-INF:BANDWIDTH=70400,AVERAGE-BANDWIDTH=70400,CODECS="mp4a.40.2"  
#';  
break;