前言
整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本爲 v11 最新的版本。
開源項目
從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。
系列文章
web server apache tomcat11-01-官方文檔入門介紹
web server apache tomcat11-02-setup 啓動
web server apache tomcat11-03-deploy 如何部署
web server apache tomcat11-04-manager 如何管理?
web server apache tomcat11-06-Host Manager App -- Text Interface
web server apache tomcat11-07-Realm Configuration
web server apache tomcat11-08-JNDI Resources
web server apache tomcat11-09-JNDI Datasource
web server apache tomcat11-10-Class Loader
...
快速開始
下面的描述使用變量名 $CATALINA_BASE
來引用大多數相對路徑解析的基本目錄。如果您尚未通過設置 CATALINA_BASE
目錄來爲 Tomcat 配置多個實例,則 $CATALINA_BASE
將設置爲 $CATALINA_HOME
的值,即您安裝 Tomcat 的目錄。
要在 Tomcat 上安裝和配置 SSL/TLS 支持,您需要遵循以下簡單步驟。有關更多信息,請閱讀本指南的其餘部分。
創建密鑰庫文件
執行以下命令創建用於存儲服務器的私鑰和自簽名證書的密鑰庫文件:
Windows:
"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
並指定密碼值爲 "changeit"。
修改配置文件
取消註釋 $CATALINA_BASE/conf/server.xml
中的 "SSL HTTP/1.1 Connector" 條目,並按照下面的配置部分所述進行修改。
SSL/TLS 簡介
傳輸層安全性(TLS)及其前身安全套接字層(SSL)是使 Web 瀏覽器和 Web 服務器能夠通過安全連接進行通信的技術。這意味着發送的數據由一方加密,然後傳輸,然後由另一方在處理之前解密。這是一個雙向過程,這意味着服務器和瀏覽器都會在發送數據之前對所有流量進行加密。
SSL/TLS 協議的另一個重要方面是認證。這意味着在您首次嘗試通過安全連接與 Web 服務器通信時,該服務器將向您的 Web 瀏覽器提供一組憑據,以證明該站點是誰以及它聲稱的內容。在某些情況下,服務器還可能要求您的 Web 瀏覽器提供證書,以證明您是您所聲稱的人。這稱爲 "客戶端認證",儘管在實踐中,這更多用於業務對業務(B2B)交易而不是與個人用戶。大多數啓用 SSL 的 Web 服務器不會請求客戶端認證。
證書
爲了實施 SSL,Web 服務器必須爲接受安全連接的每個外部接口(IP 地址)準備一個相關聯的證書。這個設計背後的理論是服務器應該提供某種合理的保證,證明其所有者是您認爲的那個人,特別是在接收任何敏感信息之前。雖然證書的廣泛解釋超出了本文檔的範圍,但將證書視爲一個 Internet 地址的 "數字護照"。它說明了該站點與哪個組織相關聯,以及關於站點所有者或管理員的一些基本聯繫信息。
這個證書由其所有者以密碼形式簽名,因此其他人很難僞造。爲了使證書在訪客的瀏覽器中無警告地工作,它需要由受信任的第三方簽名。這些被稱爲證書頒發機構(CA)。要獲得簽名的證書,您需要選擇一個 CA,並按照您選擇的 CA 提供的說明來獲取您的證書。有各種各樣的 CA 可供選擇,包括一些免費提供證書的 CA。
Java 提供了一個相對簡單的命令行工具,稱爲 keytool,可以輕鬆創建 "自簽名" 證書。自簽名證書只是用戶生成的未經 well-known CA 簽名的證書,因此不真正保證是真實的。雖然自簽名證書可能對某些測試場景有用,但對於任何形式的生產使用都不合適。
運行 SSL 的一般提示
在使用 SSL 保護網站時,重要的是確保網站使用的所有資源都通過 SSL 提供,以防止攻擊者通過在 JavaScript 文件中注入惡意內容等方式繞過安全性。爲了進一步增強網站的安全性,您應該考慮使用 HSTS 標頭。它允許您向瀏覽器通信,指示您的站點應始終通過 https 訪問。
在安全連接上使用基於名稱的虛擬主機需要謹慎配置單個證書中指定的名稱,或者在支持 Server Name Indication(SNI)的 Tomcat 8.5 及更高版本中,其中可用。SNI 允許將具有不同名稱的多個證書關聯到單個 TLS 連接器。
配置
準備證書密鑰庫
Tomcat 目前僅支持 JKS、
PKCS11 或 PKCS12 格式的密鑰庫。JKS 格式是 Java 的標準 "Java KeyStore" 格式,是 keytool 命令行實用程序創建的格式。此工具包含在 JDK 中。PKCS12 格式是一種互聯網標準,可以通過 OpenSSL 和 Microsoft 的 Key-Manager 等方式進行操作。
密鑰庫中的每個條目都由別名字符串標識。雖然許多密鑰庫實現以不區分大小寫的方式處理別名,但也可用區分大小寫的實現。例如,PKCS11 規範要求別名區分大小寫。爲了避免與別名的大小寫敏感性相關的問題,不建議使用僅在大小寫方面有所不同的別名。要導入現有證書到 JKS 密鑰庫,請閱讀(在您的 JDK 文檔包中)有關 keytool 的文檔。請注意,OpenSSL 通常會在密鑰之前添加可讀的註釋,但 keytool 不支持。因此,如果您的證書在密鑰數據之前有註釋,請在使用 keytool 導入證書之前將其刪除。
要使用 OpenSSL 將現有 CA 簽名的證書導入 PKCS12 密鑰庫,您可以執行類似於以下命令:
openssl pkcs12 -export -in mycert.crt -inkey mykey.key
-out mycert.p12 -name tomcat -CAfile myCA.crt
-caname root -chain
對於更高級的情況,請參閱 OpenSSL 文檔。
要從頭開始創建一個新的 JKS 密鑰庫,其中包含一個單獨的自簽名證書,請從終端命令行執行以下操作:
Windows:
"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
(RSA 算法應優先選擇作爲安全算法,這還確保與其他服務器和組件的一般兼容性。)
此命令將在您運行它的用戶的主目錄中創建一個名爲 .keystore
的新文件。要指定不同的位置或文件名,請將 -keystore
參數添加到上面顯示的 keytool 命令,後面跟上到您密鑰庫文件的完整路徑名。您還需要在後面描述的 server.xml
配置文件中反映這個新位置。例如:
Windows:
"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
-keystore \path\to\my\keystore
Unix:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
-keystore /path/to/my/keystore
執行此命令後,您首先會提示輸入密鑰庫密碼。Tomcat 使用的默認密碼是 "changeit"(全部小寫),儘管您可以指定自定義密碼。您還需要在後面描述的 server.xml
配置文件中指定自定義密碼。
接下來,您將提示提供有關此證書的一般信息,例如公司、聯繫人姓名等。將顯示此信息以便嘗試訪問您應用程序中的安全頁面的用戶,請確保此處提供的信息與他們預期的相匹配。
最後,您將被提示輸入密鑰密碼,這是專門爲此證書(而不是存儲在同一密鑰庫文件中的任何其他證書)的密碼。keytool 提示將告訴您,按 ENTER 鍵會自動使用與密鑰庫相同的密碼來使用密鑰。您可以自由選擇相同的密碼或選擇自定義密碼。如果您選擇與密鑰庫密碼不同的密碼,則還需要在後面描述的 server.xml
配置文件中指定自定義密碼。
如果一切順利,現在您有一個帶有證書的密鑰庫文件,該證書可供您的服務器使用。
編輯 Tomcat 配置文件
Tomcat 可以使用兩種不同的 SSL 實現:
- 作爲 Java 運行時的一部分提供的 JSSE 實現
- 使用 OpenSSL 的 JSSE 實現
確切的配置細節取決於使用的是哪種實現。如果通過指定通用 protocol="HTTP/1.1"
配置連接器,則 Tomcat 使用的實現將自動選擇。
如果需要,可以通過在連接器的 protocol
屬性中指定類名來避免自動選擇實現。
要定義 Java(JSSE)連接器,無論 APR 庫是否已加載,請使用以下之一:
<!-- 在端口 8443 上定義 HTTP/1.1 連接器,JSSE NIO 實現 -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
port="8443" .../>
<!-- 在端口 8443 上定義 HTTP/1.1 連接器,JSSE NIO2 實現 -->
<Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation"
port="8443" .../>
如果需要,也可以顯式配置 OpenSSL JSSE 實現。如果安裝了 Tomcat Native 庫或 Java 22,則使用 sslImplementationName
屬性可以啓用它。當使用 OpenSSL JSSE 實現時,配置可以使用 JSSE 屬性或 OpenSSL 屬性,但不得在相同的 SSLHostConfig
或 Connector
元素中混合使用來自兩種類型的屬性。
使用 Tomcat Native:
<!-- 在端口 8443 上定義 HTTP/1.1 連接器,JSSE NIO 實現和 OpenSSL -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443"
sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"
.../>
使用 Java 22 FFM API:
<!-- 在
端口 8443 上定義 HTTP/1.1 連接器,JSSE NIO 實現和 OpenSSL -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443"
sslImplementationName="org.apache.tomcat.util.net.openssl.panama.OpenSSLImplementation"
.../>
或者,可以向服務器添加偵聽器以在不必在每個 SSLHostConfig 或 Connector 元素上添加 sslImplementationName
屬性的情況下在所有連接器上啓用 OpenSSL。
使用 Tomcat Native:
<Listener className="org.apache.catalina.core.AprLifecycleListener"/>
使用 Java 22 FFM API:
<Listener className="org.apache.catalina.core.OpenSSLLifecycleListener"/>
偵聽器的 SSLRandomSeed
屬性允許指定一個熵源。生產系統需要可靠的熵源,但熵可能需要大量時間才能收集,因此測試系統可以使用無阻塞熵源,如 "/dev/urandom",這將允許 Tomcat 更快地啓動。
最後一步是在 $CATALINA_BASE/conf/server.xml
文件中配置連接器,其中 $CATALINA_BASE
表示 Tomcat 實例的基目錄。默認的 server.xml
文件中包含了一個 SSL 連接器的示例 <Connector>
元素。要配置使用 JSSE 並且使用 JSSE 配置樣式的 SSL 連接器,您需要刪除註釋並編輯它,使其看起來像這樣:
<!-- 在端口 8443 上定義一個 SSL Coyote HTTP/1.1 連接器 -->
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443"
maxThreads="150"
SSLEnabled="true">
<SSLHostConfig>
<Certificate
certificateKeystoreFile="${user.home}/.keystore"
certificateKeystorePassword="changeit"
type="RSA"
/>
</SSLHostConfig>
</Connector>
OpenSSL 配置樣式使用許多 SSL 設置的不同屬性,特別是密鑰和證書。APR 配置樣式的示例是:
<!-- 在端口 8443 上定義一個 SSL Coyote HTTP/1.1 連接器 -->
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443"
maxThreads="150"
SSLEnabled="true" >
<SSLHostConfig>
<Certificate
certificateKeyFile="conf/localhost-rsa-key.pem"
certificateFile="conf/localhost-rsa-cert.pem"
certificateChainFile="conf/localhost-rsa-chain.pem"
type="RSA"
/>
</SSLHostConfig>
</Connector>
配置選項和關於哪些屬性是強制的信息,都記錄在 HTTP 連接器配置參考的 SSL 支持部分中。Tomcat 使用所有 TLS 連接器支持任一配置樣式(JSSE 或 OpenSSL)。
port
屬性是 Tomcat 將偵聽安全連接的 TCP/IP 端口號。您可以將其更改爲任何您希望的端口號(例如,默認的 https 通信端口 443)。但是,在許多操作系統上運行 Tomcat 的端口號低於 1024 需要特殊設置(超出了本文檔的範圍)。
如果在這裏更改了端口號,則還應更改非 SSL 連接器上指定的 redirectPort
屬性的值。這允許 Tomcat 自動重定向試圖訪問具有指定了 SSL 爲必需的安全約束的頁面的用戶,如 Servlet 規範所要求的那樣。
完成這些配置更改後,您必須像平常一樣重新啓動 Tomcat,然後您應該可以運行了。您應該能夠通過 SSL 訪問 Tomcat 支持的任何 Web 應用程序。例如,請嘗試:
https://localhost:8443/
您應該看到通常的 Tomcat 啓動頁面(除非您已修改了 ROOT Web 應用程序)。如果這不起作用,請參閱以下部分中的一些故障排除提示。
安裝來自證書頒發機構的證書
要獲取並安裝來自證書頒發機構(如 verisign.com、thawte.com 或 trustcenter.de)的證書,請閱讀上一節,然後按照以下說明操作:
創建本地證書籤名請求(CSR)
爲了從您選擇的證書頒發機構那裏獲得證書,您必須創建一個名爲證書籤名請求(CSR)的請求。該 CSR 將由證書頒發機構用於創建將您的網站標識爲 "安全" 的證書。要創建 CSR,請執行以下步驟:
- 創建本地自簽名證書(如上一節中所述):
keytool -genkey -alias tomcat -keyalg RSA
-keystore <your_keystore_filename>
(在某些情況下,您必須在 "姓" 字段中輸入您網站的域名(即 www.myside.org),以便創建可用的證書。)
然後使用以下命令創建 CSR:
keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr
-keystore <your_keystore_filename>
現在您有一個名爲 certreq.csr 的文件,您可以將其提交給證書頒發機構(查看證書頒發機構網站上關於如何執行此操作的文檔)。
機構將使用此 CSR 創建您的證書。
從證書頒發機構獲得證書
在收到您的 CSR 後,證書頒發機構將向您發送一個文件(通常以 PEM 格式),其中包含您的新證書。
安裝證書
一旦您從證書頒發機構那裏收到了新的證書文件,您可以將其添加到您的密鑰庫文件中。首先,請將文件轉換爲與密鑰庫兼容的格式,然後再將其添加到密鑰庫中。這是一個示例命令序列,假設您收到的文件是以 PEM 格式編寫的。
要將 PEM 文件轉換爲 PKCS12 文件,請執行以下操作:
openssl pkcs12 -export -in cert.pem -out cert.p12 -name tomcat
然後將 PKCS12 文件導入到您的密鑰庫中:
keytool -importkeystore -deststorepass <your_keystore_password>
-destkeypass <your_keystore_password>
-destkeystore <your_keystore_filename> -srckeystore cert.p12
-srcstoretype PKCS12 -srcstorepass <password_used_when_creating_pkcs12> -alias tomcat
現在,您的密鑰庫中應該包含來自證書頒發機構的證書。現在可以在 Tomcat 配置文件中使用該密鑰庫(如上所示)。
最後的步驟
安裝證書後,請確保您的用戶將 $CATALINA_BASE/conf/server.xml
文件和您的密鑰庫文件保持安全。私鑰庫文件中的私鑰和密鑰庫密碼都是敏感信息,不應與他人共享。
完成所有配置更改後,必須重新啓動 Tomcat 服務器才能使更改生效。您應該能夠通過安全的 HTTPS 連接訪問您的 Tomcat 服務器了。