Nginx & UserDir & PHP

4661
ckujau

I have a fairly simple nginx/1.4.7 installation (from Debian/unstable) and I'm trying to get PHP scripts to run inside a 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; } } 

Accessing http://sid0.local/~dummy works, it lists the content of /home/dummy/www/ and I can access files there. Underneath ~dummy/bar is a file called index.php - yet, accessing http://sid0.local/~dummy/bar/ brings the dreaded "File not found." error (not a 404). The error.log has:

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" 

Now, many people seem to have this problem and some of them are even posting solutions, like making sure that SCRIPT_FILENAME is set to request_filename - but this is already the case (it's set in fastcgi_params).

However, running strace(1) against the nginx process gives (edited for readability):

4045 connect(16,, 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 

As you can see, SCRIPT_FILENAME is NOT request_filename but instead document_root+fastcgi_script_name - hence the 404, of course.

So, I guess my question is: why is my SCRIPT_FILENAME mangled (I even set it to fastcgi_script_name, no luck) and how do I get PHP scripts inside a UserDir running?

3
nginx `местоположения являются эксклюзивными. Если ваш запрос попадает в местоположение для файлов PHP, nginx не ищет другие подходящие местоположения, поэтому nginx ничего не знает о директиве `alias` в расположении _userDir_. Alexey Ten 10 лет назад 0
Благодарю. Но когда я поместил часть PHP внутри части UserDir, это ничего не изменило, SCRIPT_FILENAME все еще был искажен. ckujau 10 лет назад 0

2 ответа на вопрос

1
Alexey Ten

Я бы изменил корневой каталог вместо использования псевдонима в местоположении. Это может выглядеть так:

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; } 

Еще одна версия без переписывания:

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; } } 

По какой-то причине aliasработают именованные захваты, а с числовыми ссылками - нет. Я предполагаю, что числовые ссылки очищаются как-то во вложенном месте.

Вау, это действительно волшебство. Я бы надеялся, что это можно сделать без переписывания трюков - это только userdir и правила перезаписи (и [if] (http://wiki.nginx.org/IfIsEvil)) всегда кажутся такими хрупкими. Кроме того, я больше не могу устанавливать `autoindex` внутри userdir. Но в остальном это работает, спасибо! ckujau 10 лет назад 0
@ckujau смотрите обновление Alexey Ten 10 лет назад 0
Спасибо за обновление. Извините, мне понадобилось время, чтобы найти время, чтобы проверить это. К сожалению, здесь это не работает, я получаю 404 ошибки при попытке доступа к ~ dummy / bar / index.php. Я отнесу это в список рассылки nginx. Спасибо за ваш вклад, хотя! ckujau 10 лет назад 0
0
sudoman

Based on Alexy Ten's answer, I placed the following configuration files in /etc/nginx/default.d/ as they are included by nginx.conf in my default install:

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

Notice the added ? symbol after the / symbol to match hostname/~user without a trailing slash. That fixes one 404 error.

If you are getting 403 errors due to SELinux, you will need to update your access rules:

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