NGINX 作為 Apache 前面的反向代理在 SSL 開啟的情況下不起作用
我已經閱讀了論壇上的每一篇文章、教程和評論,一旦使用 Nginx 伺服器塊打開 SSL,我仍然無法讓 Nginx 代理正常工作。
Apache 完全設置了用於正常和 ssl 訪問的虛擬主機。Apache 監聽 8081 埠,ports.conf 如下:
NameVirtualHost *:8081 Listen 8081 <IfModule ssl_module> Listen 443 </IfModule> <IfModule mod_gnutls.c> Listen 443 </IfModule>
我的 SSL apache vhost 如下:
打開 nginx 並按照以下配置註釋掉 ssl 設置(見下文),一切正常,因為我能夠正確訪問 SSL 和非 SSL 版本的站點。
server { listen 80; # listen 443 ssl; server_name foobar.net; # ssl on; # ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem; location / { proxy_pass http://104.236.224.53:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
當我修改上述文件並通過取消註釋伺服器塊中的選項打開 SSL 時,Nginx 和 Apache 在埠 443 上似乎存在衝突?
更新和未註釋的伺服器塊如下所示:
server { listen 80; listen 443 ssl; server_name foobar.net; ssl on; ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem; location / { proxy_pass http://104.236.224.53:8081; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
嘗試啟動 nginx 返回以下錯誤:
nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Mon 2017-02-20 18:35:20 EST; 16s ago Process: 14505 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS Process: 14475 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS) Process: 14671 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE) Process: 14652 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 14328 (code=exited, status=0/SUCCESS) Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:18 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:19 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] listen() to 0.0.0.0:443, backlog 511 failed (98: Address already in use) Feb 20 18:35:20 foo.foobar.net nginx[14671]: nginx: [emerg] still could not bind() Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Control process exited, code=exited status=1 Feb 20 18:35:20 foo.foobar.net systemd[1]: Failed to start A high performance web server and a reverse proxy server. Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Unit entered failed state. Feb 20 18:35:20 foo.foobar.net systemd[1]: nginx.service: Failed with result 'exit-code'.
我在這裡缺少什麼以使 SSL 從 Nginx 正確傳遞給 Apache?
編輯 1: 為了解決 @Tim 的優點,我將編輯我的主要意圖,讓 Nginx 處理所有請求。
- 我的初衷是在 Apache 已經被用作我的主伺服器的同一台機器上安裝 Discourse,它本身位於 Docker 容器中。
- 因為 Discourse 需要訪問 80 埠才能正常執行,所以建議在前面設置 nginx 作為反向代理來處理所有傳入的請求,以便相應地傳遞它們。
- 我想在後面使用 apache 來處理所有動態內容,讓 nginx 處理靜態位。所以我的理解是,為了做到這一點,需要在 apache 上為每個實例建立一個虛擬主機:http 和 https 請求。也許我在這一點上錯了?
我遵循了DigitalOcean 建議的配置:快進到他們的可選步驟 9。
從邏輯上講,正如我在 apache 上的 HTTP 主機在埠 8081 上偵聽從 nginx 傳遞的請求一樣,我假設我可以做同樣的事情,並且 apache 上的 HTTPS 主機也可以偵聽埠 8081 並優雅地將標頭傳遞給 Apache處理其餘的。這個實現沒有完全工作,因為我被錯誤困擾
400: the plain http request was sent to https port
我更進一步並假設可能因為 Apache HTTP 和 HTTPS 都在後面偵聽埠 8081,如果我將分配的 apache HTTP 分配給埠 8081 並將 HTTPS 分配給埠 1443,那麼一切都會無縫執行。同樣,當我嘗試使用此實現通過 HTTPS 訪問我的 worpress 部落格時,它不能完全正常工作,我得到了錯誤
Your browser sent a request that this server could not understand. Reason: You're speaking plain HTTP to an SSL-enabled server port. Instead use the HTTPS scheme to access this URL, please.
在這一點上,儘管似乎很多人已經讓數字海洋建議的實施能夠正常工作,但我實際上還是沒有想法。:-/
看起來我終於得到了實施,這要歸功於我從你那裡收到的所有回饋。感謝@AlexeyTen 和@Tim
- 首先,我在 apache 上為 foobar.net 域禁用了 https vhost
sudo a2dissite foobar.net.cong
- 我編輯了 apache ports.conf 文件以僅監聽埠 8081 並刪除了對埠 443 的監聽:
NameVirtualHost *:8081 Listen 8081
- 最後我編輯了 nginx 伺服器塊來監聽埠 443 並確保註釋掉
ssl on
。不這樣做是行不通的。> server { > listen 80; > listen 443 ssl; > server_name foobar.net; > > # ssl on; > ssl_certificate /etc/letsencrypt/live/foobar.net/fullchain.pem; > ssl_certificate_key /etc/letsencrypt/live/foobar.net/privkey.pem; > > location / { > proxy_pass http://104.236.224.53:8081; > proxy_set_header Host $host; > proxy_set_header X-Real-IP $remote_addr; > proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; > proxy_set_header X-Forwarded-Proto $scheme; > } }
這個實現似乎工作正常,並且無縫地將 php 處理移交給 Apache。
您已經告訴 Apache 和 Nginx 在埠 443 上偵聽,我假設在同一台機器上。只有一個應用程序可以偵聽一個埠。
也許你可以編輯你的問題,告訴我們你為什麼要同時使用 Nginx 和 Apache——你可以用它們中的任何一個來做大多數事情。這樣你可能會得到更有用的建議。