Nginx : comment protéger un dossier ou une page par un mot de passe

Introduction

A la création d'un site ou d'un serveur web, on souhaite souvent protéger une partie du site, qui ne doit être accessible qu'aux administrateurs uniquement.
Dans cette partie, on protégera notamment les pages d'administrations, d'accès à la base de données (PHPmyAdmin...) et tous les scripts qui ne doivent être accessibles que par les personnes autorisées.

Pour cela, Nginx permet de protéger un dossier ou une url grâce à identifiant et un mot de passe.

 

Génération du fichier de mot de passe hashé

Pour ne pas afficher en clair notre mot de passe dans un fichier de configuration, nous allons commencer par générer un mot de passe au format APR-1.
APR-1.est une fonction de hashage utilisée par les serveurs Apache pour chiffrer les mots de passe .htaccess. Il se sert de MD5 comme base.

Pour générer ce mot de passe, nous allons utiliser openssl avec la commande suivante qui vous demandera de taper un mot de passe, puis de le confirmer.

openssl passwd -apr1
Password:
Verifying - Password:
$apr1$EndwnhD8$LPy5If9aTsK7ykmlrfh/61

La chaine $apr1$EndwnhD8$LPy5If9aTsK7ykmlrfh/61 est le mot de passe hashé pour cette exemple, vous aurez une chaine différente avec votre mot de passe à vous.
Copier cette chaine pour pouvoir la coller dans le fichier de mot de passe qui nous allons créer ci-dessous.

 

Création du fichier de protection par mot de passe

Imaginons que nous voulons protéger le répertoire /admin qui est dans le dossier du vHost par défaut de Nginx.

Nous allons donc créer le ficher .htpasswd dans ce dossier : il contiendra le nom d'utilisateur et le mot de passe hashé.

sudo nano /usr/share/nginx/html/admin/.htpasswd

Dans ce nouveau fichier, commencer par coller le mot de passe hashé généré précédemment.
Puis ajouter le nom de l'utilisateur devant, en utilisant : en séparateur entre les 2 chaines.

Par exemple, utilisateur admin dans mon cas.

admin:$apr1$EndwnhD8$LPy5If9aTsK7ykmlrfh/61

 

Modification de la configuration du vHost

Il faut maintenant modifier la configuration de notre vHost pour indiquer le dossier à protègrer et l'emplacement du mot de passe.

Ouvrez le fichier de configuration de vHost Nginx par défaut.

sudo nano /etc/nginx/conf.d/default.conf

Puis ajouter le dossier /admin qui contient les commandes auth_basic et auth_basic_user_file utilisées pour protéger cette adresse.

server {
    listen 80 localhost;
    root   /usr/share/nginx/html;
    index  index.html index.htm index.php;
    .....
    location /admin {
        try_files $uri $uri/ =404;
        auth_basic "Restricted Content";
        auth_basic_user_file /usr/share/nginx/html/admin/.htpasswd;
    }
    .....

}

Maintenant, essayez d'ouvrir http://<adresse de votre serveur/admin et vous obtiendrez la demande d'authentification ci-dessous.
L'adresse ne sera accessible que si vous saisissez l'identifiant et le mot de passe spécifiés précédemment dans le fichier .htpasswd

 

Tags: 

Commentaires

bonjour, merci beaucoup pour vos tutorial par contre j'ai une question le dossier pour le proteger admin c'est ok mais dans le dossier j'ai le fichier de admirer pour mysql il demande pas le mot de passe normal? merci 

Bonjour, je suis ravi que mes tutos soient utiles ;)

Le mot de passe est demandé la première fois que vous accédez au dossier ou à un fichier contenu dans le dossier (adminer.php par exemple).
L'authentification reste ensuite active un certain temps (je n'ai pas trouvé de doc qui expliquerait la durée du timeout).

Donc si vous avez accédez au dossier et tapez un mot de passe conforme, c'est normal qu'ensuite quand vous accédez à adminer.php le mot de passe ne soit pas demandé (vous êtes déjà authentifié).
Dans plusieurs heures, essayez d'accéder directement à votre script adminer.php sans vous authentifiez au préalable sur le dossier. Le mot de passe devrait être demandé.

Portrait de Roverland

Je confirme qu'il me demande aucun mot de passe quand je vais sur : 192.168.0.1/admin/adminer.php par contre il me demande bien le mot de passe sur : 192.168.0.1/admin

pas trop comprit j'ai test avec d'autre navigateur toujours la meme chose si vous avez une solution je suis preneur merci ;)

Portrait de Roverland

j'ai reussi avec le code suivant 

