3 votes

Nginx & UserDir & PHP

J'ai une installation nginx/1.4.7 assez simple (de Debian/unstable) et j'essaie de faire en sorte que les scripts de PHP s'exécutent à l'intérieur d'un UserDir .

server {
        listen          8083;                                
        server\_name     sid0.local;
        index           index.php index.html;
        root            /data/www/sid0.local;

        location / {
                try\_files $uri $uri/ =404;
        }

        # PHP-FPM
        location ~ \\.php$ {
                include         fastcgi\_params;
                fastcgi\_pass    unix:/var/run/php5-fpm.sock;
                fastcgi\_index   index.php;
        }

        # UserDir
        location ~ ^/~(.+?)(/.\*)?$ {
                alias           /home/$1/www$2;
                autoindex       on;
        }
}

Accès à http://sid0.local/~dummy fonctionne, il énumère le contenu de /home/dummy/www/ et je peux y accéder aux fichiers. En dessous de ~dummy/bar est un fichier appelé index.php - pourtant, l'accès http://sid0.local/~dummy/bar/ entraîne l'erreur redoutée "Fichier non trouvé" (et non pas une erreur 404). Le site error.log a :

2014/04/30 23:07:44 \[error\] 4237#0: \*9 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168.0.103, server: sid0.local, request: "GET /~dummy/bar/ HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "sid0.local:8083"

Maintenant, de nombreuses personnes semblent avoir ce problème et certains d'entre eux postent même solutions comme s'assurer que SCRIPT_FILENAME est réglé sur request_filename - mais c'est déjà le cas (c'est défini dans fastcgi_params).

Cependant, l'exécution strace(1) contre le processus nginx donne (édité pour la lisibilité) :

4045  connect(16, {sa\_family=AF\_FILE, path="/var/run/php5-fpm.sock"}, 110) = 0
4045  writev(16, \[{"\\1\\1\\0\\1\\0\\10\\0\\0\\0\\1\\0\\0\\0\\0\\0\\0\\1\\4\\0\\1\\3T\\4\\0\\f\\0
      QUERY\_STRING\\16\\3
      REQUEST\_METHODGET\\f\\0
      CONTENT\_TYPE\\16\\0
      CONTENT\_LENGTH\\0170
      SCRIPT\_FILENAME/data/www/sid0.local/~dummy/bar/index.php\\v\\25
      SCRIPT\_NAME/~dummy/bar/index.php\\v\\f
      REQUEST\_URI/~dummy/bar/\\f\\25
      DOCUMENT\_URI/~dummy/bar/index.php\\r\\33
      DOCUMENT\_ROOT/data/www/sid0.local

Comme vous pouvez le voir, SCRIPT_FILENAME n'est PAS request_filename mais à la place document_root+fastcgi_script_name - d'où la 404, bien sûr.

Donc, je suppose que ma question est : pourquoi mon SCRIPT_FILENAME mangled (j'ai même réglé sur fastcgi_script_name pas de chance) et comment puis-je obtenir des scripts PHP à l'intérieur d'un fichier UserDir en train de courir ?

2voto

Michel Points 5568

Je changerais le répertoire racine plutôt que d'utiliser un alias dans l'emplacement. Cela pourrait ressembler à ceci :

listen          8083;                                
server_name     sid0.local;
index           index.php index.html;

# Here is magic
set $root_dir /data/www/sid0.local;
rewrite ^(/~[^/]+)$ $1/ redirect;
rewrite ^/~(?<user>[^/]+)(.+) $2;
if ($user) {
    set $root_dir /home/$user/www;
}
root $root_dir;

# PHP-FPM
location ~ \.php$ {
    try_files $uri =404;
    include         fastcgi_params;
    fastcgi_pass    unix:/var/run/php5-fpm.sock;
    fastcgi_index   index.php;
}

Une autre version sans réécriture :

listen          8083;                                
server_name     sid0.local;
index           index.php index.html;

root /data/www/sid0.local;

location ~ ^/~(?<user>[\w-]+)(?<path>/.*)$ {
    alias /home/lynn/tmp/site/$user/www$path;
    autoindex on;

    # PHP-FPM
    location ~ \.php$ {
        try_files $uri =404;
        include         fastcgi_params;
        fastcgi_pass    unix:/var/run/php5-fpm.sock;
        fastcgi_index   index.php;
    }
}

Pour une raison quelconque alias avec des captures nommées fonctionne, alors qu'avec des références numériques, il échoue. A mon avis, les références numériques sont effacées d'une manière ou d'une autre dans les emplacements imbriqués.

0voto

andrew-e Points 183

Basé sur le rapport d'Alexy Ten réponse J'ai placé les fichiers de configuration suivants dans /etc/nginx/default.d/ car ils sont inclus par nginx.conf dans mon installation par défaut :

$ cat 00-index.conf 
index index.html;

$ cat 50-userdirs.conf
location ~ ^/~(?<user>[\w-]+)(?<path>/?.*)$ {
    alias /home/$user/www$path;
    autoindex on;
}

Remarquez l'ajout ? après le symbole / symbole pour correspondre hostname/~user sans barre oblique de fin. Cela corrige une erreur 404.

Si vous obtenez des erreurs 403 à cause de SELinux, vous devez mettre à jour vos règles d'accès :

# semanage fcontext -a -t httpd_user_content_t '/home/[^/]*/www/.*'
# for userdir in /home/* ; do restorecon -Rvi "$userdir/www" ; done

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