Nginx

我的 nginx 反向代理配置有什麼問題,單伺服器(以及以後更多)

  • January 21, 2016

我正在嘗試使 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.comcurl -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塊分隔證書。為此,請使用更具體的 IP listen

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 443ssldefault_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;
... 

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