Sowohl die Open-Source-Software NGINX als auch NGINX Plus sind als Webserver, Reverse-Proxys und Caches für Ihre Inhalte sehr sicher und zuverlässig. Für zusätzlichen Schutz vor dem Zugriff durch nicht autorisierte Clients können Sie Anweisungen aus dem Secure Link-Modul verwenden, um von den Clients zu verlangen, dass sie in die URL des angeforderten Assets eine bestimmte gehashte Zeichenfolge aufnehmen.
In diesem Blogbeitrag besprechen wir, wie die beiden im Secure Link-Modul implementierten Methoden konfiguriert werden. Die Beispielkonfigurationsausschnitte schützen HTML- und Medienwiedergabelistendateien, können aber auf jeden Typ von HTTP-URL angewendet werden. Die Methoden gelten sowohl für NGINX als auch für NGINX Plus, der Kürze halber beziehen wir uns im Rest des Blogs jedoch nur auf NGINX Plus.
Das Secure Link-Modul überprüft die Gültigkeit einer angeforderten Ressource, indem es eine codierte Zeichenfolge in der URL der HTTP-Anforderung mit der Zeichenfolge vergleicht, die es für diese Anforderung berechnet. Wenn ein Link eine begrenzte Lebensdauer hat und die Zeit abgelaufen ist, gilt der Link als veraltet. Der Status dieser Prüfungen wird in der Variable „$secure_link“
erfasst und zur Steuerung des Verarbeitungsflusses verwendet.
Wie erwähnt bietet das Modul zwei Methoden. In einem bestimmten HTTP-
, Server-
oder Standortkontext
kann nur einer davon konfiguriert werden.
Der erste und einfachere Modus wird durch die Direktive secure_link_secret
aktiviert. Die codierte Zeichenfolge ist ein MD5-Hash, der aus der Verkettung zweier Textzeichenfolgen berechnet wird: dem letzten Teil der URL und einem in der NGINX Plus-Konfiguration definierten geheimen Wort. (Einzelheiten zur ersten Textzeichenfolge finden Sie unter Verwenden einfacher sicherer URLs .)
Um auf die geschützte Ressource zuzugreifen, muss der Client den Hash direkt nach dem URL-Präfix einfügen. Dabei handelt es sich um eine beliebige Zeichenfolge ohne Schrägstriche. In dieser Beispiel-URL lautet das Präfix „videos“ und die geschützte Ressource ist die Datei bunny.m3u8 :
/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hls/bunny.m3u8
Ein Anwendungsfall für diese Methode besteht darin, dass ein Benutzer ein Bild oder Dokument zum Teilen auf einen Server hochlädt, jedoch verhindern möchte, dass jemand, der den Dateinamen kennt, darauf zugreift, bis der offizielle Link veröffentlicht wird.
Die zweite, flexiblere Methode wird durch die Anweisungen secure_link
und secure_link_md5
aktiviert. Hier ist die codierte Zeichenfolge ein MD5-Hash von Variablen, die in der NGINX Plus-Konfigurationsdatei definiert sind. Am häufigsten wird die Variable $remote_addr
eingefügt, um den Zugriff auf eine bestimmte Client-IP-Adresse zu beschränken. Sie können jedoch auch andere Werte verwenden, beispielsweise $http_user_agent
, das den User-Agent
-Header erfasst und so den Zugriff auf bestimmte Browser beschränkt.
Optional können Sie ein Ablaufdatum angeben, nach dem die URL, auch wenn der Hash korrekt ist, nicht mehr funktioniert.
Der Client muss das MD5 -Argument an die Anforderungs-URL anhängen, um den Hash anzugeben. Wenn in der gehashten Zeichenfolge ein Ablaufdatum enthalten ist, muss der Client auch das Argument „expires“ anhängen, um das Datum anzugeben, wie in dieser Beispiel-URL zum Anfordern der geschützten Datei „pricelist.html“ :
/files/pricelist.html?md5=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740
Das Secure Link-Modul ist in vorgefertigten Open-Source -NGINX-Binärdateien von nginx.org , den von Betriebssystemanbietern bereitgestellten NGINX-Paketen und in NGINX Plus enthalten. Es ist nicht standardmäßig enthalten, wenn Sie NGINX aus der Quelle erstellen; aktivieren Sie es, indem Sie dem Konfigurationsbefehl
das Argument --with-http_secure_link_module
hinzufügen.
Die grundlegendere Möglichkeit zum Sichern von URLs ist die Direktive secure_link_secret
. Im folgenden Beispielausschnitt sichern wir eine HTTP Live Streaming (HLS)-Medienwiedergabelistendatei mit dem Namen /bunny.m3u8 . Es wird im Verzeichnis /opt/secure/hls gespeichert, wird Clients jedoch über eine URL zugänglich gemacht, die mit dem Präfix „Videos“ beginnt.
Server {
abhören 80;
Servername secure-link-demo;
Standort /Videos {
secure_link_secret enigma;
if ($secure_link = "") { return 403; }
neu schreiben ^ /secure/$secure_link;
}
Standort /secure {
intern;
root /opt;
}
}
Mit dieser Konfiguration müssen Clients zum Zugriff auf die Datei /opt/secure/hls/bunny.m3u8 die folgende URL angeben:
/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hls/bunny.m3u8
Der gehashte String folgt direkt auf das Präfix, bei dem es sich um einen beliebigen String ohne Schrägstriche handelt (hier: videos ).
Der Hash wird anhand einer Textzeichenfolge berechnet, die zwei Elemente verkettet:
secure_link_secret
, hier enigma
.Wenn die Anforderungs-URL des Clients nicht über den richtigen Hash verfügt, setzt NGINX Plus die Variable $secure_link
auf die leere Zeichenfolge. Der if-
Test schlägt fehl und NGINX Plus gibt die 403
Verbotener
Statuscode in der HTTP-Antwort.
Andernfalls (d. h. der Hash ist korrekt) schreibt die Rewrite-
Direktive die URL um, in unserem Beispiel in /secure/hls/bunny.m3u8 (die Variable $secure_link
erfasst den Teil der URL, der auf den Hash folgt). URLs, die mit /secure beginnen, werden vom zweiten Standortblock
behandelt. Die Root
-Direktive in diesem Block legt /opt als Stammverzeichnis für angeforderte Dateien fest und die interne
Direktive gibt an, dass der Block nur für intern generierte Anforderungen verwendet wird.
Um den MD5-Hash im Hexadezimalformat zu erhalten, den der Client in die URL aufnehmen muss, führen wir den Befehl openssl
md5
mit der Option -hex
aus:
# echo -n 'hls/bunny.m3u8enigma' | openssl md5 -hex (stdin)= 80e2dfecb5f54513ad4e2e6217d36fd4
Eine Erläuterung der programmgesteuerten Hash-Generierung finden Sie unter Programmgesteuertes Generieren von Hashes .
Die folgenden Beispiel -Curl
-Befehle zeigen, wie der Server auf verschiedene sichere URLs reagiert.
Wenn die URL den korrekten MD5-Hash enthält, lautet die Antwort200
OK
:
# curl -I http://secure-link-demo/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hls/bunny.m3u8 | head -n 1 HTTP/1.1 200 OK
Wenn der MD5-Hash falsch ist, lautet die Antwort403
Verboten
:
# curl -I http://secure-link-demo/videos/2c5e80de986b6fc80dd33e16cf824123/hls/bunny.m3u8 | head -n 1 HTTP/1.1 403 Verboten
Wenn der Hash für bunny.m3u8 für eine andere Datei verwendet wird, lautet die Antwort ebenfalls403
Verboten
:
# curl -I http://secure-link-demo/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hs/oven.m3u8 | head -n 1 HTTP/1.1 403 Verboten
Die flexiblere Methode zum Sichern von URLs verwendet die Anweisungen secure_link
und secure_link_md5
. In diesem Beispiel verwenden wir sie, um den Zugriff auf die Datei /var/www/files/pricelist.html nur von Clients mit der IP-Adresse 192.168.33.14 und nur bis zum 31. Dezember 2016 zuzulassen.
Unser virtueller Server lauscht auf Port 80 und verarbeitet alle gesicherten HTTP-Anfragen im Speicherort-
/Files
-Block, wobei die Root-
Direktive /var/www als Stammverzeichnis für angeforderte Dateien festlegt.
Die Direktive „secure_link“
definiert zwei Variablen, die Argumente in der Anforderungs-URL erfassen: „$arg_md5“
wird auf den Wert des „md5“ -Arguments gesetzt und „$arg_expires“
auf den Wert des „expires “-Arguments.
Die Direktive secure_link_md5
definiert den Ausdruck, der gehasht wird, um den MD5-Wert für die Anfrage zu generieren; während der URL-Verarbeitung wird der Hash mit dem Wert von $arg_md5
verglichen. Der Beispielausdruck hier enthält die in der Anforderung übergebene Ablaufzeit (erfasst in der Variable $secure_link_expires
), die URL ( $uri
), die Client-IP-Adresse ( $remote_addr
) und das Wort enigma
.
Server {
Listen 80;
Servername secure-link-demo;
Standort /files {
root /var/www;
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$uri$remote_addr enigma";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
}
}
Um mit dieser Konfiguration auf /var/www/files/pricelist.html zuzugreifen, muss ein Client mit der IP-Adresse 192.168.33.14 diese Anforderungs-URL vor Samstag, 31. Dezember 2016, 23:59:00 UTC senden:
/files/pricelist.html?md5=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740
Wenn der Hash in der vom Client gesendeten URL (erfasst in der Variable $arg_md5
) nicht mit dem aus der Direktive secure_link_md5
berechneten Hash übereinstimmt, setzt NGINX Plus die Variable $secure_link
auf die leere Zeichenfolge. Der if-
Test schlägt fehl und NGINX Plus gibt die403
Verbotener
Statuscode in der HTTP-Antwort.
Wenn die Hashes übereinstimmen, der Link jedoch abgelaufen ist, setzt NGINX Plus den $sicherer_Link
variabel auf 0
; wieder die Wenn
Der Test schlägt fehl, aber dieses Mal gibt NGINX Plus das 410
Gegangen
Statuscode in der HTTP-Antwort.
Sehen wir uns nun an, wie ein Client die MD5- und Ablaufargumente berechnet, die in die URL aufgenommen werden sollen.
Der erste Schritt besteht darin, das Unix-Zeitäquivalent des Ablaufdatums zu bestimmen, da dieser Wert in Form der Variablen $secure_link_expires
im gehashten Ausdruck enthalten ist. Um die Unix-Zeit zu erhalten – die Anzahl der Sekunden seit Epoche (1970-01-01 00:00:00 UTC) – verwenden wir den Datumsbefehl
mit der Option -d
und dem Formatbezeichner +%s
.
In unserem Beispiel legen wir die Ablaufzeit auf Samstag, 31. Dezember 2016, 23:59:00 UTC fest. Der Befehl lautet also:
# Datum -d "2016-12-31 23:59" +%s1483228740
Der Client schließt diesen Wert als Argument expires=1483228740 in die Anforderungs-URL ein.
Nun führen wir den durch die Direktive secure_link_md5
definierten String – $secure_link_expires$uri$remote_addr
enigma
– durch drei Befehle aus:
openssl
md5
mit der Option -binary
generiert den MD5-Hash im Binärformat.openssl
base64
wendet die Base64- Kodierung auf den Hashwert an.tr
-Befehle ersetzen das Pluszeichen ( +
) durch den Bindestrich ( -
) und den Schrägstrich ( /
) durch den Unterstrich ( _
) und löschen das Gleichheitszeichen ( =
) aus dem codierten Wert.Für unser Beispiel lautet der vollständige Befehl:
# echo -n '1483228740/files/pricelist.html192.168.33.14 enigma' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d = AUEnXC7T-Tfv9WLsWbf-mw
Der Client schließt diesen Wert als Argument md5=AUEnXC7T-Tfv9WLsWbf-mw in die Anforderungs-URL ein.
Wenn Ihr NGINX Plus-Webserver dynamische Inhalte von einem Anwendungsserver bereitstellt, müssen sowohl NGINX Plus als auch der Anwendungsserver dieselbe sichere URL verwenden. Sie können den Hash für das MD5 -Argument in der URL programmgesteuert generieren. Die folgende Node.js-Funktion generiert einen Hash, der mit dem im obigen NGINX Plus-Konfigurationsausschnitt definierten übereinstimmt. Es verwendet eine Ablaufzeit, eine URL, eine Client-IP-Adresse und ein geheimes Wort als Argumente und gibt den Base64-codierten MD5-Hash im Binärformat zurück.
var crypto = require("crypto");
Funktion generateSecurePathHash(expires, url, client_ip, secret) {
if (!expires || !url || !client_ip || !secret) {
return undefiniert;
}
var input = expires + url + client_ip + " " + secret;
var binaryHash = crypto.createHash("md5").update(input).digest();
var base64Value = neuer Puffer(binaryHash).toString('base64');
return base64Value.replace(/=/g, '').replace(/+/g, '-').replace(///g, '_');
}
Um den Hash für unser aktuelles Beispiel zu berechnen, übergeben wir diese Argumente:
generateSecurePathHash(neues Datum('12/31/2016 23:59:00').getTime()), '/files/pricelist.html', „192.168.33.14“, „enigma“);
Die folgenden Beispiel -Curl
-Befehle zeigen, wie der Server auf sichere URLs reagiert.
Wenn ein Client mit der IP-Adresse 192.168.33.14 den korrekten MD5-Hash und die Ablaufzeit angibt, lautet die Antwort200
OK
:
# curl -I --interface "192.168.33.14" 'http://secure-link-demo/files/pricelist.html?md5=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740' | head -n 1 HTTP/1.1 200 OK
Wenn ein Client mit einer anderen IP-Adresse dieselbe URL sendet, lautet die Antwort403
Verboten
:
# curl -I --interface "192.168.33.33" 'http://secure-link-demo/files/pricelist.html?md5=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740' | head -n 1 HTTP/1.1 403 Verboten
Wenn der Hashwert des MD5 -Arguments falsch ist, lautet die Antwort403
Verboten
:
# curl -I --interface "192.168.33.14" 'http://secure-link-demo/files/pricelist.html?md5=qeUNjiY2FTIVMaXUsxG-7w&expires=1483228740' | head -n 1 HTTP/1.1 403 Verboten
Wenn die URL abgelaufen ist (das durch das Argument expires dargestellte Datum liegt in der Vergangenheit), lautet die Antwort410
Gegangen
:
# curl -I --interface "192.168.33.14" 'http://secure-link-demo/files/pricelist.html?md5=Z2rNva2InyVcRTlhqAkT4Q&expires=1467417540' | head -n 1 HTTP/1.1 410 Weg
Hier ist ein weiteres Beispiel für eine sichere URL mit Ablaufdatum, die zum Schutz sowohl der Wiedergabeliste für ein Medienobjekt als auch der Segmentdateien verwendet wird.
Ein Unterschied zum vorhergehenden Beispiel besteht darin, dass wir hier einen Kartenkonfigurationsblock
hinzufügen, um die Erweiterung aus der Wiedergabeliste ( .m3u8 -Datei) und aus den HLS-Segmenten ( .ts -Dateien) zu entfernen, während wir den Dateinamen in der Variable „$file_name“
erfassen, die an die Direktive „secure_link_md5“
übergeben wird. Dies dient der Absicherung der Anfragen sowohl an die einzelnen .ts Segmente als auch an die Playlist.
Ein weiterer Unterschied zum ersten Beispiel besteht darin, dass wir die Variable $http_user_agent
(die den User-Agent-
Header erfasst) in die Direktive secure_link_md5
aufnehmen, um den Zugriff auf Clients in bestimmten Webbrowsern einzuschränken (beispielsweise, damit die URL in Safari funktioniert, aber nicht in Chrome oder Firefox).
map $uri $file_name {
Standard keine;
"~*/s/(?<name>.*).m3u8" $name;
"~*/s/(?<name>.*).ts" $name;
}
Server {
abhören 80;
Servername secure-link-demo;
Standort /s {
root /opt;
secure_link $arg_md5,$arg_expires;
secure_link_md5 "$secure_link_expires$file_name$http_user_agent enigma";
if ($secure_link = "") { return 403; }
if ($secure_link = "0") { return 410; }
}
}
Mit dem Secure Link-Modul in NGINX können Sie Dateien vor unberechtigtem Zugriff schützen, indem Sie verschlüsselte Daten hinzufügen, beispielsweise den Hash eines bestimmten Teils der URL. Durch das Hinzufügen einer Ablaufzeit wird auch die Gültigkeitsdauer von Links begrenzt, um die Sicherheit noch weiter zu erhöhen.
Um NGINX Plus auszuprobieren, starten Sie noch heute Ihre kostenlose 30-Tage-Testversion oder kontaktieren Sie uns, um Ihre Anwendungsfälle zu besprechen.
„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."