在 nginx 中使用别名作为相对 url 时的禁止位置

Posted

技术标签:

【中文标题】在 nginx 中使用别名作为相对 url 时的禁止位置【英文标题】:Forbidden location when using alias in nginx for relative urls 【发布时间】:2016-05-17 11:42:59 【问题描述】:

我正在尝试在相对 url 上使用 nginx 设置 roundcube / phpldapadmin / ...,例如:

example.com/roundcube
example.com/phpldapadmin

源位于以下文件夹中:

/var/www/roundcube
/usr/share/phpldapadmin

Apache 2.4 一切正常,但我是 Nginx 新手。对于roundcube,我有以下location

location /roundcube/ 
    root /var/www;
    index index.php;

    location ~ \.php$ 
        try_files $uri =404;
        include /etc/nginx/fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    

效果很好,但phpldapadmin 的以下内容不起作用:

location /phpldapadmin/ 
    alias  /usr/share/phpldapadmin/htdocs;
    index  index.php index.html index.htm;

    location ~ \.php$ 
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    

我收到了403 forbidden,其中包含以下日志:

2016/02/07 21:43:33 [错误] 23047#0: *1 "/usr/share/phpldapadmin/htdocs" 的目录索引被禁止,客户端:xxx.xxx.xxx.xxx,服务器: ,请求:“GET /phpldapadmin/ HTTP/1.1”,主机:“

我检查了权限:

$ namei -om /usr/share/phpldapadmin/htdocs
f: /usr/share/phpldapadmin/htdocs
 drwxr-xr-x root root     /
 drwxr-xr-x root root     usr
 drwxr-xr-x root root     share
 drwxr-xr-x root root     phpldapadmin
 drwxr-xr-x root www-data htdocs
$ ls -l /usr/share/phpldapadmin/htdocs/index.php
-rw-r--r-- 1 root root 20036 Oct 28 17:32 /usr/share/phpldapadmin/htdocs/index.php

我尝试将所有者更改为:www-data,但没有成功。当我为圆形立方体尝试以下方法时,它不起作用:

location /roundcube/ 
    alias /var/www/roundcube;
    ...

我认为这可能是尾随 / 或类似的问题,但我对 nginx 真的很陌生,所以我找不到它...

基本上,我有反问题:https://***.com/questions/31820362/nginx-403-directory-is-forbidden-when-using-root-location

【问题讨论】:

【参考方案1】:

locationalias 都应该有一个尾随 /,或者都不应该有一个尾随 /。但在您的情况下,您应该对两个位置块使用 root 而不是 alias

location /roundcube 
    root /var/www;
    index index.php;

    location ~ \.php$ 
        try_files $uri =404;

        fastcgi_pass unix:/var/run/php5-fpm.sock;

        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    


location /phpmyadmin 
    root  /usr/share;
    index  index.php index.html index.htm;

    location ~ \.php$ 
        try_files $uri =404;

        fastcgi_pass unix:/var/run/php5-fpm.sock;

        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    

fastcgi_index 不会在仅匹配.php 的位置执行任何操作(请参阅this document)。

两个块都需要SCRIPT_FILENAME 参数(如果它已经在/etc/nginx/fastcgi_params 中,则不需要)。

【讨论】:

感谢您的回复,实际上我已经尝试了 locationroot 的所有可能的斜杠组合,但未能成功。使用root 效果很好,问题是(我忘了把它放在问题中......)我有phpldapadmin,它的根在phpldapadmin/htdocs,所以我不能使用root。在阅读了 try_filesalias 不能很好地协同工作之后,我设法通过删除 try_files 指令使其工作。 我还必须将 fastcgi_param 更改为 $request_filename 才能使 conf 正常工作,它可以在 location 中使用斜杠,在 root 中没有斜杠(但不适用于alias),不知道是否正常... root 不关心尾部斜杠,因为它不会尝试重写 URI。但是使用 $request_filenamealias 是个好主意 - 我会记住那个。 我搞定了,但由于你似乎比我更能胜任 nginx,如果你能解释为什么 $request_filename 使整个事情有效,我会很高兴...感谢您对斜杠的解释! 许多示例显示 SCRIPT_FILENAME 设置为 $document_root$fastcgi_script_name,因为它适用于 fastcgi_split_path_info 指令。除非修改,否则$fastcgi_script_name$uri 的值相同。 root 指令导致$request_filename 设置为$document_root$uri,而alias 指令在计算$request_filename 之前从$uri 中删除位置前缀。我认为$request_filename 是一个强大的解决方案,alias 有一些不寻常的副作用,不一定都是错误。【参考方案2】:

或者你可以尝试写在nginx.conf的顶部>>用户username

由于我使用的是我编写的 AWS Linux EC2 实例

user ec2-user;

而不是

user nginx;

这通过提供所有必需的权限来解决问题

【讨论】:

以上是关于在 nginx 中使用别名作为相对 url 时的禁止位置的主要内容,如果未能解决你的问题,请参考以下文章

laravel 不能在 nginx 中作为别名工作

nginx:如何创建别名 url 路由?

使用别名时的 Apache VirtualHost 混淆

nginx 从根服务静态文件并从别名上传文件

如何为 DJANGO 中动态创建的 URL 设置 URL 别名?

如何在 apache 配置中使用通配符别名作为文件名?