對于大多數(shù)用例來說,默認配置下的 Tomcat 都是相當安全的。有些環(huán)境可能需要更多(或更少)的安全配置。本文統(tǒng)一介紹了一下可能影響安全性的配置選項,并適當說明了一下修改這些選項所帶來的預(yù)期影響。目的是為了在評價 Tomcat 安裝時,提供一些應(yīng)值得考慮的配置選項。
注意:本章內(nèi)容畢竟有所局限,你還需要對配置文檔進行深入研究。在相關(guān)文檔中有更完整的屬性描述。
Tomcat 配置不應(yīng)成為唯一的防線,也應(yīng)該保障系統(tǒng)(操作系統(tǒng)、網(wǎng)絡(luò)及數(shù)據(jù)庫,等等)中的其他組件的安全。
不應(yīng)該以根用戶的身份來運行 Tomcat,應(yīng)為 Tomcat 進程創(chuàng)建并分配一個專門的用戶,并為該用戶配置最少且必要的操作系統(tǒng)權(quán)限。比如,不允許使用 Tomcat 用戶實現(xiàn)遠程登錄。
文件權(quán)限同樣也應(yīng)適當限制。就拿 ASF 中的 Tomcat 實例為例說明吧(禁止自動部署,Web 應(yīng)用被部署為擴張的目錄。),標準配置規(guī)定所有的 Tomcat 文件都由根用戶及分組用戶所擁有,擁有者具有讀寫特權(quán),分組只有讀取特權(quán),而 World 則沒有任何特權(quán)。例外之處在于,logs、temp 以及 work 目錄的權(quán)限都由 Tomcat 用戶而不是根用戶所擁有。這意味著即使攻擊者破壞了 Tomcat 進程,他們也不能改變 Tomcat 配置,無法部署新應(yīng)用,也無法修改現(xiàn)有應(yīng)用。Tomcat 進程使用掩碼 007 來維護這種權(quán)限許可。
對于網(wǎng)絡(luò)層面,需要使用防火墻來限制進站與出站連接,只允許出現(xiàn)那些你希望的連接。
Tomcat 安裝時自帶了一些默認啟用的 Web 應(yīng)用。過去一段時間內(nèi)發(fā)現(xiàn)了不少關(guān)于這些應(yīng)用的漏洞。用不到的應(yīng)用就該刪除,以避免給系統(tǒng)帶來相關(guān)漏洞而產(chǎn)生的安全風險。
ROOT 應(yīng)用帶來安全風險的可能性非常小,但它確實含有正在使用的 Tomcat 的版本號。應(yīng)該從可公開訪問的 Tomcat 實例中清除 ROOT 應(yīng)用,不是出于安全性原因,而是因為這樣能給用戶提供一個更適合的默認頁面。
Documentation 帶來安全風險的可能性非常小,但》它標識出了當前正使用的 Tomcat 版本。應(yīng)該從可公開訪問的 Tomcat 實例中清除該應(yīng)用。
應(yīng)該從安全敏感性安裝中移除 examples 應(yīng)用。雖然 examples 應(yīng)用并不包含任何已知的漏洞,但現(xiàn)已證明,它所包含的一些功能可以被攻擊者利用,特別是一些顯示所有接收內(nèi)容,并且能設(shè)置新 cookie 的 cookie 范例。攻擊者將這些公關(guān)和部署在 Tomcat 實例中的另一個應(yīng)用中的漏洞相結(jié)合,就能獲取原本根本不可能得到的信息。
由于 Manager 應(yīng)用允許遠程部署 Web 應(yīng)用,所以經(jīng)常被攻擊者利用,因為應(yīng)用的密碼普遍強度不夠,而且大多在 Manager 應(yīng)用中啟用了 Tomcat 實例可公開訪問的功能。Manager 應(yīng)用默認是不能訪問的,因為沒有配置能夠執(zhí)行這種訪問的用戶。如果啟用 Manager 應(yīng)用,就應(yīng)該遵循 保證管理型應(yīng)用的安全性 一節(jié)中的指導(dǎo)原則。
Host Manager 應(yīng)用能夠創(chuàng)建并管理虛擬主機,包括啟用虛擬主機的 Manager 應(yīng)用。Host Manager 應(yīng)用默認是不能訪問的,因為沒有配置能夠執(zhí)行這種訪問的用戶。如果啟用 Host Manager 應(yīng)用,就應(yīng)該遵循 保證管理型應(yīng)用的安全性 一節(jié)中的指導(dǎo)原則。
在配置能夠為 Tomcat 實例提供管理功能的 Web 應(yīng)用時,需要遵循下列指導(dǎo)原則:
/META-INF/context.xml
中的限制訪問 localhost 的RemoteAddrValve 取消注釋。如果需要遠程訪問,使用該值可限制到特定的 IP 地址。啟用安全管理器能讓 Web 應(yīng)用運行在沙盒中,從而極大限制 Web 應(yīng)用執(zhí)行惡意行為的能力——比如調(diào)用 System.exit()
,在 Web 應(yīng)用根目錄或臨時目錄外建立網(wǎng)絡(luò)連接或訪問文件系統(tǒng)。但應(yīng)注意的是,有些惡意行為是安全管理器所無法阻止的,比如利用無限循環(huán)產(chǎn)生 CPU 極大開銷。
啟用安全管理器經(jīng)常用來限制潛在影響,比如防止攻擊者通過某種方式危害受信任的 Web 應(yīng)用。安全管理器也可能被用來減少運行不受信任的 Web 應(yīng)用(比如在托管環(huán)境中)所帶來的風險,但它只能減少這種風險,并不能終止不受信任的 Web 應(yīng)用。如果運行多個不受信任的 Web 應(yīng)用,強烈建議將每個應(yīng)用都部署為獨立的 Tomcat 實例(理想情況下還需要部署在獨立的主機上),以便盡量減少惡意 Web 應(yīng)用對其他應(yīng)用產(chǎn)生的危害。
Tomcat 已經(jīng)過安全管理器的測試。但大多數(shù) Tomcat 用戶卻沒有運行過安全管理器,所以 Tomcat 也沒有相關(guān)的用戶測試過的配置。現(xiàn)在已經(jīng)(并會繼續(xù))報告指出了一些關(guān)于運行安全管理器時產(chǎn)生的 Bug。
安全管理器在運行時所暴露出的限制可能在于中斷很多應(yīng)用。所以,在未經(jīng)大量測試前,還是不要使用它為好。理想情況下,安全管理器應(yīng)該在開發(fā)前期使用,因為對于一個成熟的應(yīng)用來說,啟用安全管理器后,記錄修補問題會極大浪費時間。
啟用安全管理器會改變下列設(shè)置的默認值:
deployXML
屬性默認值會被改為 false
。默認的 server.xml 包含大量注釋,比如一些被注釋掉的范例組件定義。去掉這些注釋將會使其更容易閱讀和理解。
如果某個組件類型沒有列出,那么該類型也沒有能夠直接影響安全的相關(guān)設(shè)置。
將 port
屬性設(shè)為 -1
能禁用關(guān)閉端口。
如果關(guān)閉端口未被禁用,會為 shutdown 配置一個強密碼。
如果在 Solaris 上使用 gcc 編譯 APR 生命周期偵聽器,你會發(fā)現(xiàn) APR 生命周期偵聽器并不穩(wěn)定。如果在 Solaris 上使用 APR(或原生)連接器,需要用 Sun Studio 編譯器進行編譯。
應(yīng)該啟用并恰當?shù)嘏渲?Security 偵聽器。
默認配置了一個 HTTP 和 AJP 連接器。沒有用到的連接器應(yīng)從 server.xml 中清除掉。
address
屬性用來控制連接器在哪個 IP 地址上偵聽連接。默認,連接器會在所有配置好的 IP 地址上進行偵聽。
allowTrace
屬性可啟用能夠利于調(diào)試的 TRACE 請求。由于一些瀏覽器處理 TRACE 請求的方式(將瀏覽器暴露給 XSS 攻擊),所以默認是不支持 TRACE 請求的。
maxPostSize
屬性控制解析參數(shù)的 POST 請求的最大尺寸。在整個請求期間,參數(shù)會被緩存,所以該值默認會被限制到 2 MB大小,以減少 DOS 攻擊的風險。
maxSavePostSize
屬性控制在 FORM 和 CLIENT-CERT 驗證期間,saving of POST requests。在整個驗證期間(可能會占用好幾分鐘),參數(shù)會被緩存,所以該值默認會被限制到 4 KB大小,以減少 DOS 攻擊的風險。
maxParameterCount
屬性控制可解析并存入請求的參數(shù)與值對(GET + POST)的最大數(shù)量。過多的參數(shù)將被忽略。如果想拒絕這樣的請求,配置FailedRequestFilter。
xpoweredBy
屬性控制是否 X-Powered-By HTTP 報頭會隨每一個請求發(fā)送。如果發(fā)送,則該報頭值包含 Servlet 和 JSP 規(guī)范版本號、完整的 Tomcat 版本號(比如 Apache Tomcat/8.0)、JVM Vendor 名稱,以及 JVM 版本號。默認禁用該報頭。該報頭可以為合法用戶和攻擊者提供有用信息。
server
屬性控制 Server HTTP 報頭值。對于 Tomcat 4.1.x 到 8.0.x,該報頭默認值為 Apache-Coyote/1.1。該報頭為合法用戶和攻擊者提供的有用信息是有限的。
SSLEnabled
、scheme
和 secure
這三個屬性可以各自獨立設(shè)置。這些屬性通常應(yīng)用場景為:當 Tomcat 位于反向代理后面,并且該代理通過 HTTP 或 HTTPS 連接 Tomcat 時。通過這些屬性,可查看客戶端與代理間(而不是代理與 Tomcat之間)連接的 SSL 屬性。例如,客戶端可能通過 HTTPS 連接代理,但代理連接 Tomcat 卻是通過 HTTP。如果 Tomcat 有必要區(qū)分從代理處接收的安全與非安全連接,那么代理就必須使用單獨分開的連接,向
Tomcat 傳遞安全與非安全請求。如果代理使用 AJP,客戶端連接的 SSL 屬性會經(jīng)由 AJP 協(xié)議傳遞,那么就不需要使用單獨的連接。
sslEnabledProtocols
屬性用來確定所使用的 SSL/TLS 協(xié)議的版本。從 2014 年發(fā)生的 POODLE 攻擊起,SSL 協(xié)議被認為是不安全的,單獨 Tomcat 設(shè)置中該屬性的安全設(shè)置為 sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
。
ciphers
屬性控制 SSL 連接所使用的 cipher。默認使用 JVM 的缺省 cipher。這往往意味著,可用 cipher 列表將包含弱導(dǎo)出級 cipher。安全環(huán)境通常需要配置更受限的 cipher 集合。該屬性可以利用 OpenSSL 語法格式來包括/排除 cipher 套件。截止
2014 年 11 月 19 日,對于單獨 Tomcat 8 與 Java 8,可使用 sslEnabledProtocols
屬性,并且排除非 DH cipher,以及弱/失效 cipher 來指定 TLS 協(xié)議,從而實現(xiàn)正向加密(Forward Secrecy)技術(shù)。對于以上這些設(shè)定工作來說,Qualys SSL/TLS test是一個非常不錯的配置工具。
tomcatAuthentication
和 tomcatAuthorization
屬性都用于 AJP 連接,用于確定 Tomcat 是否應(yīng)該處理所有的認證和授權(quán),或者是否應(yīng)委托反向代理來認證(認證用戶名作為 AJP 協(xié)議的一部分被傳遞給 Tomcat),而讓 Tomcat 繼續(xù)執(zhí)行授權(quán)。
allowUnsafeLegacyRenegotiation
屬性提供對 CVE-2009-3555 漏洞(一種 TLS 中間人攻擊)的應(yīng)對方案,應(yīng)用于 BIO 連接器中。如果底層 SSL 實現(xiàn)易受 CVE-2009-3555 漏洞影響,才有必要使用該屬性。參看
Tomcat 8 安全文檔可詳細了解這種缺陷的當前狀態(tài)及其可使用的解決方案。
AJP 連接器中的 requiredSecret
屬性配置了 Tomcat 與 Tomcat 前面的反向代理之間的共享密鑰,從而防止通過 AJP 協(xié)議進行非授權(quán)連接。
Host 元素控制著部署。自動部署能讓管理更為輕松,但也讓攻擊者更容易部署惡意應(yīng)用。自動部署由 autoDeploy
和 deployOnStartup
屬性來控制。如果兩個屬性值為 false
,則 server.xml 中定義的上下文將會被部署,任何更改都將需要重啟 Tomcat 才能生效。
在 Web 應(yīng)用不受信任的托管環(huán)境中,將 deployXML
設(shè)置為 false
將忽略任何包裝 Web 應(yīng)用的 context.xml,可能會把增加特權(quán)賦予 Web 應(yīng)用。注意,如果啟用安全管理器,則 deployXML
屬性默認為 false
。
server.xml
、默認的 context.xml
文件,每個主機的 context.xml.default
文件、Web 應(yīng)用上下文文件
crossContext
屬性能夠控制是否允許上下文訪問其他上下文資源。默認為 false
,而且只應(yīng)該針對受信任的 Web 應(yīng)用。
privileged
屬性控制是否允許上下文使用容器提供的 servlet,比如 Manager servlet。默認為 false
,而且只針對受信任的 Web 應(yīng)用。
內(nèi)嵌 Resource 元素中的 allowLinking
屬性控制是否允許上下文使用鏈接文件。如果啟用而且上下文未經(jīng)部署,那么當刪除上下問資源時,也會一并將鏈接文件刪除。默認值為 false
。在大小寫敏感的操作系統(tǒng)上改變該值,將會禁用一些安全措施,并且允許直接訪問 WEB-INF 目錄。
強烈建議配置 AccessLogValve。默認的 Tomcat 配置包含一個 AccessLogValve。通常會對每個 Host 上進行配置,但必要時也可以在每個 Engine 或 Context 上進行配置。
應(yīng)通過 RemoteAddrValve 來保護管理應(yīng)用。注意:這個 Valve 也可以用作過濾器。allow 屬性用于限制對一些已知信任主機的訪問。
默認的 ErrorReportValve 在發(fā)送給客戶端的響應(yīng)中包含了 Tomcat 版本號。為了避免這一點,可以在每個 Web 應(yīng)用上配置自定義錯誤處理器。另一種方法是,可以配置 ErrorReportValve
,將其 showServerInfo
屬性設(shè)為 false
。另外,通過創(chuàng)建帶有下列內(nèi)容的
CATALINA_BASE/lib/org/apache/catalina/util/ServerInfo.properties 文件,可以改變版本號。
server.info=Apache Tomcat/8.0.x
根據(jù)需要來改變該值。注意,這也會改變一些管理工具所報告的版本號,可能難于確定實際安裝的版本號。CATALINA_HOME/bin/version.bat|sh
腳本依然能夠報告版本號。
當出現(xiàn)錯誤時,默認的 ErrorReportValve
能向客戶端顯示堆棧跟蹤信息以及/或者 JSP 源代碼。為了避免這一點,可以在每個 Web 應(yīng)用內(nèi)配置自定義錯誤處理器。另一種方法是,可以顯式配置一個 ErrorReportValve
,并將其 showReport
屬性設(shè)為 false
。
MemoryRealm 并不適用于生產(chǎn)用途,因為要想讓 Tomcat-users.xml 中的改動生效,就必須重啟 Tomcat。
JDBCRealm 也不建議用于生產(chǎn)環(huán)境,因為所有的認證和授權(quán)選項都占用一個線程??梢杂?DataSourceRealm 來替代它。
UserDatabaseRealm 不適合大規(guī)模安裝。它適合小規(guī)模且相對靜態(tài)的環(huán)境。
JAASRealm 使用并不廣泛,因此也不如其他幾個 Realm 成熟。在未進行大量測試之前,建議不采用這種 Realm。
默認,Realm 并不能實現(xiàn)賬戶鎖定。這就給暴力破解者帶來了方便。要想防范這一點,需要將 Realm 包裝在 LockOutRealm 中。
manager 組件用來生成會話 ID。
可以利用 randomClass
屬性來改變生成隨機會話 ID 的類。
可以利用 sessionIdLength
屬性來改變會話 ID 的長度。
將系統(tǒng)屬性 org.apache.catalina.connector.RECYCLE_FACADES
設(shè)為 true
,將為每一個請求創(chuàng)建一個新的門面(facade)對象,這能減少因為應(yīng)用 bug 而將一個請求中數(shù)據(jù)暴露給其他請求的風險。
系統(tǒng)屬性 org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH
和 org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH
允許對請求 URI 的非標準解析。使用這些選項,當處于反向代理后面時,攻擊者可以繞過由代理所強制設(shè)定的各種安全限制。
如果禁用系統(tǒng)屬性 org.apache.catalina.connector.Response.ENFORCE_ENCODING_IN_GET_WRITER
可以會帶來不利后果。許多違反 RFC2616 的用戶代理在應(yīng)該使用 ISO-8859-1 的規(guī)范強制默認值時,試圖猜測文本媒體類型的字符編碼。一些瀏覽器會解析為 UTF-7 編碼,這樣做的后果是:如果某一響應(yīng)包含的字符對 ISO-8859-1 是安全的,但如果解析為 UTF-7,卻能觸發(fā) XSS 漏洞。
如果Web 應(yīng)用中默認的 conf/web.xml
和 WEB-INF/web.xml
文件定義了本文提到的組件,》》
在配置 DefaultServlet 時,將 readonly
設(shè)為 true
。將其變?yōu)?false
能讓客戶端刪除或修改服務(wù)器上的靜態(tài)資源,進而上傳新的資源。由于不需要認證,故而通常也不需要改變。
將 DefaultServlet
的 listings
設(shè)為 false
。之所以這樣設(shè)置,不是因為允許目錄列表是不安全之舉,而是因為要對包含數(shù)千個文件的目錄生產(chǎn)目錄列表,會大量消耗計算資源,會容易導(dǎo)致 DOS 攻擊。
DefaultServlet
的 showServerInfo
設(shè)為 true
。當啟用目錄列表后,Tomcat 版本號就會包含在發(fā)送給客戶端的響應(yīng)中。為了避免這一點,可以將 DefaultServlet
的 showServerInfo
設(shè)為 false
。另一種方法是,另外,通過創(chuàng)建帶有下列內(nèi)容的 CATALINA_BASE/lib/org/apache/catalina/util/ServerInfo.properties
文件,可以改變版本號。
server.info=Apache Tomcat/8.0.x
根據(jù)需要來改變該值。注意,這也會改變一些管理工具所報告的版本號,可能難于確定實際安裝的版本號。CATALINA_HOME/bin/version.bat|sh
腳本依然能夠報告版本號。
可以設(shè)置 FailedRequestFilter
來拒絕那些請求參數(shù)解析時發(fā)生錯誤的請求。沒有過濾器,默認行為是忽略無效或過多的參數(shù)。
HttpHeaderSecurityFilter
可以為響應(yīng)添加報頭來提高安全性。如果客戶端直接訪問 Tomcat,你可能就需要啟用這個過濾器以及它所設(shè)定的所有報頭(除非應(yīng)用已經(jīng)設(shè)置過它們)。如果通過反向代理訪問 Tomcat,該過濾器的配置需要與反向代理所設(shè)置的任何報頭相協(xié)調(diào)。
BASIC 與 FORM 驗證會將用戶名及密碼存為明文。在不受信任的網(wǎng)絡(luò)情況下,使用這種認證機制的 Web 應(yīng)用和客戶端間的連接必須使用 SSL。
會話 cookie 加上已認證用戶,基本上就將用戶密碼擺在攻擊者面前了,無論何時給予跟密碼級別相同的保護。通常這就需要經(jīng)過 SSL 來認證,或者在整個會話期間都使用 SSL。
更多建議: