[英]In order to switch my domain to HTTPS, do I need to change Apache or my Node.js app?
我有一個在我的域上運行的Web應用程序。 首先,我有一個常規的HTTP站點,該站點運行在服務器的8082端口上,而Apache服務器(使用虛擬主機)將請求從80端口重定向到localhost:8082
。
現在,我獲得了一個SSL證書,該證書試圖與我的網站一起安裝。 我在Node中制作了一個HTTPS服務器,並在https://localhost:8082
所有工作。
但是后來我嘗試通過HTTPS為我的域提供服務。 我嘗試編輯我的虛擬主機文件以使用證書,但我認為我沒有正確編寫它。 另外,我嘗試使它將HTTP重定向到HTTPS,但沒有用。
我該怎么辦? 我應該在Node中運行HTTP還是HTTPS服務器,我應該在Apache虛擬主機配置中添加什么?
這是我的虛擬主機文件:
<VirtualHost *:80>
ServerName www.domain.com
Redirect permanent / https://www.domain.com
</VirtualHost>
<VirtualHost *:443>
ServerName domain.com
ServerAlias www.domain.com
SSLEngine On
SSLProxyEngine On
SSLCertificateFile "/home/USERNAME/Projects/NODEAPP/chained.pem"
SSLCertificateKeyFile "/home/USERNAME/Projects/NODEAPP/domain.key"
ProxyPreserveHost On
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
<Location />
ProxyPass http://localhost:8082/
ProxyPassReverse http://localhost:8082/
</Location>
</VirtualHost>
(警告:我對您的問題的理解是,您希望https://www.domain.com
出現在瀏覽器的網址欄中,而不是https://www.domain.com:8082
。如果不是這樣的話以下內容是錯誤的,但可能仍將幫助您更好地理解問題。)
(aka,HTTP設計速成課程,因為我認為您不太了解正在發生的事情,但是如果您這樣做,請隨時跳過:)
我認為您對Apache的操作有一個誤解-主要是因為您是在說它正在“重定向”請求。
HTTP重定向是狀態代碼在3xx范圍內的任何(?)響應,它告訴您的瀏覽器所請求的資源已移動到其他地方。 例如,假設http://example.com/foo
曾經存在,但此后已移至http://example.org/bar
(請注意.com
和.org
區別)。 如果您在URL欄中輸入http://example.com/foo
,則瀏覽器將向example.com
請求/foo
(特別是它將發送HTTP GET請求)。 然后example.com
將HTTP響應發送回瀏覽器, 將其重定向到http://example.org/bar
。 然后,瀏覽器將/bar
的HTTP GET請求發送到example.org
並獲取包含該資源的響應。
這是一個圖:
Step 1:
------------- --------------------------
| | | |
| Browser | -------- HTTP GET /foo ---------> | example.com web server |
| | <-- HTTP 301 Moved Permanently -- | |
------------- --------------------------
Step 2:
------------- --------------------------
| | | |
| Browser | --- HTTP GET /bar ---> | example.org web server |
| | <---- HTTP 200 OK ---- | |
------------- --------------------------
現在,這是事情。 那不是你在做什么,也可能不是你想做什么。 您正在做的事情稱為反向代理,這是每當Web服務器(在您的情況下為Apache)接收到請求時,它將轉發到其他地方的請求。 在您的原始(全HTTP)設置中,Web瀏覽器將向Apache請求www.domain.com
,然后Apache只需將該請求(幾乎沒有修改)轉發到http://localhost:8082
。 如下圖:
Step 1:
------------- ---------- ------------------
| | | | | |
| | ----- HTTP GET / ----> | | | |
| Browser | | Apache | ----- HTTP GET / ----> | localhost:8082 |
| | | | <---- HTTP 200 OK ---- | |
| | <---- HTTP 200 OK ---- | | | |
------------- ---------- ------------------
Step 2:
There is no step 2. BOOM.
這里要注意的真正重要的事情是瀏覽器沒有“看到” Node.js,而是看到了另一端的Apache。 同樣,Node.js不會“看到”瀏覽器,而是看到Apache(盡管通常Apache會使用有關瀏覽器連接的詳細信息來擴充請求-例如,參見X-Forwarded-For
標頭)。
這是HTTP設計的故意部分-HTTP請求和響應語義並不暗示有關如何處理請求的內部實現細節。 這就是HTTP如此強大的原因。 它使您可以創建非常復雜的設置-思考您正在做的事情,但是要更大的規模並使用更多的組件-然后通過向外界顯示的簡單,統一的界面抽象出這種復雜性:URL層次結構與HTTP請求/響應周期。
既然我們已經確定了您要嘗試做的事情,這就是您的問題所在:您正在將Node.js在說什么協議與Apache在說什么協議(以及外界在看什么)混為一談。
您的最終目標是讓人們通過HTTPS連接到您的網站,對嗎? 在那種情況下,您不需要Node.js講HTTPS,因為直接與Node.js對話的唯一東西就是Apache。 Apache是與瀏覽器對話的東西,因此Apache是使用HTTPS所需要的。 理想情況下,您應該讓Apache對瀏覽器講HTTPS,對HTTP.Node.js講HTTP-Apache是否加密到Node的流量並不重要,因為Node在本地主機上。 以圖表形式:
------------- ---------- ------------------
| | | | | |
| | ----- HTTPS GET / ----> | | | |
| Browser | | Apache | ----- HTTP GET / ----> | localhost:8082 |
| | | | <---- HTTP 200 OK ---- | |
| | <---- HTTPS 200 OK ---- | | | |
------------- ---------- ------------------
因此,請讓您的Node應用程序偵聽HTTP請求,然后修復您的Apache配置,以使用HTTPS來提供服務,但要向Node后端講HTTP。
我認為您的配置有問題,您需要在路徑兩邊加上引號,即<Location "/">
。 或者,在我具有的反向代理配置中,我設置了ProxyPass
指令,而沒有<Location>
塊,如下所示:
ProxyPass / http://localhost:8082/
ProxyPassReverse / http://localhost:8082/
因此您也可以嘗試。
如果仍然無法正常運行,請嘗試刪除<Proxy>
/ </Proxy>
塊-我不確定是否可以這樣做,但是我的反向代理配置中沒有類似的功能(可以正常工作)-因此它可能會干擾某些事情。
至於您的HTTP到HTTPS重定向,我沒有發現任何問題。 您確定要連接到www.domain.com
而不是domain.com
嗎? 第二台VirtualHost可以同時為兩者提供服務,但第一台VirtualHost只能為前者提供服務。
根據您的描述,我將總結您的問題,如下所示:
您已將node.js配置為接受TLS連接
您希望Apache接受TLS連接
好。 所以第一個問題。 你說:
我在Node中制作了https服務器,並在https:// localhost:8082上使一切正常運行。
在不進行任何更改的情況下,嘗試訪問http://localhost:8082
什么? 我可以告訴您發生了什么(沒有猜測,沒有“應該”,我可以肯定地告訴您),但是您至少應該嘗試一下,以便自己了解發生了什么。
SPOILERS:HTTP不支持在單個端口上同時偵聽TLS和未加密的連接。 這只是協議的指定方式。 其他協議(例如POP3,SMTP,FTP等)也可以執行此操作,但HTTP無法執行。 因此,嘗試訪問http://localhost:8082
會失敗。
現在,仔細查看您的Apache配置:
# THIS is the problematic part:
ProxyPass http://localhost:8082/
ProxyPassReverse http://localhost:8082/
# ^
# |______ notice this?
因此,問題在於您正在代理無法使用的網址。
您在這里有兩個選擇。 兩者均有效,具體取決於您要如何設計體系結構。
代理https
而不是http
。
ProxyPass https://localhost:8082/ ProxyPassReverse https://localhost:8082/
這樣做的好處是您可以獲得端到端加密。 即使有人設法登錄到您的服務器,他們也無法收聽連接。 這樣做的缺點是您要加密兩次,這意味着您將花費更多的CPU時間來處理請求。
從node.js刪除TLS。
這樣做的好處是讓Apache處理所有加密,因此您的Web應用程序無需花費任何CPU時間來處理加密本身。 對於Google或Facebook這樣的大型服務,他們甚至可以將加密工作轉移到另一台前端服務器(或更可能的服務器),這樣運行您的Web應用程序的服務器就不會忙於加密和解密HTTP連接。 缺點是任何可以登錄到您的服務器的人都可以輕松收聽連接。
有些人可以采用第三種方法,但是這種方法越來越不受歡迎。 運行node.js在兩個端口上偵聽。 例如,配置一個可以監聽8082的HTTP,也可以監聽8084的https,然后可以將HTTP頁面代理到8082,將https頁面代理到8084。但是,查看您的Apache配置,我可以知道這不是您想要做的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.