簡體   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