我的 nginx 反向代理配置有什麼問題,單伺服器(以及以後更多)
我正在嘗試使 nginx 反向代理設置正常工作。我設置了兩台網路伺服器,一台使用 nginx,一台使用 apache2。我目前無法讓它僅與 nginx 伺服器一起工作,所以這就是我現在正在嘗試的全部內容,但我補充說,我最終會嘗試兩個,以防影響設置。
我在這個設置中有四台機器。
1.客戶端機器
192.168.0.5
Ubuntu 14.04 桌面
2.反向代理伺服器
192.168.0.10
nginx 1.4.6
Ubuntu 14.04 伺服器
3. 伺服器 1
192.168.0.15
server1.mydomain.com
nginx 1.4.6
Ubuntu 14.04 伺服器
4. 伺服器 2
192.168.0.20
server2.mydomain.com
阿帕奇2
Ubuntu 14.04 伺服器
在我的客戶端電腦上,我已將主機文件設置為指向每個 Web 伺服器的反向代理伺服器,如下所示
/etc/hosts在客戶端 192.168.0.5 127.0.0.1 localhost 192.168.0.10 server1.mydomain.com 192.168.0.10 server2.mydomain.com
我有 server1 和 server2 的 ssl 證書,我已將其放在反向代理伺服器 (192.168.0.10) 上。我們將它們稱為 server1.crt、server1.key 和 server2.crt、server2.key。
我相信我必須使用這樣的證書進行此設置:
client(192.168.0.5) ---https---> reverseProxy(192.168.0.10 holds ssl certs) ---http---> server1 or server2
我現在兩台伺服器都在使用 http,我只需要修復 192.168.0.10 上的 nginx 反向代理設置。
這是我嘗試過的東西,但它沒有正確重定向。再一次,我想要一個到反向代理伺服器的 https 連接,然後在反向代理和伺服器之間建立一個 http 連接。
/etc/nginx/nginx.conf
user www-data; worker_processes 4; pid /run/nginx.pid; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## 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_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; ## # nginx-naxsi config ## # Uncomment it if you installed nginx-naxsi ## #include /etc/nginx/naxsi_core.rules; ## # nginx-passenger config ## # Uncomment it if you installed nginx-passenger ## #passenger_root /usr; #passenger_ruby /usr/bin/ruby; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
/etc/nginx/sites-available/default
server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; root /usr/share/nginx/html; index index.html index.htm; # Make site accessible from http://localhost/ server_name localhost; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } server { listen 443; server_name server1.mydomain.com; ssl on; ssl_certificate /usr/local/nginx/conf/server1.crt; ssl_certificate_key /usr/local/nginx/conf/server1.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; location / { proxy_pass http://192.168.0.15:80; proxy_set_header Host server1; proxy_redirect http:// https://; } }
我假設我的
/etc/nginx/sites-available/default
文件中有一些不正確的地方,但我已經閱讀了幾個教程,這似乎非常接近。這種設置顯然只嘗試使用 server1,而忽略了 server2,但我假設如果我能完成一項工作,我可以添加任意數量的其他工作。我發現了類似的問題,例如這個問題,但我仍然無法讓此配置與單個伺服器一起使用。目前正在發生的事情
目前,當我訪問 server1.mydomain.com 時,我得到標準的**“歡迎使用 nginx!”** 來自反向代理伺服器 (192.168.0.10) 的頁面。沒有進行轉發。
我接近了嗎?提前致謝
編輯1
在嘗試了 Capile 發布的解決方案後,我遇到了另一個問題(這可能是比我擁有更多網路知識的人所預料到的)。
當我將
/etc/nginx/sites-available/default
文件更改為此:/etc/nginx/sites-available/default(在反向代理上)
server { listen 80 default_server; listen 443 ssl default_server; server_name server1.mydomain.com; ssl on; ssl_certificate /usr/local/nginx/conf/server1.com.crt; ssl_certificate_key /usr/local/nginx/conf/server1.com.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; location / { proxy_pass http://192.168.0.15:80; proxy_set_header Host server1; proxy_redirect http:// https://; } }
有了這個配置,我得到一個
400 錯誤請求
純 HTTP 請求被發送到 HTTPS 埠
我想也許我應該嘗試一下
https://server1.mydomain.com
,但這只是旋轉。另外,我不介意為兩台伺服器使用相同的 ssl 證書。我不認為這將是一個問題。
編輯2
首先,感謝大家的幫助。
我
ssl on;
按照 Capile 的建議刪除了該行,並將該proxy_redirect http:// https://;
行更改proxy_redirect http:// $scheme://;
為 Richard Smith 推薦的行。這修復了對 http 流量的錯誤請求。所以現在,如果我訪問**http://server1.mydomain.com** ,我將成功重定向到該站點(耶!)
如果我嘗試訪問**https://server1.mydomain.com,我也會被重定向,這很好,但我收到了Unable to connect**錯誤。如果反向代理將 http 流量轉發到 http,將 https 流量轉發到 https,這是有道理的,因為後端伺服器沒有 https 配置。
我的目標是,如果我訪問http://server1.domain.com,它使用 https 連接到反向代理,然後使用 http 轉發到後端伺服器。這似乎沒有發生……看起來它只是在沒有使用 https 的情況下轉發它。
另一方面,如果我訪問https://server1.domain.com,它應該使用 https 連接到反向代理,然後使用 http 轉發到後端伺服器。
所以我從不想要從客戶端到反向代理伺服器的 http 連接。
捲髮雖然按預期行事。當我捲曲 http 或 https 站點時,我得到以下資訊:
curl -i https://server1.mydomain.com或curl -i http://server1.mydomain.com
HTTP/1.1 302 Found Server: nginx/1.4.6 (Ubuntu) Date: Thu, 21 Jan 2016 16:34:29 GMT Content-Type: text/html; charset=utf-8 Content-Length: 92 Connection: keep-alive Cache-Control: no-cache Location: http://test1/users/sign_in Set-Cookie: session=336e109ad711; path=/; expires=Thu, 28 Jan 2016 16:34:36 -0000; HttpOnly Status: 302 Found X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN X-Request-Id: ad65f-f6ds204-9fs8d-bdsdfa43-df5583266sdf87 X-Runtime: 0.005358 X-Xss-Protection: 1; mode=block <html><body>You are being <a href="http://test1/users/sign_in">redirected</a>.</body></html>
因此,對於任何一種類型的連接都肯定會發生重定向,但我認為客戶端和反向代理伺服器之間的 https 連接的 SSL 證書從未被使用過。
你很接近,但沒有配置 http 的反向代理,只有 https (在上面的設置中)——所以它應該顯示來自文件根目錄的預設內容。第一個伺服器也缺少結尾
}
。您可以在同一塊中同時配置 http 和 https ,只需
ssl
在 listen 指令中使用關鍵字(在 ssl 埠下,因此無需設置ssl on
指令):server { listen 80 default_server; listen 443 ssl default_server; ... ssl_certificate /usr/local/nginx/conf/server1.crt; ssl_certificate_key /usr/local/nginx/conf/server1.key; ssl_session_cache shared:SSL:10m; ...
我必須提醒,在同一個 IP 中使用兩個不同的 SSL 證書有些限制和復雜——因為它需要 HTTP 重新協商(因為在請求正確的主機之前需要使用證書加密請求),所以你可能會需要逐
server
塊分隔證書。為此,請使用更具體的 IPlisten
:server { listen 192.168.0.10:443 ssl; # for server1.mydomain.com ... server { listen 192.168.0.11:443 ssl; # for server2.mydomain.com ...
我還建議您使用Mozilla SSL 配置生成器來獲得 SSL 安全性的最佳實踐。
編輯1
為避免 400 錯誤,只需刪除指令
ssl on;
並重新載入。它導致 http 流量需要 SSL — 您已經在該行上指示使用 ssl:(這意味著在此埠上打開 ssl)。listen 443
ssl
default_server;
其餘配置沒問題,但根據您的伺服器響應,您可能需要調整代理設置。
首先,檢查旋轉是客戶端還是伺服器端:使用cURL訪問它或打開瀏覽器上的 Web 開發人員工具並檢查網路:如果您的瀏覽器被重定向,您可能需要調整
proxy_redirect
甚至做一些伺服器響應上的字元串替換。使用 cURL 以這種方式檢查:
curl -i http://server1.mydomain.com
如果您
Location:
在響應中看到標頭,則需要微調您的代理設置(這將取決於響應)。例如,您可能以 https 訪問它,然後您的代理作為 http 轉發,而您的後端伺服器應用程序重定向到 https(但是當響應通過代理時,它會返回到瀏覽器的 http)。有幾種方法可以修復它,通過使用proxy_set_header
甚至調整您的後端伺服器。例如,您可以使用:
proxy_set_header X-Forwarded-Proto $scheme;
但是您的後端 http 伺服器或您的應用程序都需要正確理解這一點。
或者,如果沒有重定向,但也沒有響應(或請求超時後沒有網關響應 - 30 秒),請檢查您的後端伺服器是否正確響應代理伺服器。
另請注意,您的後端不需要 http 伺服器,例如,您可以直接使用 FastCGI 伺服器——這有時會減少故障。
編輯2
根據 cURL 響應,我看到配置按預期工作 - 後端伺服器響應要求您登錄。如果 SSL 證書不起作用,您將無法
curl -i https://server1.mydomain.com
.前端(代理)和後端之間的流量僅通過 http 進行(請參閱
proxy_pass
指令),這通常也是預期的(另一種加密可能會增加不必要的成本)。現在,如果您希望僅使用 https,您有兩個選擇:要麼在後端配置它(以便將您轉發到https ://test1/users/sign_in),要麼對 nginx 使用不同的設置,您可以在其中剝離http:80 伺服器並使其將所有內容重定向到 https:443。像這樣的東西(一定
listen 80
要從下一個伺服器塊中刪除):server { listen 80 default; server_name _; return 301 https://$host$request_uri; } server { listen 443 ssl; ...