nginx反向代理apache url靜默重寫和https重寫
我有一個 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*; }
<?php echo $_SERVER['REQUEST_SCHEME']; ?>
返回:http
<?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 }
我自己沒有使用過重寫,所以我不知道這是否是你想要做的任何事情的最佳方式。