5. Restrictions d’accès
Il est parfois nécessaire de restreindre l’accès à une ressource afin de s’assurer que seules les personnes autorisées consultent la ressource.
Une méthode simple consiste à prendre en compte l’adresse IP du client afin de lui autoriser ou refuser l’accès à la ressource.
5.1. Apache
Certaines directives et conteneurs permettent de définir des restrictions d’accès à tous les fichiers d’un répertoire, via les conteneurs <Directory>
ou via le fichier .htaccess
(ce type de restriction ne peut pas être associé directement à un fichier donné). Ces directives sont fournies par des modules mod_auth*_*
, dont un sous-ensemble est généralement activé par défaut par les distributions.
Dans Apache 2.2 (que vous rencontrerez peut-être un jour ou l’autre), les restrictions sont mises en place au moyen des directives Order
, Allow
et Deny
. Ces directives sont obsolètes avec Apache 2.4, elles sont donc à éviter (bien qu’on puisse les utiliser grâce au module mod_access_compat
).
La directive permettant les restrictions est, depuis Apache 2.4, la directive Require
. Les modules mod_authz_core
et mod_authz_host
mettent à disposition des fournisseurs d’autorisation génériques utilisables avec la directive Require.
On les utilise ainsi :
Require *option* *fournisseur d'autorisation* *arguments*
Parmi les fournisseurs d’autorisation, citons :
all
, qui prend en argumentgranted
oudenied
pour autoriser ou bloquer toutes les requêtes ;ip
, qui prend une ou plusieurs adresse IP ou réseaux ;host
, qui prend en argument tout ou partie d’un nom d’hôte qui sera comparé au nom d’hôte du client via une double interrogation DNS (à éviter) ;local
, qui ne prend pas d’argument, et qui autorisera l’accès si le client est la machine locale (127.0.0.0/8
,::1
ou si l’IP du client et du serveur sont les mêmes) ;method
, qui prend en argument une ou plusieurs méthodes HTTP.
Il est à noter que pour les fournisseurs d’autorisation ip
et host
peuvent prendre en argument des adresses IP partielles (équivalentes à des adresses réseaux) ou des noms d’hôte partiels (c-à-d que le nom d’hôte du client finit comme le paramètre de la directive) :
Require ip 192.168 Require host .net
L’adresse partielle 192.168
correspond au réseau 192.168.0.0/16
, qu’il est possible de noter 192.168.0.0/255.255.0.0
(ip
accepte ces trois syntaxes).
Pour inverser une requête, on utilisera l’option not
1 :
Require not local
Notez que not
étant la négation d’une valeur, il ne peut pas être utilisé pour autoriser ou interdire une requête, car non vrai ne sera pas interpreté par Apache comme faux. Ainsi, pour interdire la visite d’une page à l’aide d’une négation, le bloc doit contenir un élément évalué à vrai ou faux.
Pour grouper différentes directives d’autorisation, on pourra utiliser les conteneurs <RequireAll>
(toutes les directives doivent correspondre pour autoriser l’accès), <RequireAny>
(au moins une directive doit correspondre) ou <RequireNone>
(aucune directive ne doit correspondre).
Si les directives ne sont pas dans un conteneur <Require*>
, on considérera qu’elles sont dans un conteneur <RequireAny>
.
Vous trouverez un peu de documentation sur https://httpd.apache.org/docs/2.4/fr/howto/access.html.
Exemples :
# La ressource n’est accessible qu’au réseau 192.168.1.0/24 <Directory /var/www/lan> Require ip 192.168.1.0/24 </Directory> # La ressource est interdite au réseau 10.10.0.0/16 <Directory /var/www/other_lan> <RequireAll> Require all granted Require not ip 10.10.0.0/16 </RequireAll> </Directory>
5.2. Nginx
C’est le module ngx_http_access_module
2 qui fournit les directives allow
et deny
, auquelles on donnera un paramètre (une adresse IP, un réseau au format CIDR ou all
).
deny 192.0.2.1; allow 192.0.2.0/24; allow 198.51.100.0/24; deny all;
Les directives sont évaluées de haut en bas : la première qui correspond s’applique. Attention donc à ne jamais placer un allow all;
ou un deny all;
en haut de la liste, les autres directives d’accès ne seraient jamais évaluées !
6. Contrôles d’accès
3.4. Différences et comparaison des contextes et directives Apache et Nginx
Nous avons déjà étudié précédemment quelles étaient les possibilités de restrictions en fonction de l’origine d’un client (directives Require
pour Apache et allow
et deny
pour Nginx). D’autres directives permettent de contrôler l’accès à une page ou à un ensemble de pages.
Le protocole d’authentification HTTP prévoit 2 méthodes d’authentification différentes : le mode basic (où les informations correspondantes transitent en clair) et le mode digest (où les informations correspondantes sont chiffrées).
NB : Nginx ne supporte pas le mode digest, uniquement le basic.
Dans l’authentification basique, le couple identifiant / mot de passe est envoyé encodé en base64 (et donc décodable) dans l’en-tête Authorization
. Ainsi, pour l’utilisatrice dr
avec le mot de passe who
, on enverra :
Authorization: Basic ZHI6d2hv
(ZHI6d2hv
correspond à dr:who
encodé en base64 : echo -n dr:who | base64
)
Les informations envoyées dans l’authentification digest dépendent de paramètres envoyés par le serveur et ne contiennent pas de données décodables. Exemple :
Authorization Digest username="luc", realm="foo", nonce="ZklQHRbRBQA=caebe745c92bc7932ad1b071631990d13cda189d", uri="/digest/", algorithm=MD5, response="98cee1c3b1eb9733695538b0d6e464d9", qop=auth, nc=00000006, cnonce="848b920ed0422c15"
Si l’authentification digest semble plus robuste, elle ne suffit pas pour autant améliorer la sécurité de manière significative par rapport à l’authentification basique. En outre, le stockage du mot de passe sur le serveur est encore moins sûr dans le cas d’une authentification à base de condensé que dans le cas d’une authentification basique. C’est pourquoi l’utilisation de l’authentification basique associée à un chiffrement de la connexion via SSL/TLS constitue une bien meilleure alternative.
6.2. L’authentification basique
Cette méthode ne chiffrant pas les informations d’authentification, celle-ci ne doit être mise en place en production que sur un serveur sécurisé via le protocole HTTPS (sauf pour des tests, bien sûr).
Pour ce premier mode, il faut tout d’abord créer un fichier texte contenant les logins et les mots de passe. Le logiciel htpasswd
(disponible sur Debian via le paquet apache2-utils
) peut être utilisé pour cela.
Il accepte en particulier les options suivantes :
-c
: création d’un nouveau fichier ;-b
: considère le mot de passe de la ligne de commande au lieu de le demander interactivement (utile lorsque l’on veut automatiser la création des comptes).
Pour créer le fichier :
htpasswd -c fichier nom_de_l_utilisatrice
Pour modifier le fichier :
htpasswd fichier nom_de_l_utilisatrice
Pour ajouter une utilisatrice au fichier :
htpasswd fichier nom_de_l_autre_utilisatrice
Une fois le fichier des mots de passe créé, il est alors nécessaire de configurer le serveur Web pour l’utiliser.
6.2.1. Apache
L’utilisation du fichier de mots de passe se fait dans les contextes répertoire ou .htaccess à l’aide de plusieurs directives.
<Location /private> AuthName "closed site" AuthType basic AuthBasicProvider file AuthUserFile /usr/local/apache2/auth/userfile Require user user1 user2 … </Location>
Dans l’exemple ci-dessus, l’authentification en elle-même est assurée par les 4 premières lignes, commençant toutes par Authxxx
. La dernière ligne (Require
) est utilisée une fois l’authentification effectuée. C’est une directive d’autorisation, détaillant les utilisatrices autorisés1. Nous aurions pu choisir d’autoriser toutes les utilisatrices du fichier plutôt que quelques-unes avec Require valid-user
.
Les directives d’authentification (Authxxx
) sont fournies par différents modules Apache (via des fichiers, une base de données, un annuaire LDAP…). Regardez les modules dont le nom commence par mod_auth
sur https://httpd.apache.org/docs/2.4/mod/.
Notez bien que l’authentification basique ne se rapporte pas à la méthode d’authentification sous-jacente (fichier, base de données, annuaire LDAP…) mais à la manière dont se fait la recherche
AuthName
sert généralement à donner une indication à la personne voulant s’authentifier… ou pas. Mettez ce que vous voulez.AuthType
sert à indiquer le module d’authentification utilisé :basic
dans notre cas.AuthBasicProvider
est une directive propre au modulemod_auth_basic
(que nous avons choisi viaAuthType basic
) et indique la source de données à utiliser pour l’authentification : fichier, base de données, annuaire LDAP, etc.AuthUserFile
est une directive propre au modulemod_authn_file
, que nous avons désigné comme fournisseur de la source de données pour l’authentification avecAuthBasicProvider file
. Il s’agit du chemin du fichier contenant les identifiants des utilisatrices.
6.2.2. Nginx
Le support de l’authentification est plus sommaire dans Nginx. Ainsi, il n’est pas possible de spécifier un sous-ensemble des utilisatrices autorisées :
location / { auth_basic "closed site"; auth_basic_user_file conf/htpasswd; }
auth_basic
peut prendre une chaîne de caractères en argument ouoff
(pour désactiver l’authentification).auth_basic_user_file
prendra en argument le chemin du fichier des utilisatrices et de leurs mots de passe. Cet argument peut inclure des variables (comme par exemple/etc/nginx/auth/$host
).
Le module fournissant l’authentification est ngx_http_auth_basic_module
2.
Notez que contrairement à Apache, on ne peut pas autoriser que quelques utilisatrices : toutes les utilisatrices présentes dans le fichier sont autorisées.
6.3. L’authentification digest
Si le principe de fonctionnement de l’authentification digest est différent de la méthode basic, son principe de mise en œuvre est relativement similaire. Vous trouverez plus d’informations sur https://httpd.apache.org/docs/current/mod/mod_auth_digest.html.
L’utilisation de ce mode d’authentification étant désuet depuis la généralisation du web sécurisé, nous ne nous étendrons pas plus sur l’authentification digest.