location ^~ /admin {
        try_files $uri $uri/ =404;
        fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
        auth_basic "Restricted Content";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }

le rajout du  ^~  marche je crois bien

Le problème vient du fait que vous avez (je présume), 2 locations dans le fichier de configuration de votre vHost :

  • location /admin pour définir la protection du dossier
  • location  ~ \.php$ pour définir comment traiter les fichiers PHP

Or quand vous accédez à 192.168.0.1/admin/adminer.php, seule la location ~ \.php$ est utilisée surprise 

Je vous invite à visiter cette page http://wiki.whyaskwhy.org/Nginx/Location qui explique l'ordre de traitement des balises locations.

Et du coup, pour votre config, l'exemple ci-dessous me parait pas mal.

Les fichiers PHP sont traités hors et dans la zone /admin. Et le mot de passe est bien demandé quand vous accédez à un fichier PHP dans la zone /admin

server {
    listen 80;
    server_name testadmin.com;

    root   /home/dev/www/test;
    index  index.html index.htm index.php;

    location ^~ /admin {
        try_files $uri $uri/ =404;
        auth_basic "Restricted Content";
        auth_basic_user_file  /usr/share/nginx/html/admin/.htpasswd;

        # pass the PHP scripts to FastCGI server listening on /run/php/php7.0-fpm.sock
        location ~ \.php$ {
            try_files      $uri =404;
            fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }
    }

    # pass the PHP scripts to FastCGI server listening on /run/php/php7.0-fpm.sock
    location ~ \.php$ {
       try_files      $uri =404;
       fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
       fastcgi_index  index.php;
       include        fastcgi_params;
       fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   }
}

 

Portrait de Roverland

Oui marche impecable, par contre j'ai une autre question j'ai tester de metre le .htpasswd sur mon ip donc http://xx.xx.xx.xxip et https://xx.xx.xx.xxip et sur mon adresse dsn je ve pas de password donc https://mydomaine.fr j'ai vu que vous avez proteger votre ip avec le htpasswd si vous avez une solution pour moi merci beaucoup en tout cas je suis vos tuto sa m'aide vraiement beaucoup ;)

J'ai simplement créé 2 vhost : un vHost pour mon nom de domaine (sans la config auth_basic pour ne pas avoir de mot de passe) et un vHost pour mon IP (avec mot de passe).

Ca se passe sur la ligne server_name, un fichier de config par vHost

server {
    listen 80;
    server_name testadmin.com;
    ....
}
server {
    listen 80;
    server_name 10.20.30.40;
    ....
}

 

Portrait de Roverland

Impecable du coup il demande un mot de passe sur mon adresse ip et c'est plus securisé du coup? merci encore

Bonsoir,

J'héberge mon site web sur une distribution yunohost à base de debian 10. Je souhaitai mettre en place la protection d'un dossier comme proposé dans votre tutoriel et comme esquissé dans ce forum. Malheureusement je bloque sur la directive location.

Voilà mon fichier de configuration; my_webapp__3.conf:

rewrite ^/site3$ /site3/ permanent;
location /site3/ {

# Path to source
alias /var/www/my_webapp__3/www/;

# Force usage of https
if ($scheme = http) {
rewrite ^ https://$server_name$request_uri? permanent;
}

# Default indexes and catch-all
index index.html index.php;
try_files $uri $uri/ /site3/index.php?$args;

# Prevent useless logs
location = /site3/favicon.ico {
log_not_found off;
access_log off;
}
location = /site3/robots.txt {
allow all;
log_not_found off;
access_log off;
}

# Deny access to hidden files and directories
location ~ ^/site3/(.+/|)\.(?!well-known\/) {
deny all;
}

# Execute and serve PHP files
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_pass unix:/var/run/php/php7.3-fpm-my_webapp__3.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param REMOTE_USER $remote_user;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $request_filename;
}

# Include SSOWAT user panel.
include conf.d/yunohost_panel.conf.inc;

location /var/www/my_webapp__3/www/_ecam {
auth_basic “Zone Ecam”;
auth_basic_user_file /var/www/my_webapp__3/www/_ecam/.htpasswd;
}
}

Et mon fichier d'erreur partiel me renvoie systématiquement une erreur 46:

Feb 09 15:50:48 nginx[10529]: nginx: [emerg] location "/_ecam" is outside location "/site3/" in /etc/nginx/conf.d/wendling.xyz.d/my_webapp__3.conf:46

Auriez-vous une piste pour me guider vers une solution? En vous remerciant.

Ajouter un commentaire

You must have Javascript enabled to use this form.