Nginx

nginx反向代理apache url靜默重寫和https重寫

  • May 2, 2017

我有一個 nginx + apache 配置正在執行。我對 nginx 非常陌生,我花了很多時間來學習它。

首先,我想做一個基本的重寫。據我了解,當 nginx 用作反向代理時 - 來自 apache 的 .htaccess 應該仍然可以工作。可悲的是 - 我對它的理解並不完全正確 - 有些部分有效,而其他部分似乎無效。

所以我嘗試用 .htaccess 進行基本的重寫

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?index.* /fp/ [P]

我發現使用

$$ P $$.htaccess 中的標誌而不是正常的重寫 - 導致無法找到 /index.html 的錯誤(整個站點上沒有任何 index.html,因此很明顯無法​​找到)。 我嘗試使用

$$ L $$標誌也是如此,但不是像我期望的那樣靜默轉發,而是進行了重定向,因此使用者可以在地址欄中看到 /fp/ - 而不是我正在尋找的結果。 所以 - 我將重定向移動到 nginx 配置。這似乎工作正常。

我所做的 nginx 重定向非常基本,使用 if 語句

   if ($uri = '/'){
       rewrite / /fp/ break;
   }

此重定向僅重定向 / 不重定向 /index.php 或任何其他文件。

接下來我有一個名為/login.php 的文件。https://如果正在通過訪問,我想將使用者轉發到http://

所以我嘗試對 apache 方案進行檢查,$_SERVER['REQUEST_SCHEME'];問題是 - 無論是返回http還是https://``http://

login.php 在 /

所以對於初學者來說,我怎樣才能讓 http 僅在 login.php 頁面上重定向到 https。

我還應該注意,我嘗試使用 .htaccess 將 http 重定向到 https,但是由於伺服器返回的是 http 而不是 https,這導致了無限循環。

除此之外,為什麼 apache .htaccess

$$ P $$flag 導致搜尋 index.html,為什麼 silect 重定向突然變得公開? 如果我需要顯示我的配置 - 請告訴我哪些 :)

更新以顯示配置

nginx.conf

server {
proxy_pass_request_headers      on;
index index.php;
listen      192.227.210.138:80;
server_name adsactlyhits.com www.adsactlyhits.com;
error_log  /var/log/apache2/domains/adsactlyhits.com.error.log error;

location / {
   if ($uri = '/'){
       rewrite / /fp/ break;
   }
   proxy_pass      http://192.227.210.138:8080;
   location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
       root           /home/adsactly/web/adsactlyhits.com/public_html;
       access_log     /var/log/apache2/domains/adsactlyhits.com.log combined;
       access_log     /var/log/apache2/domains/adsactlyhits.com.bytes bytes;
       expires        max;
       try_files      $uri @fallback;
   }
}

location /error/ {
   alias   /home/adsactly/web/adsactlyhits.com/document_errors/;
}

location @fallback {
   proxy_pass      http://192.227.210.138:8080;
}
location ~ /\.svn/  {return 404;}
location ~ /\.git/  {return 404;}
location ~ /\.hg/   {return 404;}
location ~ /\.bzr/  {return 404;}

include /home/adsactly/conf/web/nginx.adsactlyhits.com.conf*;
}

snginx.conf

server {
listen      192.227.210.138:443;
server_name adsactlyhits.com www.adsactlyhits.com;
ssl         on;
ssl_certificate      /home/adsactly/conf/web/ssl.adsactlyhits.com.pem;
ssl_certificate_key  /home/adsactly/conf/web/ssl.adsactlyhits.com.key;
error_log  /var/log/apache2/domains/adsactlyhits.com.error.log error;

location / {
   if ($uri = '/'){
       rewrite / /fp/ break;
   }

   proxy_pass      http://192.227.210.138:8080;
   proxy_cache cache;
   proxy_cache_valid 15m;
   proxy_cache_valid 404 1m;
   proxy_no_cache $no_cache;
   proxy_cache_bypass $no_cache;
   proxy_cache_bypass $cookie_session $http_x_update;

   location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
       proxy_cache    off;
       root           /home/adsactly/web/adsactlyhits.com/public_html;
       access_log     /var/log/apache2/domains/adsactlyhits.com.log combined;
       access_log     /var/log/apache2/domains/adsactlyhits.com.bytes bytes;
       expires        max;
       try_files      $uri @fallback;
   }
}

location /error/ {
   alias   /home/adsactly/web/adsactlyhits.com/document_errors/;
}

location @fallback {
   proxy_pass      http://192.227.210.138:8080;
}

location ~ /\.ht    {return 404;}
location ~ /\.svn/  {return 404;}
location ~ /\.git/  {return 404;}
location ~ /\.hg/   {return 404;}
location ~ /\.bzr/  {return 404;}

include /home/adsactly/conf/web/nginx.adsactlyhits.com.conf*;
}

http://theurl.com/test.php

<?php echo $_SERVER['REQUEST_SCHEME']; ?>

返回:http

https://theurl.com/test.php

<?php echo $_SERVER['REQUEST_SCHEME']; ?>

返回:http

所以對於初學者來說,我怎樣才能讓 http 只在 login.php 頁面上重定向到 https

關鍵是 http 和 https 的不同伺服器塊。如果您從單個伺服器塊提供服務,則您的控制權將受到限制。像這樣的東西應該​​工作。

server {
 server_name example.com;
 listen 80; 

 location = login.php {
   return 302 https://example.com/login.php;
 }
}

server {
 server_name example.com;
 listen 443 ssl;

 # define any locations required
}

更大的圖景,您應該只通過 https 為您的整個站點提供服務以避免這些問題,除非您有充分的理由必須使用 http。您的應用程序可能必須知道站點在 http 和 https 之間被分段以支持此設置。

此外,通常不需要同時使用 Nginx 和 Apache。Nginx 可以做 Apache 可以做的大部分事情,而同時使用這兩者會增加複雜性。

任何時候你發現自己需要在 Nginx 中使用“if”,你都應該考慮一下Nginx “if is evil”一文。我確實使用 if,但只是為控制記憶體指令設置變數,而不是為任何關鍵或與流程相關的東西。您應該盡可能避免使用“如果”。

更新

本文向您展示瞭如何將諸如協議之類的標頭傳遞到下一層,以便它知道原始協議。你最好完全擺脫 Apache 並讓 Nginx 使用 php-fpm 呼叫 PHP。

location / {
 proxy_set_header HOST $host;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 proxy_pass http://example.com/new/prefix;
}

刪除如果重定向

而不是這個

location / {
 if ($uri = '/'){
   rewrite / /fp/ break;
 }
 // etc
}

你可以試試這樣的。等於運算符是完全匹配運算符。這將提供更好的性能(稍微)和更可靠的操作。

location = / {
   rewrite / /fp/ break;
}

location / {
 // etc
}

我自己沒有使用過重寫,所以我不知道這是否是你想要做的任何事情的最佳方式。

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