Nginx

在 AWS ELB 後面使用 NGINX 剝離 www

  • April 7, 2017

我正在嘗試從我的請求 URL 中刪除 www,但是當我將以下內容添加到我的 nginx 配置中時,我的 AWS ELB 執行狀況檢查失敗。

server {
   listen 80;
   server_name www.example.com;
   return 301 $scheme://example.com$request_uri;
}

知道可能導致問題的原因嗎?這是我的配置的其餘部分:

server {

   listen 80;

   server_name .example.com;
   root /var/www/static;
   index index.html;

   try_files $uri.html $uri $uri/ =404;

   charset UTF-8;

   error_log /var/log/error.log;
   access_log /var/log/access.log;

   # ELB test route
   location /test {
       add_header X-Robots-Tag noindex;
       default_type text/plain; 
       return 200 'success';
   }

   # Redirect any request http request that come from AWS ELB to https
   if ($http_x_forwarded_proto = "http") {
       return 301 https://$server_name$request_uri;
   }
}

這是我的健康檢查設置:

aws 目標組健康檢查

來自亞馬遜文件

為確保您的負載均衡器可以正確擴展,請驗證您的負載均衡器的每個子網都有一個至少具有 /27 位遮罩的 CIDR 塊(例如,10.0.0.0/27)並且至少有 8 個空閒 IP 地址。您的負載均衡器使用這些 IP 地址與實例建立連接。

這聽起來像是 ELB 健康檢查是通過 AWS 私有 IP 而不是域名進行的。根據我對亞馬遜的了解,這就是他們在可能的情況下更喜歡做事的方式(出於明顯的性能原因,不需要 DNS 查找,可以由更近的路由器處理等)

如果是這種情況,那麼主機標頭(除非它是空白的,我不能 100% 確定當您向裸 IP 發出請求時主機標頭是如何工作的)將是 EC2 實例的私有 AWS 地址(I’ m 假設它是 EC2) 執行網路伺服器。這會影響 Nginx 選擇應由哪個虛擬伺服器處理請求的方式。

由於 Nginx 有兩個server塊,它必須決定哪個塊獲得任何給定的請求。它選擇伺服器塊的過程(詳見此處)如下:

  • 首先,它查找正在偵聽請求傳入埠的伺服器。在這種情況下,兩台伺服器都在偵聽同一個埠,所以這沒有任何幫助。
  • 然後它查看請求的主機頭,並尋找與server_name主機頭匹配的伺服器。在這種情況下,它們都不匹配,因為主機標頭是分配給實例的私有 AWS IP(或空白,正如我所說,我不確定。)
  • 最後,如果這些都沒有產生匹配,它只會與預設的伺服器一起使用。在沒有明確的預設聲明的情況下,首先在站點配置中定義的伺服器被選為預設值。

如果您的重定向伺服器位於主伺服器配置之前(正如我想像的那樣),那麼這可能是您的問題。您需要做以下三件事之一:

  • 通過添加到指令中指定您希望其他伺服器(主伺服器)成為預設伺服器,即default_server``listen``listen 80 default_server;
  • 將塊切換location /test到另一個伺服器塊,或
  • 顛倒定義伺服器塊的順序。

第一個選項似乎是要走的路,因為default_server指令顯式而不是隱式是有意義的,主伺服器是預設伺服器而不是你有一個工作的重定向伺服器是有意義的。

如果我的假設是正確的,那應該可以解決。

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