Apache HTTP 伺服器 2.4 版
諸如「mod_ssl: 子處理程序無法開啟 SSLMutex 鎖定檔案 /opt/apache/logs/ssl_mutex.18332(系統錯誤如下)[...] 系統:權限被拒絕(錯誤碼:13)
」之類的錯誤通常是由於_父_目錄的權限過於嚴格所致。請確保所有父目錄(這裡是 /opt
、/opt/apache
和 /opt/apache/logs
)至少為執行 Apache 子處理程序的 UID 設定了 x 位元(請參閱 User
指令)。
密碼軟體需要不可預測的數據來源才能正常運作。許多開源作業系統都提供了一個「隨機性裝置」來實現這個目的(通常命名為 /dev/random
)。在其他系統上,應用程式必須在產生金鑰或執行公鑰加密之前,使用適當的數據手動為 OpenSSL 虛擬隨機數產生器 (PRNG) 設定種子。從 0.9.5 版開始,需要隨機性的 OpenSSL 函數會在 PRNG 未設定至少 128 位元隨機性種子的情況下回報錯誤。
為了防止這個錯誤,mod_ssl
必須為 PRNG 提供足夠的熵值,才能讓它正常運作。這可以使用 SSLRandomSeed
指令來完成。
SSL_XXX
變數?可以。HTTP 和 HTTPS 使用不同的伺服器連接埠(HTTP 綁定到連接埠 80,HTTPS 綁定到連接埠 443),因此它們之間沒有直接衝突。您可以執行兩個分別綁定到這些連接埠的獨立伺服器實例,或者使用 Apache 優雅的虛擬主機功能來建立兩個虛擬伺服器,這兩個伺服器都由同一個 Apache 實例提供服務 - 一個透過 HTTP 回應連接埠 80 上的請求,另一個透過 HTTPS 回應連接埠 443 上的請求。
您可以在任何連接埠上執行 HTTPS,但標準指定了連接埠 443,這是任何相容 HTTPS 的瀏覽器預設會查找的連接埠。您可以透過在 URL 中指定不同的連接埠,強制瀏覽器在該連接埠上查找。例如,如果您的伺服器設定為透過 HTTPS 在連接埠 8080 上提供網頁,則您可以透過 https://example.com:8080/
存取這些網頁。
雖然您通常只使用
$ telnet localhost 80
GET / HTTP/1.0
透過 HTTP 對 Apache 進行簡單測試,但對於 HTTPS 來說並不容易,因為 TCP 和 HTTP 之間有 SSL 協定。但是,藉助 OpenSSL 的 s_client
命令,您可以透過 HTTPS 執行類似的檢查。
$ openssl s_client -connect localhost:443 -state -debug
GET / HTTP/1.0
在實際的 HTTP 回應之前,您將收到有關 SSL 交握的詳細資訊。如需更通用的命令列用戶端,可以直接理解 HTTP 和 HTTPS、可以執行 GET 和 POST 操作、可以使用代理伺服器、支援位元組範圍等,您應該查看一下精巧的 cURL 工具。使用這個工具,您可以按如下方式檢查 Apache 是否正確回應透過 HTTP 和 HTTPS 發出的請求。
$ curl https://127.0.0.1/
$ curl https://127.0.0.1/
當您嘗試透過 HTTP 連接到 HTTPS 伺服器(或虛擬伺服器)時(例如,使用 http://example.com/
而不是 https://example.com
),就可能會發生這種情況。在嘗試透過 HTTPS 連接到 HTTP 伺服器時,也可能會發生這種情況(例如,在不支援 HTTPS 的伺服器上使用 https://example.com/
,或在非標準連接埠上支援 HTTPS 的伺服器上使用 https://example.com/
)。請確保您要連接到支援 SSL 的(虛擬)伺服器。
這個錯誤可能是設定錯誤造成的。請確認您的 Listen
指令與您的 <VirtualHost>
指令相符。如果所有方法都失敗,請使用 mod_ssl
提供的預設設定重新開始。
SSL_XXX
變數?請確認您的 CGI/SSI 請求環境中已啟用「SSLOptions +StdEnvVars
」。
通常,若要在 HTTP 和 HTTPS 之間切換,您必須使用完整格式的超連結(因為您必須變更 URL 結構描述)。但是,使用 mod_rewrite
,您可以操作相對超連結來達到相同的效果。
RewriteEngine on RewriteRule "^/(.*)_SSL$" "https://%{SERVER_NAME}/$1" [R,L] RewriteRule "^/(.*)_NOSSL$" "http://%{SERVER_NAME}/$1" [R,L]
這個重寫規則集允許您使用 <a href="document.html_SSL">
格式的超連結,在相對連結中切換到 HTTPS。(將 SSL 替換為 NOSSL 即可切換到 HTTP。)
RSA 私鑰檔案是一個數位檔案,您可以使用它來解密傳送給您的訊息。它有一個公開元件,您可以透過您的憑證檔案分發,允許人們將這些訊息加密給您。
憑證簽署請求 (CSR) 是一個數位檔案,其中包含您的公鑰和您的名稱。您將 CSR 傳送到憑證授權單位 (CA),CA 會透過簽署將其轉換為真實憑證。
憑證包含您的 RSA 公鑰、您的名稱、CA 的名稱,並且由 CA 進行數位簽署。瞭解 CA 的瀏覽器可以驗證該憑證上的簽章,從而取得您的 RSA 公鑰。這使得它們能夠傳送只有您可以解密的訊息。
如需 SSL 協定的概述,請參閱簡介章節。
是的。一般來說,使用內建 mod_ssl
啟動 Apache 就像在沒有它的情況下啟動 Apache 一樣。但是,如果您的 SSL 私鑰檔案上有通行密碼,則會彈出一個啟動對話方塊,要求您輸入通行密碼。
在啟動伺服器時必須手動輸入通行密碼可能會造成問題 - 例如,從系統開機指令碼啟動伺服器時。在這種情況下,您可以按照下方的步驟從您的私鑰中移除通行密碼。請記住,這樣做會帶來額外的安全風險 - 請謹慎操作!
PATH
中。server.key
和 server.crt
檔案。$ openssl req -new -x509 -nodes -out server.crt -keyout server.key
httpd.conf
檔案中按如下方式使用。SSLCertificateFile "/path/to/this/server.crt" SSLCertificateKeyFile "/path/to/this/server.key"
server.key
_沒有_任何通行密碼。若要為金鑰新增通行密碼,您應該執行以下命令,並根據要求輸入和驗證通行密碼。$ openssl rsa -des3 -in server.key -out server.key.new
$ mv server.key.new server.key
server.key
檔案和您輸入的通行密碼備份到安全的位置。以下是逐步說明。
PATH
中。$ openssl genrsa -des3 -out server.key 2048
server.key
檔案和您輸入的通行密碼備份到安全的位置。您可以使用以下命令查看這個 RSA 私鑰的詳細資訊。$ openssl rsa -noout -text -in server.key
$ openssl rsa -in server.key -out server.key.unsecure
$ openssl req -new -key server.key -out server.csr
https://www.foo.dom/
存取的網站產生 CSR 時,請在此處輸入「www.foo.dom」。您可以使用以下命令查看這個 CSR 的詳細資訊。$ openssl req -noout -text -in server.csr
$ openssl x509 -noout -text -in server.crt
server.key
和 server.crt
。這些可以在您的 httpd.conf
檔案中按如下方式使用。SSLCertificateFile "/path/to/this/server.crt" SSLCertificateKeyFile "/path/to/this/server.key"不再需要
server.csr
檔案。簡單的答案是使用 OpenSSL 提供的 CA.sh
或 CA.pl
指令碼。除非您有充分的理由不這樣做,否則您應該優先使用這些指令碼。如果您不能這樣做,則可以按如下方式建立自簽憑證。
$ openssl genrsa -des3 -out server.key 2048
server.key
檔案和您輸入的通行密碼備份到安全的位置。您可以使用以下命令查看這個 RSA 私鑰的詳細資訊。$ openssl rsa -noout -text -in server.key
$ openssl rsa -in server.key -out server.key.unsecure
$ openssl req -new -x509 -nodes -sha1 -days 365 -key server.key -out server.crt -extensions usr_cert
server.crt
檔案。$ openssl x509 -noout -text -in server.crt
您只需使用舊的通行片語讀取它,然後再次寫入,並指定新的通行片語。您可以使用以下指令完成此操作
$ openssl rsa -des3 -in server.key -out server.key.new
$ mv server.key.new server.key
第一次系統要求您輸入 PEM 通行片語時,您應該輸入舊的通行片語。之後,系統會再次要求您輸入通行片語 - 這次請使用新的通行片語。如果系統要求您驗證通行片語,您需要再次輸入新的通行片語。
這個對話方塊會在啟動和每次重新啟動時彈出,原因是 server.key
檔案中的 RSA 私鑰是為了安全起見以加密格式儲存的。需要使用通行片語來解密此檔案,以便讀取和解析它。移除通行片語會降低伺服器的安全性 - 請謹慎操作!
$ cp server.key server.key.org
$ openssl rsa -in server.key.org -out server.key
server.key
檔案$ chmod 400 server.key
現在 server.key
包含金鑰的未加密副本。如果您將伺服器指向此檔案,它將不會提示您輸入通行片語。但是,如果有人取得此金鑰,他們將能夠在網路上冒充您。請確保此檔案的權限設定為只有 root 或網路伺服器使用者可以讀取它 (最好讓您的網路伺服器以 root 身分啟動,但以另一個使用者身分執行,並且金鑰只能由 root 讀取)。
或者,您也可以使用 ``SSLPassPhraseDialog exec:/path/to/program
'' 功能。請記住,這當然不會更安全或更不安全。
私鑰包含一系列數字。其中兩個數字構成「公鑰」,其他數字則屬於「私鑰」。產生 CSR 時會包含「公鑰」位元,這些位元隨後會成為關聯憑證的一部分。
若要檢查憑證中的公鑰是否與私鑰的公開部分相符,您只需比較這些數字即可。若要檢視憑證和金鑰,請執行以下指令
$ openssl x509 -noout -text -in server.crt
$ openssl rsa -noout -text -in server.key
金鑰和憑證中的「模數」和「公開指數」部分必須相符。由於公開指數通常是 65537,而且很難以視覺方式檢查長模數是否相同,因此您可以使用以下方法
$ openssl x509 -noout -modulus -in server.crt | openssl md5
$ openssl rsa -noout -modulus -in server.key | openssl md5
這會產生兩個較短的數字供您比較。理論上,這些數字可能相同,而模數卻不同,但這種可能性微乎其微。
如果您想檢查特定 CSR 屬於哪個金鑰或憑證,您可以對 CSR 執行相同的計算,如下所示
$ openssl req -noout -modulus -in server.csr | openssl md5
OpenSSL 的預設憑證格式為 PEM,它只是 Base64 編碼的 DER,包含標頭和頁尾行。對於某些應用程式 (例如 Microsoft Internet Explorer),您需要使用純 DER 格式的憑證。您可以使用以下指令將 PEM 檔案 cert.pem
轉換為對應的 DER 檔案 cert.der
:$ openssl x509 -in cert.pem -out cert.der -outform DER
發生這種情況的原因之一可能是您的伺服器憑證是由中間 CA 簽署的。各種 CA,例如 Verisign 或 Thawte,已經開始使用中間憑證而不是根憑證來簽署憑證。
中間 CA 憑證位於根 CA 憑證 (安裝在瀏覽器中) 和伺服器憑證 (您安裝在伺服器上) 之間。為了讓瀏覽器能夠遍歷並驗證從伺服器憑證到根憑證的信任鏈,它需要取得中間憑證。CA 應該能夠提供您可以在伺服器上安裝的此類中間憑證套件。
您需要使用 SSLCertificateChainFile
指令包含這些中間憑證。
這可能有幾個原因,但主要原因是 SSLSessionCache
指令指定的 SSL 工作階段快取出現問題。DBM 工作階段快取最有可能出現問題,因此使用 SHM 工作階段快取 (或完全不使用快取) 可能會有幫助。
SSL 使用強大的加密加密,這需要大量的計算。當您透過 HTTPS 請求網頁時,所有內容 (甚至是圖片) 在傳輸之前都會被加密。因此,HTTPS 流量增加會導致負載增加。
這通常是由於 SSLRandomSeed
的 /dev/random
裝置會封鎖 read(2) 呼叫,直到有足夠的熵可用於服務請求為止。如需詳細資訊,請參閱 SSLRandomSeed
指令的參考手冊。
通常,mod_ssl
也支援 OpenSSL 版本支援的任何 SSL 密碼。可用的密碼取決於您建置 OpenSSL 的方式。通常,至少支援以下密碼
若要判斷實際可用的密碼清單,您應該執行以下指令
$ openssl ciphers -v
根據預設,基於安全考量,OpenSSL 不允許使用 ADH 密碼。如果您選擇啟用這些密碼,請務必了解潛在的副作用。
若要使用匿名迪菲 - 海爾曼 (ADH) 密碼,您必須使用 ``-DSSL_ALLOW_ADH
'' 建置 OpenSSL,然後在您的 SSLCipherSuite
中新增 ``ADH
''。
您可能在 SSLCipherSuite
指令中犯了錯誤 (將其與 extra/httpd-ssl.conf
中預先設定的範例進行比較),或者您在產生私鑰時選擇使用 DSA/DH 演算法而不是 RSA,並且忽略或忽略了警告。如果您選擇了 DSA/DH,則您的伺服器將無法使用基於 RSA 的 SSL 密碼進行通訊 (至少在您設定額外的基於 RSA 的憑證/金鑰對之前是如此)。NS 或 IE 等現代瀏覽器只能使用 RSA 密碼透過 SSL 進行通訊。結果就會出現「沒有共用密碼」錯誤。若要解決此問題,請使用 RSA 演算法重新產生您的伺服器憑證/金鑰對。
原因非常技術性,而且有點像是「雞生蛋,蛋生雞」的問題。SSL 協定層位於 HTTP 協定層下方,並封裝 HTTP。當建立 SSL 連線 (HTTPS) 時,Apache/mod_ssl 必須與用戶端協商 SSL 協定參數。為此,mod_ssl 必須查閱虛擬伺服器的設定 (例如,它必須查找密碼套件、伺服器憑證等)。但是,為了轉到正確的虛擬伺服器,Apache 必須知道 Host
HTTP 標頭欄位。為此,必須讀取 HTTP 請求標頭。這在 SSL 握手完成之前無法完成,但需要這些資訊才能完成 SSL 握手階段。如需如何解決此問題,請參閱下一個問題。
請注意,如果您有萬用字元 SSL 憑證,或使用 subjectAltName 欄位在其上具有多個主機名稱的憑證,則可以在基於名稱的虛擬主機上使用 SSL,而無需進一步的解決方法。
基於名稱的虛擬主機是一種非常流行的識別不同虛擬主機的方法。它允許您為許多不同的網站使用相同的 IP 位址和相同的埠號。當人們轉向 SSL 時,很自然地會認為可以使用相同的方法在同一台伺服器上擁有許多不同的 SSL 虛擬主機。
這是可能的,但前提是使用 2.2.12 或更新版本的網路伺服器,並使用 0.9.8j 或更新版本的 OpenSSL 建置。這是因為它需要 SSL 規範最新版本中才新增的一項功能,稱為伺服器名稱指示 (SNI)。
請注意,如果您有萬用字元 SSL 憑證,或使用 subjectAltName 欄位在其上具有多個主機名稱的憑證,則可以在基於名稱的虛擬主機上使用 SSL,而無需進一步的解決方法。
原因是 SSL 協定是一個獨立的層,它封裝了 HTTP 協定。因此,SSL 工作階段是一個獨立的交易,它在 HTTP 工作階段開始之前進行。伺服器在 IP 位址 X 和埠 Y (通常是 443) 上收到 SSL 請求。由於 SSL 請求不包含任何 Host: 欄位,因此伺服器無法決定要使用哪個 SSL 虛擬主機。通常,它只使用它找到的第一個與指定埠和 IP 位址相符的主機。
但是,如果您使用的是支援 SNI 的網路伺服器和 OpenSSL 版本,並且用戶端的瀏覽器也支援 SNI,則主機名稱會包含在原始 SSL 請求中,並且網路伺服器可以選擇正確的 SSL 虛擬主機。
當然,您可以使用基於名稱的虛擬主機來識別許多非 SSL 虛擬主機 (例如,全部都在埠 80 上),然後擁有一個 SSL 虛擬主機 (在埠 443 上)。但是,如果您這樣做,則必須確保在 NameVirtualHost 指令中放入非 SSL 埠號,例如
NameVirtualHost 192.168.1.1:80
其他解決方法包括
為不同的 SSL 主機使用不同的 IP 位址。為不同的 SSL 主機使用不同的埠號。
雖然 SSL 壓縮協商是在 SSLv2 和 TLS 的規範中定義的,但直到 2004 年 5 月,RFC 3749 才將 DEFLATE 定義為一種可協商的標準壓縮方法。
當使用 zlib
選項編譯時,OpenSSL 0.9.8 開始預設支援此功能。如果用戶端和伺服器都支援壓縮,則將使用壓縮。但是,大多數用戶端仍然嘗試使用 SSLv2 Hello 進行初始連線。由於 SSLv2 的握手中未包含偏好的壓縮演算法陣列,因此無法與這些用戶端協商壓縮。如果用戶端停用對 SSLv2 的支援,則可能會傳送 SSLv3 或 TLS Hello,具體取決於使用的 SSL 程式庫,並且可能會設定壓縮。您可以透過記錄 %{SSL_COMPRESS_METHOD}x
變數來驗證用戶端是否使用 SSL 壓縮。
不,使用者名稱/密碼是以加密方式傳輸的。Netscape 瀏覽器中的圖示實際上與 SSL/TLS 層不同步。只有在實際網頁資料的第一部分傳輸完成後,它才會切換到鎖定狀態,這可能會讓人感到困惑。基本驗證功能是 HTTP 層的一部分,位於 HTTPS 中 SSL/TLS 層的上方。在 HTTPS 中進行任何 HTTP 資料通訊之前,SSL/TLS 層已經完成了握手階段,並切換到加密通訊。所以不要被這個圖示搞糊塗了。
第一個原因是,某些 MSIE 版本中的 SSL 實作在與 HTTP 持久連線功能和通訊埠連線關閉時的 SSL 關閉通知警報相關方面存在一些細微的錯誤。此外,在某些 MSIE 版本中,SSL 和 HTTP/1.1 功能之間的交互作用也存在問題。您可以透過強制 Apache 不使用 HTTP/1.1、持久連線或向 MSIE 用戶端發送 SSL 關閉通知訊息來解決這些問題。這可以透過在您的 SSL 感知虛擬主機區段中使用以下指令來完成
SetEnvIf User-Agent "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0
此外,某些 MSIE 版本在特定密碼方面存在問題。遺憾的是,無法針對此問題實作特定於 MSIE 的解決方法,因為密碼在 SSL 握手階段就已經需要了。因此,特定於 MSIE 的 SetEnvIf
無法解決這些問題。相反,您必須對全域參數進行更徹底的調整。在您決定這樣做之前,請確保您的用戶端確實存在問題。如果沒有,請不要進行這些更改 - 它們將影響您的*所有*用戶端,無論是 MSIE 還是其他用戶端。
TLS-SRP(TLS 的安全遠端密碼金鑰交換,在 RFC 5054 中指定)可以補充或替換用於驗證 SSL 連線的憑證。若要使用 TLS-SRP,請將 SSLSRPVerifierFile
指令設定為指向 OpenSSL SRP 驗證器檔案。若要建立驗證器檔案,請使用 openssl
工具
openssl srp -srpvfile passwd.srpv -add username
建立此檔案後,在 SSL 伺服器組態中指定它
SSLSRPVerifierFile /path/to/passwd.srpv
若要強制用戶端使用非憑證 TLS-SRP 密碼套件,請使用以下指令
SSLCipherSuite "!DSS:!aRSA:SRP"
從 2.4.7 版本開始,mod_ssl
將使用包含長度超過 1024 位元的質數的 DH 參數。但是,Java 7 及更早版本將其對 DH 質數大小的支援限制為最多 1024 位元。
如果您的基於 Java 的用戶端因 java.lang.RuntimeException: Could not generate DH keypair
和 java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
等異常而中止,並且 httpd 記錄 tlsv1 alert internal error (SSL alert number 80)
(在 LogLevel
info
或更高版本),您可以使用 SSLCipherSuite
重新排列 mod_ssl 的密碼清單(可能與 SSLHonorCipherOrder
結合使用),或者您可以使用具有 1024 位元質數的自訂 DH 參數,這些參數始終優先於任何內建的 DH 參數。
若要產生自訂 DH 參數,請使用 openssl dhparam 1024
命令。或者,您可以使用 RFC 2409 第 6.2 節中的以下標準 1024 位元 DH 參數
-----BEGIN DH PARAMETERS----- MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL /1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC -----END DH PARAMETERS-----
將包含「BEGIN DH PARAMETERS」和「END DH PARAMETERS」行的自訂參數添加到您使用 SSLCertificateFile
指令組態的第一個憑證檔案的末尾。
以下資訊資源可用。如果出現問題,您應該先在這裡搜尋。
以下列出了 mod_ssl 的所有支援可能性,按優先順序列出。請*按此順序*仔細閱讀這些可能性 - 不要只選擇您喜歡的那一種。
您應始終至少提供以下資訊
httpd -v
來確定。OpenSSL 版本可以透過執行 openssl version
來確定。或者,如果您安裝了 Lynx,則可以執行命令 lynx -mime_header https://127.0.0.1/ | grep Server
來一步收集這些資訊。configure
命令列。總體而言,不,至少在您沒有提供有關 Apache 傾印核心的程式碼位置的更多細節的情況下是這樣。為了幫助您,通常始終需要的是回溯追蹤(請參見下一個問題)。如果沒有這些資訊,幾乎不可能找到問題並幫助您解決問題。
以下是您需要完成的步驟,以取得回溯追蹤
OPTIM="-g -ggdb3"
」建置 Apache+mod_ssl 才能獲得此功能。在其他平台上,至少需要「OPTIM="-g"
」。CoreDumpDirectory /tmp
」之類的指令來確保可以寫入核心傾印檔案。這應該會產生 /tmp/core
或 /tmp/httpd.core
檔案。如果您沒有獲得其中任何一個檔案,請嘗試以非 root UID 執行您的伺服器。出於安全原因(記憶體中可能殘留特權資訊),許多現代核心不允許程序在執行 setuid()
之後傾印核心(除非它執行 exec()
)。如有必要,您可以手動執行 /path/to/httpd -X
以強制 Apache 不進行分岔。gdb /path/to/httpd /tmp/httpd.core
或類似的命令。在 GDB 中,您要做的就是輸入 bt
,然後您就會看到回溯追蹤。對於其他除錯器,請參閱您的本地除錯器手冊。