允許通過反向代理登錄 IIS 站點的正確方法是什麼?
我有一個 nginx 反向代理,我正在嘗試讓一個帶有登錄名的 IIS 網站在它後面工作。我發現這個問題被問了好幾次,但每個答案似乎都不一樣,而且有些問題與我遇到的問題有點不同。
使用我目前的配置,我可以登錄,但是我收到 401 錯誤,並且它一直在詢問憑據。
我目前的配置:
/etc/nginx/sites-available/default
server { listen 80 default; server_name _; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name server2.mydomain.com; ssl_certificate /usr/local/nginx/conf/mydomain.com.crt; ssl_certificate_key /usr/local/nginx/conf/mydomain.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.20:80; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_redirect http:// $scheme://; } }
我的問題是,這應該工作的正確方法是什麼?
以下是我迄今為止研究過的內容:
這個連結,說這是不可能的。
這個連結說我應該在上游使用keepalive。這可能是答案,但是每當我在其中添加
upstream server2.mydomain.com
任何配置時,nginx 都無法重新啟動。我確定我有一些語法不正確,但我已經嘗試了幾件事。我會發布我嘗試過的所有內容,但我什至不確定這是正確的方法,而且我已經嘗試了很多東西,我想問問普通人是如何做到的會更容易。這個連結說你可以只添加
proxy_pass_request_headers on;
一行,它會以某種方式工作……但它不適合我。這個連結,似乎最有可能工作,但在試圖弄清楚如何使用這個連結編碼為 base64 之後,我一無所獲。
任何幫助是極大的讚賞。 這是我之前問過的一個問題,與此相關,但問題不同。
編輯1
我很抱歉這麼晚了,已經走了一點。
這是我對 nginx 反向代理伺服器的訪問日誌。192.168.0.5 是我的客戶僅供參考。
這些日誌來自我訪問該站點、獲得登錄提示、嘗試登錄一次(未成功)並登出提示。
/var/log/nginx/access.log
192.168.0.5 - - [09/Feb/2016:14:04:14 -0600] "GET / HTTP/1.1" 401 1293 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0" 192.168.0.5 - - [09/Feb/2016:14:04:31 -0600] "GET / HTTP/1.1" 401 341 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0" 192.168.0.5 - - [09/Feb/2016:14:04:31 -0600] "GET / HTTP/1.1" 401 1293 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0" 192.168.0.5 - - [09/Feb/2016:14:04:34 -0600] "GET /favicon.ico HTTP/1.1" 401 1293 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0"
/var/log/nginx/error.log
This file is empty
IIS 日誌
2016-02-11 19:39:22 192.168.0.20 GET /login - 80 - 192.168.0.10 Mozilla/5.0+(X11;+Linux+x86_64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Ubuntu+Chromium/45.0.2454.101+Chrome/45.0.2454.101+Safari/537.36 401 2 5 125 2016-02-11 19:39:28 192.168.0.20 GET /login - 80 - 192.168.0.10 Mozilla/5.0+(X11;+Linux+x86_64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Ubuntu+Chromium/45.0.2454.101+Chrome/45.0.2454.101+Safari/537.36 401 1 21480424 0 2016-02-11 19:39:36 192.168.0.20 GET /login - 80 - 192.168.0.10 Mozilla/5.0+(X11;+Linux+x86_64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Ubuntu+Chromium/45.0.2454.101+Chrome/45.0.2454.101+Safari/537.36 401 1 21480724 0 2016-02-11 19:40:16 192.168.0.20 GET /login - 80 - 192.168.0.10 Mozilla/5.0+(X11;+Linux+x86_64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Ubuntu+Chromium/45.0.2454.101+Chrome/45.0.2454.101+Safari/537.36 401 1 21407424 15 2016-02-11 19:40:22 192.168.0.20 GET /login - 80 - 192.168.0.10 Mozilla/5.0+(X11;+Linux+x86_64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Ubuntu+Chromium/45.0.2454.101+Chrome/45.0.2454.101+Safari/537.36 401 1 21480742 0
登錄沒有安全錯誤,所以我猜它從來沒有真正將登錄送出到系統。每次我點擊“登錄”時,它都會再次給我登錄彈出視窗。
實時 HTTP 標頭外掛輸出
https://server2.mydomain.com/ GET / HTTP/1.1 Host: server2.mydomain.com User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive HTTP/1.1 401 Unauthorized Server: nginx/1.4.6 (Ubuntu) Date: Tue, 09 Feb 2016 19:21:04 GMT Content-Type: text/html Content-Length: 1293 Connection: keep-alive WWW-Authenticate: NTLM WWW-Authenticate: Negotiate X-Powered-By: ASP.NET ---------------------------------------------------------- https://server2.mydomain.com/ GET / HTTP/1.1 Host: server2.mydomain.com User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Authorization: NTLM TlRNTVMTUAAAB4IIAAAAAAAAAAAAACDAFGAAAAAAAAAAAAAAAAA= HTTP/1.1 401 Unauthorized Server: nginx/1.4.6 (Ubuntu) Date: Tue, 09 Feb 2016 19:22:00 GMT Content-Type: text/html; charset=us-ascii Content-Length: 341 Connection: keep-alive WWW-Authenticate: NTLM TlRMTVNTUAACAAAAGgAaADgAAuzKir6ADucAAAAAAAAAAL4A&%$DSDADvgBSAAAABgGxHQAAAA9HAEUARQBLAFMAQQBOAEQATgBFAFIARABTAAIAGgBHRQBLAFMAQQBOAEQATgBFDFAFIARABTAAEADABLAEUATABWAEkATgAEACIAZwBlAGUAawBzAGEAbgBkAG4AZQByAGQAcwAuAGMAbwBtAAMAMABLAEUATABWAEkATgAuAGcAZQBlAGsAcwBhAG4AZABuAGUAcgBkAHMALgBjAG8AbQAFACIAZwBlAGUAawBzAGEAbgBkAG4AZQByAGQAcwAuAGMAbwBtAAcACAABRuM1b2PRAQAAAAA= ---------------------------------------------------------- https://server2.mydomain.com/ GET / HTTP/1.1 Host: server2.mydomain.com User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:42.0) Gecko/20100101 Firefox/42.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHAAAADqAOoAiAAAAAAAAAAGgAaAEAAAAAWABYAWgAAAAAAAAAAAAAABYIIAGEAbQBhAG4AZABhAC4AYgBsAG8AdQBuAHQAVwBPAFIASwBTAFQAQQBUAEkATwBOAHorEf/j46zta4wONTUAADAA-98uH//ZL0Am16vGzdWutoAAAAGAAYAHQAAAAAAAACFdzVEB9QHmLWLCuQQAAAAAAgAaAEcARQBFAEsAUwBBAE4ARABOAEUAUgBEAFMAAQAMAEsARQBMAFYASQBOAAQAIgBnAGUAZQBrAHMAYQBuAGQAbgBlAHIAZABzAC4AYwBvAG0AAwAwAEsARQBMAFYASQBOAC4AZwBlAGUAawBzAGEAbgBkAG4AZQByAGQAcwAuAGMAbwBtAAUAIgBnAGUAZQBrAHMAYQBuAGQAbgBlAHIAZABzAC4AYwBvAG0ABwAIAAFG4zVvY9EBAAAAAA== HTTP/1.1 401 Unauthorized Server: nginx/1.4.6 (Ubuntu) Date: Tue, 09 Feb 2016 19:22:00 GMT Content-Type: text/html Content-Length: 1293 Connection: keep-alive WWW-Authenticate: NTLM WWW-Authenticate: Negotiate X-Powered-By: ASP.NET ----------------------------------------------------------
EDIT2 - 為清楚起見,這裡是 IP 設置。
客戶端機器
192.168.0.5
Ubuntu 14.04 桌面
反向代理伺服器
192.168.0.10
nginx 1.4.6
Ubuntu 14.04 伺服器
伺服器 2
192.168.0.20
server2.mydomain.com
阿帕奇2
Ubuntu 14.04 伺服器
EDIT3 - 也許這有效,我做錯了,….也許不是
從這篇文章中,Fizz 寫了答案。
我在下面試過這個
/etc/nginx/sites-available/default
server { listen 80 default; server_name _; return 301 https://$host$request_uri; } upstream server2.mydomain.com { server 192.168.0.20:80 keepalive 16; } server { listen 443 ssl; server_name server2.mydomain.com; ssl_certificate /usr/local/nginx/conf/mydomain.com.crt; ssl_certificate_key /usr/local/nginx/conf/mydomain.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.20:80; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_redirect http:// $scheme://; } }
結果相同。基於其他答案….也許 apache2 是更好的選擇?
EDIT4 - 根據 Maxim Dounin 的回答進行編輯
我現在正在嘗試使用 Nginx 1.9.9,以及 Maxim Dounin 的回答中提到的流代理方法。
我從原始碼編譯,所以我的文件位置現在不同了。
/opt/nginx/nginx.conf
worker_processes 1; events { worker_connections 1024; } stream { upstream backend { hash $remote_addr consistent; server server2.mydomain.com:80 weight=5; server 192.168.0.20:80 max_fails=3 fail_timeout=30s; } server { listen 443 ssl; #Line 27 server_name server2.mydomain.com; ssl_certificate /usr/local/nginx/conf/mydomain.com.crt; ssl_certificate_key /usr/local/nginx/conf/mydomain.com.key; ssl_session_cache shared:SSL:10m; ssl_session_timeout 5m; proxy_connect_timeout 1s; proxy_timeout 3s; proxy_pass backend; } # server { # listen [::1]:12345; # proxy_pass unix:/tmp/stream.socket; # } }
我註釋掉了最後一個推薦的伺服器行,因為我不知道該怎麼做,但是由於其他錯誤,我的配置文件無論如何都沒有到達那裡。現在我的**/opt/nginx/logs/error.log**第 27 行有問題
the "ssl" parameter requires ngx_stream_ssl_module in /opt/nginx/nginx.conf:27
我肯定是用 ngx_stream_ssl_module 編譯的,因為當我執行nginx -V時,我得到了
configure arguments: --with-stream
希望我走在正確的軌道上。
問題是NTLM 身份驗證(注意
WWW-Authenticate: NTLM ...
),也就是 Windows 身份驗證。NTLM 身份驗證對連接而不是請求進行身份驗證,這與 HTTP 協議有些矛盾,HTTP 協議預計是無狀態的。因此,它通常不能通過代理工作,包括 nginx。
最簡單的解決方案是將 IIS 端的身份驗證更改為“基本”。如果由於某種原因這不是一個選項,其他可能性包括:
請注意,有一些建議將上游與 keepalive 一起使用,以使 NTLM 身份驗證正常工作。這些建議是不正確且有害的 - 除非您只為一位使用者使用代理。最糟糕的是,它可能看起來工作正常。問題是上游伺服器的keepalive連接保存在一個公共記憶體中,這些連接可以用於所有客戶端。因此,如果記憶體中存在經過身份驗證的連接,則碰巧使用此連接的無關客戶端將能夠繞過身份驗證。