Nginx

為什麼“/” nginx 位置規則無法擷取某些 URL?不應該和所有人一起去嗎?

  • May 28, 2021

我有一個用作反向代理的 nginx,它根據請求 URL 將請求重定向到 Angular 應用程序或節點 js 後端應用程序。還有一個location ~ /s/(cas)/(.*)提供靜態內容的規則(儘管我現在看到如果“/”也擷取了這條路線,那麼就沒有必要擁有該規則,因為靜態內容也保存在後端:4000)。

我擔心的是最普遍的規則“/”應該擷取所有未落入任何其他位置的請求,它沒有正確應用於某些 URLS,導致 nginx 發送其 50x.html 錯誤頁面。特別是,我的問題是這種重定向似乎無法擷取所有不符合先前規則的流量。並且是負責重定向應該登陸 Angular 應用程序的流量的一條規則。

如果我是正確的,這應該屬於“/”規則:

https://SUBDOMAIN.DOMAIN.es/user/trip/13925/instant?sharedToken=[REDACTED]

這些至少應該通過“/”規則正確重定向,但在大量超時後也會顯示 nginx 失敗頁面:

https://SUBDOMAIN.DOMAIN.es/user/trip/foo/instant?sharedToken=[REDACTED] # changed id for "foo"
https://SUBDOMAIN.DOMAIN.es/user/trip/instant?sharedToken=[REDACTED] # removed id segment of url
https://SUBDOMAIN.DOMAIN.es/user/instant?sharedToken=[REDACTED] # also removed "trip" segment of url

url 的任何其他變體都可以正常工作,並被重定向到 https://backend:4000。

那麼,為什麼這些規則沒有被位置“/”擷取呢?

這是 nginx 配置文件。域和子域已被故意省略:

server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
   expires $expires;
   add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
   server_name [SUBDOMAIN].[DOMAIN_NAME].es;
   ssl_certificate /etc/nginx/ssl/CERT.crt;
   ssl_certificate_key /etc/nginx/ssl/CERT.key;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_prefer_server_ciphers on;
   ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
   ssl_session_cache shared:SSL:5m;
   ssl_session_timeout 1h;
   gzip on;
   gzip_disable "msie6";
   gzip_vary on;
   gzip_proxied any;
   gzip_comp_level 6;
   gzip_buffers 16 8k;
   gzip_http_version 1.1;
   gzip_min_length 256;
   gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

   location ~ /api(?<url>/.*)  {
       resolver 127.0.0.11;
       set $target http://backend:5000/api${url}$is_args$args;
       proxy_set_header X-Forwarded-Host $host;     # Relay whatever hostname was received
       proxy_set_header X-Forwarded-Proto $scheme;  # Relay either http or https
       proxy_set_header X-Forwarded-Server $host;   # Relay whatever hostname was received
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Prefix /api/;
       proxy_set_header Host "SUBDOMAIN.DOMAIN.es";

       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Max-Age 3600;
       add_header Access-Control-Expose-Headers Content-Length;
       add_header Access-Control-Allow-Headers Range;

   ## Websockets support 2/2
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection $connection_upgrade;
   ## END Websockets support 2/2

       proxy_pass $target;
       client_max_body_size 10M;
   }

   location ^~ /_assets/ {
       alias /usr/share/nginx/html/assets/;
   }

   location ^~ /.well-known/acme-challenge/ {
       alias /usr/share/nginx/html/.well-known/acme-challenge/;
   }

   location ~ /s/(cas)/(.*) {
       add_header Pragma "no-cache";
       add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
       proxy_pass http://backend:4000;
   }

   location / {
       #root /usr/share/nginx/html;
       proxy_pass http://backend:4000;
       expires -1;
       proxy_set_header X-Forwarded-Host "SUBDOMAIN.DOMAIN.es";
       proxy_set_header X-Forwarded-Server "SUBDOMAIN.DOMAIN.es";
       proxy_set_header Host "SUBDOMAIN.DOMAIN.es";

       add_header Pragma "no-cache";
       add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";

       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Max-Age 3600;
       add_header Access-Control-Expose-Headers Content-Length;
       add_header Access-Control-Allow-Headers Range;
   }

   #error_page  404              /404.html;

   # redirect server error pages to the static page /50x.html
   #

   error_page   500 502 503 504  /50x.html;
   location = /50x.html {
       root   /usr/share/nginx/html;
   }

}

這些至少應該通過“/”規則正確重定向,但在大量超時後也會顯示 nginx 失敗頁面:

這表明是您的應用程序超時。nginx 錯誤頁面立即出現。

您應該檢查後端應用程序的日誌,當您發出需要很長時間的請求然後顯示失敗頁面時會發生什麼。

在這種情況下, nginxerror.log也是一個很好的調試工具。

引用自:https://serverfault.com/questions/1064975