Le logiciel open source NGINX et NGINX Plus sont tous deux très sécurisés et fiables en tant que serveurs Web, proxys inverses et caches pour votre contenu. Pour une protection supplémentaire contre l'accès par des clients non autorisés, vous pouvez utiliser des directives du module Secure Link pour exiger que les clients incluent une chaîne hachée spécifique dans l'URL de la ressource qu'ils demandent.
Dans cet article de blog, nous expliquerons comment configurer les deux méthodes implémentées dans le module Secure Link. Les extraits de configuration d'exemple protègent les fichiers HTML et les listes de lecture multimédia, mais peuvent être appliqués à tout type d'URL HTTP. Les méthodes s’appliquent à la fois à NGINX et à NGINX Plus, mais par souci de concision, nous ferons uniquement référence à NGINX Plus pour le reste du blog.
Le module Secure Link vérifie la validité d'une ressource demandée en comparant une chaîne codée dans l'URL de la requête HTTP avec la chaîne qu'il calcule pour cette requête. Si un lien a une durée de vie limitée et que le délai a expiré, le lien est considéré comme obsolète. L'état de ces contrôles est capturé dans la variable $secure_link
et utilisé pour contrôler le flux de traitement.
Comme mentionné, le module fournit deux méthodes. Un seul d'entre eux peut être configuré dans un contexte http
, serveur
ou emplacement
donné.
Le premier mode, plus simple, est activé par la directive secure_link_secret
. La chaîne codée est un hachage MD5 calculé sur la concaténation de deux chaînes de texte : la partie finale de l'URL et un mot secret défini dans la configuration NGINX Plus. (Pour plus de détails sur la première chaîne de texte, voir Utilisation des URL sécurisées de base .)
Pour accéder à la ressource protégée, le client doit inclure le hachage juste après le préfixe de l'URL, qui est une chaîne arbitraire sans aucune barre oblique. Dans cet exemple d'URL, le préfixe est videos et la ressource protégée est le fichier bunny.m3u8 :
/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hls/bunny.m3u8
Un cas d’utilisation de cette méthode est lorsqu’un utilisateur télécharge une image ou un document sur un serveur pour le partager, mais souhaite empêcher toute personne connaissant le nom du fichier d’y accéder jusqu’à ce que le lien officiel soit publié.
La deuxième méthode, plus flexible, est activée par les directives secure_link
et secure_link_md5
. Ici, la chaîne codée est un hachage MD5 de variables définies dans le fichier de configuration NGINX Plus. Le plus souvent, la variable $remote_addr
est incluse pour restreindre l'accès à une adresse IP client particulière, mais vous pouvez utiliser d'autres valeurs, par exemple $http_user_agent
, qui capture l'en-tête User-Agent
et restreint ainsi l'accès à certains navigateurs.
En option, vous pouvez spécifier une date d'expiration après laquelle l'URL ne fonctionne plus même si le hachage est correct.
Le client doit ajouter l’argument md5 à l’URL de la demande pour spécifier le hachage. Si une date d'expiration est incluse dans la chaîne hachée, le client doit également ajouter l'argument expires pour spécifier la date, comme dans cet exemple d'URL pour demander le fichier protégé pricelist.html :
/files/pricelist.html?md5=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740
Le module Secure Link est inclus dans les binaires NGINX open source prédéfinis de nginx.org , les packages NGINX fournis par les fournisseurs de systèmes d'exploitation et dans NGINX Plus . Il n'est pas inclus par défaut lorsque vous créez NGINX à partir de la source ; activez-le en incluant l'argument --with-http_secure_link_module
à la commande configure
.
La manière la plus simple de sécuriser les URL est d'utiliser la directive secure_link_secret
. Dans l'extrait d'exemple suivant, nous sécurisons un fichier de liste de lecture multimédia HTTP Live Streaming (HLS) nommé /bunny.m3u8 . Il est stocké dans le répertoire /opt/secure/hls , mais est exposé aux clients utilisant une URL qui commence par le préfixe des vidéos .
serveur {
écoute 80 ;
nom_serveur secure-link-demo ;
emplacement /vidéos {
secure_link_secret enigma ;
si ($secure_link = "") { retour 403 ; }
réécriture ^ /secure/$secure_link ;
}
emplacement /secure {
interne ;
racine /opt ;
}
}
Avec cette configuration, pour accéder au fichier /opt/secure/hls/bunny.m3u8 les clients doivent présenter l'URL suivante :
/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hls/bunny.m3u8
La chaîne hachée vient juste après le préfixe, qui est une chaîne arbitraire sans aucune barre oblique (ici, vidéos ).
Le hachage est calculé sur une chaîne de texte qui concatène deux éléments :
secure_link_secret
, ici enigma
.Si l'URL de demande du client n'a pas le hachage correct, NGINX Plus définit la variable $secure_link
sur la chaîne vide. Le si
le test échoue et NGINX Plus renvoie le 403
Interdit
code d'état dans la réponse HTTP.
Sinon (ce qui signifie que le hachage est correct), la directive de réécriture
réécrit l’URL – dans notre exemple vers /secure/hls/bunny.m3u8 (la variable $secure_link
capture la partie de l’URL qui suit le hachage). Les URL commençant par /secure sont gérées par le deuxième bloc d'emplacement
. La directive racine
de ce bloc définit /opt comme répertoire racine pour les fichiers demandés et la directive interne
spécifie que le bloc est utilisé uniquement pour les demandes générées en interne.
Pour obtenir le hachage MD5 au format hexadécimal que le client doit inclure dans l'URL, nous exécutons la commande openssl
md5
avec l'option -hex
:
# echo -n 'hls/bunny.m3u8enigma' | openssl md5 -hex (stdin)= 80e2dfecb5f54513ad4e2e6217d36fd4
Pour une discussion sur la génération de hachages par programmation, voir Génération du hachage par programmation .
Les exemples de commandes curl
suivants montrent comment le serveur répond à différentes URL sécurisées.
Si l'URL inclut le hachage MD5 correct, la réponse est200
D'ACCORD
:
# curl -I http://secure-link-demo/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hls/bunny.m3u8 | head -n 1 HTTP/1.1 200 OK
Si le hachage MD5 est incorrect, la réponse est403
Interdit
:
# curl -I http://secure-link-demo/videos/2c5e80de986b6fc80dd33e16cf824123/hls/bunny.m3u8 | head -n 1 HTTP/1.1 403 Interdit
Si le hachage de bunny.m3u8 est utilisé pour un fichier différent, la réponse est également403
Interdit
:
# curl -I http://secure-link-demo/videos/80e2dfecb5f54513ad4e2e6217d36fd4/hs/oven.m3u8 | head -n 1 HTTP/1.1 403 Interdit
La méthode la plus flexible pour sécuriser les URL utilise les directives secure_link
et secure_link_md5
. Dans cet exemple, nous les utilisons pour autoriser l'accès au fichier /var/www/files/pricelist.html uniquement à partir des clients sur l'adresse IP 192.168.33.14 et uniquement jusqu'au 31 décembre 2016.
Notre serveur virtuel écoute sur le port 80 et gère toutes les requêtes HTTP sécurisées sous le bloc d'emplacement
/files
, où la directive root
définit /var/www comme répertoire racine pour les fichiers demandés.
La directive secure_link
définit deux variables qui capturent les arguments dans l'URL de la requête : $arg_md5
est défini sur la valeur de l'argument md5 et $arg_expires
sur la valeur de l'argument expires .
La directive secure_link_md5
définit l'expression qui est hachée pour générer la valeur MD5 de la requête ; pendant le traitement de l'URL, le hachage est comparé à la valeur de $arg_md5
. L'exemple d'expression ici inclut le délai d'expiration passé dans la requête (capturé dans la variable $secure_link_expires
), l'URL ( $uri
), l'adresse IP du client ( $remote_addr
) et le mot enigma
.
serveur {
écoute 80 ;
nom_serveur secure-link-demo ;
emplacement /fichiers {
racine /var/www ;
secure_link $arg_md5,$arg_expires ;
secure_link_md5 "$secure_link_expires$uri$remote_addr enigma" ;
si ($secure_link = "") { retour 403 ; }
si ($secure_link = "0") { retour 410 ; }
}
}
Avec cette configuration, pour accéder à /var/www/files/pricelist.html , un client avec l'adresse IP 192.168.33.14 doit envoyer cette URL de requête avant le Sat Dec 31 23:59:00 UTC 2016 :
/files/pricelist.html?md5=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740
Si le hachage dans l'URL envoyée par le client (capturé dans la variable $arg_md5
) ne correspond pas au hachage calculé à partir de la directive secure_link_md5
, NGINX Plus définit la variable $secure_link
sur la chaîne vide. Le test if
échoue et NGINX Plus renvoie le403
Code d'état interdit
dans la réponse HTTP.
Si les hachages correspondent mais que le lien a expiré, NGINX Plus définit le $lien_secure
variable à 0
; encore une fois le si
le test échoue mais cette fois NGINX Plus renvoie le 410
Disparu
code d'état dans la réponse HTTP.
Voyons maintenant comment un client calcule les arguments md5 et expire à inclure dans l'URL.
La première étape consiste à déterminer l’équivalent temporel Unix de la date d’expiration, car cette valeur est incluse dans l’expression hachée sous la forme de la variable $secure_link_expires
. Pour obtenir l'heure Unix – le nombre de secondes depuis Epoch (1970-01-01 00:00:00 UTC) – nous utilisons la commande date
avec l'option -d
et le spécificateur de format +%s
.
Dans notre exemple, nous définissons l'heure d'expiration sur Sat Dec 31 23:59:00 UTC 2016 , donc la commande est :
# date -d "2016-12-31 23:59" +%s1483228740
Le client inclut cette valeur comme argument expires=1483228740 dans l’URL de la demande.
Nous exécutons maintenant la chaîne définie par la directive secure_link_md5
– $secure_link_expires$uri$remote_addr
enigma
– via trois commandes :
openssl
md5
avec l'option -binary
génère le hachage MD5 au format binaire.openssl
base64
applique l'encodage Base64 à la valeur hachée.tr
remplacent le signe plus ( +
) par le trait d'union ( -
) et la barre oblique ( /
) par le trait de soulignement ( _
), et suppriment le signe égal ( =
) de la valeur codée.Pour notre exemple, la commande complète est :
# echo -n '1483228740/files/pricelist.html192.168.33.14 enigma' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d = AUEnXC7T-Tfv9WLsWbf-mw
Le client inclut cette valeur comme argument md5=AUEnXC7T-Tfv9WLsWbf-mw dans l'URL de la demande.
Si votre serveur Web NGINX Plus diffuse du contenu dynamique à partir d'un serveur d'applications, NGINX Plus et le serveur d'applications doivent utiliser la même URL sécurisée. Vous pouvez générer le hachage pour l'argument md5 dans l'URL par programmation. La fonction Node.js suivante génère un hachage correspondant à celui défini dans l'extrait de configuration NGINX Plus ci-dessus. Il prend un délai d'expiration, une URL, une adresse IP client et un mot secret comme arguments et renvoie le hachage MD5 au format binaire codé en Base64.
var crypto = require("crypto");
function generateSecurePathHash(expires, url, client_ip, secret) {
if (!expires || !url || !client_ip || !secret) {
return undefined;
}
var input = expires + url + client_ip + " " + secret;
var binaryHash = crypto.createHash("md5").update(input).digest();
var base64Value = new Buffer(binaryHash).toString('base64');
return base64Value.replace(/=/g, '').replace(/+/g, '-').replace(///g, '_');
}
Pour calculer le hachage de notre exemple actuel, nous passons ces arguments :
generateSecurePathHash(nouvelle date('31/12/2016 23:59:00').getTime()), '/files/pricelist.html', "192.168.33.14", "enigma");
Les exemples de commandes curl
suivants montrent comment le serveur répond aux URL sécurisées.
Si un client avec l'adresse IP 192.168.33.14 inclut le hachage MD5 et le délai d'expiration corrects, la réponse est200
D'ACCORD
:
# 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
Si un client avec une adresse IP différente envoie la même URL, la réponse est403
Interdit
:
# 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 Interdit
Si la valeur de hachage de l'argument md5 est incorrecte, la réponse est403
Interdit
:
# 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 Interdit
Si l'URL a expiré (la date représentée par l'argument expires est dans le passé), la réponse est410
Disparu
:
# 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 Disparu
Voici un autre exemple d’URL sécurisée avec date d’expiration, utilisée pour protéger à la fois la liste de lecture d’un élément multimédia et les fichiers de segment.
Une différence par rapport à l'exemple précédent est que nous ajoutons ici un bloc de configuration de carte
pour supprimer l'extension de la liste de lecture (fichier .m3u8 ) et des segments HLS (fichiers .ts ) lorsque nous capturons le nom de fichier dans la variable $file_name
, qui est transmise à la directive secure_link_md5
. Cela permet de sécuriser les requêtes pour les segments .ts individuels ainsi que pour la playlist.
Une autre différence par rapport au premier exemple est que nous incluons la variable $http_user_agent
(qui capture l'en-tête User-Agent
) dans la directive secure_link_md5
, pour restreindre l'accès aux clients sur des navigateurs Web spécifiques (par exemple, pour que l'URL fonctionne sur Safari mais pas sur Chrome ou Firefox).
map $uri $file_name {
default none;
"~*/s/(?<name>.*).m3u8" $name;
"~*/s/(?<name>.*).ts" $name;
}
serveur {
listen 80;
server_name secure-link-demo;
location /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; }
}
}
Le module Secure Link de NGINX vous permet de protéger les fichiers contre tout accès non autorisé en ajoutant des données codées telles que le hachage d'une partie spécifique de l'URL. L'ajout d'un délai d'expiration limite également la durée de validité des liens, pour encore plus de sécurité.
Pour essayer NGINX Plus, démarrez votre essai gratuit de 30 jours dès aujourd'hui ou contactez-nous pour discuter de vos cas d'utilisation.
« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."