1 votes

Comment vérifier l'existence de fichiers illisibles avant de les transmettre à un backend fastcgi?

Je possède plusieurs sites PHP que je veux séparer en termes de permissions. J'ai donc créé un nouvel utilisateur et configuré un pool PHP pour ces utilisateurs. Considérez la configuration ci-dessous :

  • PHP-FPM fonctionne en tant qu'utilisateur php
  • nginx fonctionne en tant qu'utilisateur nginx
  • Le webroot est /srv/http, accessible à la fois par php et nginx.
  • Le fichier /srv/http/index.php est lisible par php, mais pas lisible par nginx.
  • Le fichier fastcgi_stuff contient des paramètres fastcgi de base pour définir les en-têtes, définir le backend, etc. Supposons que le webroot pour les fichiers statiques et les fichiers PHP soit le même.

Le fichier nginx.conf ci-dessous contient les éléments essentiels de cette configuration, il est placé dans une directive server :

server_name example.com;
root /srv/http;

index index.php;
location ~ \.php$ {
    include fastcgi_stuff;
}

Si je demande http://example.com/ avec la configuration ci-dessus, la page se charge comme prévu. Pour http://example.com/does.not.exist, j'obtiens une erreur 404 comme prévu.

Pour empêcher de transmettre des fichiers inexistants à PHP-FPM, j'ai essayé d'ajouter l'une des lignes ci-dessous :

    try_files $uri =404;
    if ( !-e $request_filename ){ return 404; }

Les deux ne fonctionnent pas comme annoncé, ils essaient d'ouvrir les fichiers au lieu de vérifier leur existence en effectuant un appel stat(). J'ai confirmé cela en vérifiant le code source et en exécutant strace sur un processus de travail.

C'est un cas basique sur lequel j'avais des difficultés, un autre cas est lorsque je cache l'extension et que je mets donc un try_files $uri.php =404 dans le bloc de localisation. Des suggestions ?

1voto

Lekensteyn Points 5981

Nginx tente d'ouvrir le fichier car j'avais disable_symlinks on;. Le code source pertinent se trouve dans core/ngx_open_file_cache.c, fonction ngx_file_info_wrapper (appelée par ngx_open_cached_file, depuis ngx_http_script_file_code).

Si disable_symlinks est défini sur off, nginx effectue un simple appel de stat (ngx_file_info est typedef'd to stat sur *nix). Lorsque disable_symlinks est défini sur autre chose (par exemple on), il tente d'ouvrir le fichier de manière sécurisée contre les attaques de lien symbolique, puis effectue un appel fstat() sur le descripteur de fichier ouvert. Comme nginx ne peut pas ouvrir le fichier en lecture car il n'a pas les autorisations pour cela, cela échoue.

La solution à court terme est de réactiver les liens symboliques en utilisant disable_symlinks off, une solution à long terme consiste à modifier les fonctions pour se déplacer vers le répertoire contenant et ensuite faire un fstatat() sur le fichier de ce répertoire. N'oubliez pas de désactiver les liens symboliques pour les répertoires ne contenant pas de scripts PHP, mais qui sont inscriptibles par l'utilisateur PHP.


Comme mentionné sur http://forum.nginx.org/read.php?2,225152,234724#msg-234724, ce comportement est documenté:

Sur les systèmes qui ne prennent pas en charge l'ouverture des répertoires en mode lecture seule, l'utilisation de ces paramètres nécessite que les processus worker aient des autorisations de lecture pour tous les répertoires vérifiés.

J'ai téléversé un correctif qui vous permet de restreindre les liens symboliques et de rendre try_files ou if fonctionnels. Voir également le fil de discussion lié ci-dessus.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X