繁体   English   中英

NGINX - 为什么我收到 403 Forbidden for root 位置?

[英]NGINX - Why I am getting a 403 Forbidden for root location?

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

api.my-domain.com :内置于 Z878D66F98B73E26B50Z9AD532 中的 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 但它也应该允许访问服务器上的其他 static 文件(图像,fonts,styles ...)以使着陆正常工作。

使用以下 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 禁止页面。 所以,问题是:

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

先感谢您。

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

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

对于 static 网站,我建议完全消除try_files 它只对动态网站有意义,并且可能是邪恶的。

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

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

一旦定义了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; 
    # ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM