【问题标题】:NGINX - Why I am getting a 403 Forbidden for root location?NGINX - 为什么我得到一个 403 Forbidden for root 位置?
【发布时间】:2020-07-12 12:50:45
【问题描述】:

我开发了一个具有以下结构的项目:

api.my-domain.com:一个内置于 Symfony 5 中的 Restfull API。
app.my-domain.com:一个 Angular 应用程序。
www.my-domain.com:一个简单但漂亮的 HTML/CSS/JS 登录页面。

这个结构是在 Ubuntu 服务器上使用 NGINX 提供的。 apiapp 站点的配置文件运行良好。那里无事可做。

对于landing,我有一些自定义要求:

  • 我需要将包含“login”或“pm-”的请求重定向到app站点。
  • 我需要支持多语言网站,所以:
  • 当有人访问www.my-domain.com时,服务器应该返回index_es.html;但它也应该允许访问服务器上的其他静态文件(图像、字体、样式...)以使登陆正常工作。

使用以下 NGINX 站点配置站点已满足此要求:

server {
    server_name www.my-domain.com my-domain.com;
    root /var/www/my-project/;

    location = /es {
      try_files /index_es.html /index.html;
    }

    location = /en {
      try_files /index_en.html /index.html;
    }

    location = /ca {
      try_files /index_ca.html /index.html;
    }

    location = / {
      try_files /index_es.html /index.html;
    }

    location ~ ^/(login|pm-) {
      return 301 $scheme://app.my-project.com$request_uri;
    }
    
    location / {
      try_files $uri $uri/ /index_es.html;
    }

    error_log /var/log/nginx/my-project-error.log;
    access_log /var/log/nginx/my-project-access.log;



    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/my-project.com-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/my-project.com-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot




}
server {
    if ($host = www.my-project.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = my-project.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    server_name www.my-project.com my-project.com;
    listen 80;
    return 404; # managed by Certbot

}

问题是,在我第一次尝试让它工作时,我没有输入以下代码:

location = / {
  try_files /index_es.html /index.html;
}

因为我认为指定这个就足够了:

location / {
  try_files $uri $uri/ /index_es.html;
}

但是当我尝试访问www.my-domain.com 时,我从 NGINX 得到了一个 403 Forbidden 页面。所以,问题是:

  • 为什么我目前需要输入 location = / 代码才能使其正常工作?
  • 如何优化配置以删除location = / 代码?

提前谢谢你。

【问题讨论】:

  • $uri/ 术语正在寻找一个索引文件,默认为index.html。如果您添加了index index_es.html;,它将按预期工作。
  • @RichardSmith 感谢您的评论。所以...您的意思是删除 location = / 部分,然后定义以下内容: location / { try_files $uri $uri/;索引 index_es.html; };对吗?

标签: nginx redirect location


【解决方案1】:

如果您直接在server 上下文中使用简单的rewrites,您的配置会更简洁:

server {
    server_name www.my-domain.com my-domain.com;
    root /var/www/my-project/;

    rewrite ^/(es|en|ca)$ /index_$1.html;
    
    location = / {
        index index_es.html; 
    }
    # ...
}

对于静态网站,我建议完全消除try_files。 仅对动态网站和may be evil 有意义。

为什么我目前需要放置 location = / 一段代码才能使其正常工作?

因为在您发布的配置中,如果您删除它,那么对于 URI /,NGINX 将选择 location / { 块,这将尝试(由于 $uri/)定义为 index 的文件,默认为 @ 987654331@。所以它会尝试检查它是否存在,成功,并使用它来服务请求。

一旦你定义了location = /,NGINX 就会使用它来提供服务,因为精确匹配类型 (=) 在 NGINX 中总是优先于其他位置类型。

如何优化配置以删除 location = / 一段代码?

您实际上不需要删除location = /(请参阅上面的调整配置)。如果有的话,最好使用精确匹配类型,因为它将导致最快的匹配。 (除非您可以通过删除文件存在检查来处理问题,请参见下文)。

有人可能会争论:

location = /es {
    try_files /index_es.html /index.html;
}

location = /en {
    try_files /index_en.html /index.html;
}

location = /ca {
    try_files /index_ca.html /index.html;
}

... 会比建议的rewrite 更快。它不会很快,因为try_files 会让事情变慢。为什么,因为try_files首先检查一个文件是否存在,然后决定是继续下一个文件还是服务。

rewrite 正在无条件地决定使用哪个文件来提供服务。 (当然,除非你有其他指令影响它)。

您还可以尝试进一步优化,方法是不使用index 并使用rewrite 作为主页。 (注意index 也承担文件存在检查的性能损失,与try_files 相同)。

因此:

server {
    server_name www.my-domain.com my-domain.com;
    root /var/www/my-project/;

    rewrite ^/(es|en|ca)$ /index_$1.html;
    rewrite ^/$ /index_es.html; 
    # ...
}

【讨论】:

  • 对不起,能不能详细解释一下,为什么$uri/会尝试加载默认的索引文件?
  • 每当 NGINX 尝试处理一个目录以提供服务(try_files 是它首先检查目录是否存在的地方),它需要使用 a file 来提供响应。响应中没有“提供目录”之类的东西(除非我们查看 autoindex 模块,但这是另一种情况)。 NGINX 需要一个文件来返回响应。在为目录请求 ($uri/) 传递响应时正在尝试哪些文件由 index 指令控制,该指令具有默认值 index.html
猜你喜欢
  • 2016-11-14
  • 1970-01-01
  • 2018-05-06
  • 2020-03-26
  • 2018-04-15
  • 2020-04-12
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
相关资源
最近更新 更多