Tomcat 对于典型用途来说足够安全,没有已知的安全漏洞或弱点。然而,互联网是一个疯狂的地方。这些是强化 Tomcat 的最佳实践。
1.工具
2. 简介
3. 先决条件
4. 以非特权用户身份运行 Tomcat
4.1 Unix/Linux
4.2 窗户
5. 限制对关键文件的访问
6.使用防火墙
7. 删除默认的 Tomcat 应用程序
8.更改默认索引页面
9. 从 HTTP 错误消息中删除版本字符串
10.替换默认错误页面
11.替换默认server.xml
12.替换服务器版本字符串
13. 将Tomcat的关闭程序置于锁定状态
14.保护关机端口
15、尽量使用最新稳定版的Tomcat
16. 维护和使用日志
17. 保护 Manager WebApp
18. 使用安全管理器运行 Tomcat
19. 强制 HTTPS
20. 结论
在此示例中,我们将说明强化 Apache Tomcat 安装的最佳实践。
默认情况下,Tomcat 在端口 8080 上运行,因此不需要 root 运行。重要的是不要以 root 身份运行。创建一个特殊用户,例如名为“tomcat”,它拥有 ${tomcat_home} 下的所有内容,并更改为该用户以运行 Tomcat。这个特殊用户将需要对 ${tomcat_home} 及其子目录的读/写权限,以及对您的数据目录的读权限。不要授予 tomcat 用户在任何其他目录中的任何权限。如果您的操作系统允许(例如 Unix、Linux),您也可能不允许 tomcat 用户登录,而是要求您以自己的身份登录,然后切换到 tomcat 用户。
这条建议适用于大多数 Web 服务器平台。与 Web 相关的服务不应由具有高级管理访问权限的用户帐户运行。在 Tomcat 的情况下,应专门创建具有最低必要操作系统权限的用户来运行 Tomcat 进程。
创建一个Tomcat用户:
创建 Tomcat 用户
1
|
sudo adduser tomcat
|
下载并解压核心发行版。
解压Tomcat
1
2
3
|
sudo cp apache-tomcat-8.0.33. tar .gz /opt
cd /opt
sudo tar zxvf apache-tomcat-8.0.33. tar .gz
|
将 tomcat 文件夹所有权更改为 tomcat 用户和 tomcat 组。
更改所有权
1
|
sudo chown -R tomcat:tomcat /opt/apache-tomcat-8 .0.33
|
以特定用户身份运行 Tomcat:
运行Tomcat
1
|
sudo -u tomcat /opt/apache-tomcat-8 .0.33 /bin/catalina .sh run
|
创建一个非特权帐户(如果您的主机是 Active Directory 的一部分,则可能已经有服务用户的模板)。用户应具有分配给它的“作为服务登录”权限。
确保将 Apache Tomcat 服务设置为以该用户身份运行。
确保 /opt/apache-tomcat-8.0.33/conf/ 下的所有内容都只能由 tomcat 用户读取。通常,您还会为 tomcat 用户提供写访问权限。
Tomcat 安装目录(有时称为 CATALINA_HOME)应该以不同于运行它的用户身份安装。
在 Linux 下,以 root 身份解压 Tomcat 发行版是执行此操作的最简单方法。
不幸的是,Tomcat 确实需要对分发目录中的某些目录进行写访问,但它们应该仅在需要时启用。
除非您在专用网络上,否则您需要防火墙。防火墙限制允许谁访问网络端口。进行默认设置以禁止所有访问,然后仅启用需要的访问。
端口 8080 应该具有不受限制的访问权限。如果您允许远程管理,您还必须打开端口 8443。Tomcat 还使用端口 8005 来启用关闭。但是,shutdown 只能在运行 Tomcat 的同一台机器上运行。只要不受信任的用户不在您的服务器计算机上运行,您就不必担心此端口是否打开。
但是,您可能希望限制对它的公共访问,以免黑客受到诱惑。如果您还使用 Tomcat 与其他 Web 服务器(如 Apache)一起处理 servlet/JSP 请求,则需要允许该服务器访问端口 8009,但通常可以限制在同一台机器上或至少在您的子网上访问. 如果您在独立版本中运行 Tomcat,则在 ${tomcat_home}/conf/server.xml 中禁用端口 8009。
删除默认的 webapps:
从 CATALINA_HOME/webapps 中删除所有内容(ROOT、balancer、jsp-examples、servlet-examples、tomcat-docs、webdav)。
从 CATALINA_HOME/server/webapps (host-manager, manager) 中删除所有内容。请注意,如果您需要在不重新启动 Tomcat 的情况下重新部署,则保持安装管理器 webapp 会很有用。如果您选择保留它,请阅读有关保护 Manager WebApp 的部分。
删除 CATALINA_HOME/conf/Catalina/localhost/host-manager.xml 和 CATALINA_HOME/conf/Catalina/localhost/manager.xml(同样,如果您要保留管理器应用程序,请不要删除它)。
Tomcat 附带了几个默认的 Web 应用程序,可以在 ${tomcat_home}/webapps 目录中找到。这些默认值取决于 Tomcat 的版本和您使用的安装程序。
ROOT 应用程序包含服务器的主页。将提供您在 ${tomcat_home}/webapps/ROOT 下添加的任何文件。admin 和 manager 应用程序用于远程管理。要使用这些应用程序,您必须添加具有 admin 和 manager 角色的用户。然后可以从主页访问应用程序,并可用于添加更多用户、启动和停止 webapps 等。您应该通过编辑文件 admin.xml 和 manager.xml 来限制允许运行这些应用程序的 IP 地址在 ${tomcat_home}/conf/Catalina/localhost/ 目录中。
应该从生产服务器中删除 servlets-examples 和 jsp-examples,以最大限度地减少安全风险。您可以从管理器应用程序或通过从 ${tomcat_home}/webapps 中删除这些目录来执行此操作。tomcat-docs、balancer 和 webdav 应用程序可能是无害的,但如果您愿意,也可以将其删除。
大多数 Web 服务器平台还提供一组示例或一个测试 Web 应用程序,用于演示和学习目的。已知这些应用程序存在漏洞,如果不使用,应将其删除。应删除 Tomcat 的示例 Web 应用程序以防止被利用。
确保默认 servlet 配置为在没有欢迎文件时不提供索引页面。在 CATALINA_HOME/conf/web.xml
索引页
01
02
03
04
05
06
07
08
09
10
11
12
13
|
< servlet >
< servlet-name >default servlet-name >
< servlet-class >org.apache.catalina.servlets.DefaultServlet servlet-class >
< init-param >
< param-name >debug param-name >
< param-value >0 param-value >
init-param >
< init-param >
< param-name >listings param-name >
< param-value >false param-value >
init-param >
< load-on-startup >1 load-on-startup >
servlet >
|
通过使用更新的 ServerInfo.properties 文件重新打包 CATALINA_HOME/server/lib/catalina.jar 从 HTTP 错误消息中删除版本字符串。
打开包装
1
2
|
cd CATALINA_HOME /server/lib
jar xf catalina.jar org /apache/catalina/util/ServerInfo .properties
|
通过将 server.info 行更改为 server.info=Apache Tomcat 重新打包 catalina.jar 来更新 ServerInfo.properties
重新包装
1
|
jar uf catalina.jar org /apache/catalina/util/ServerInfo .properties
|
删除 CATALINA_HOME/server/lib/org(在提取 ServerInfo.properties 文件时创建)。
通过将以下内容添加到 CATALINA_HOME/conf/web.xml 中来替换默认错误页面(默认为 stacktrace)。默认错误页面显示一个完整的堆栈跟踪,其中泄露了敏感信息。将以下内容放在 web-app 标记中(在welcome-file-list 标记之后)。以下解决方案并不理想,因为它会产生一个空白页面,因为 Tomcat 找不到指定的文件,但至少可以达到预期的结果。配置良好的 Web 应用程序将覆盖 CATALINA_HOME/webapps/APP_NAME/WEB-INF/web.xml 中的此默认设置,因此不会导致问题。
错误页面
1
2
3
4
|
< error-page >
< exception-type >java.lang.Throwable exception-type >
< location >/error.jsp location >
error-page >
|
将 CATALINA_HOME/conf/server.xml 重命名为 CATALINA_HOME/conf/server-original.xml 并将 CATALINA_HOME/conf/server-minimal.xml 重命名为 CATALINA_HOME/conf/server.xml。最小配置提供相同的基本配置,但没有嵌套注释更容易维护和理解。请勿删除原始文件,因为如果您需要进行更改,注释会为您提供参考——例如启用 SSL。
通过在 CATALINA_HOME/conf/server.xml 中的连接器中添加 server 关键字,替换服务器响应中 HTTP 标头中的服务器版本字符串。
版本字符串
1
2
3
4
|
< Connector port = "8080" protocol = "HTTP/1.1"
connectionTimeout = "20000"
redirectPort = "8443"
server = "Apache" />
|
这可以防止恶意行为者关闭 Tomcat 的 Web 服务。通过将 server.xml 文件中的端口属性设置为 -1 来禁用关闭端口。如果端口必须保持打开状态,请务必配置强密码以进行关机。
Tomcat 使用一个端口(默认为 8005)作为关闭端口。这意味着要停止所有 webapps 并停止 Tomcat,关闭脚本会干净地连接到该端口并发送关闭命令。考虑到必须从运行 tomcat 的机器上建立与端口的连接,并且关闭命令可以更改为字符串 SHUTDOWN 以外的其他内容,这并不像听起来那么严重的安全问题。但是,明智的做法是采取以下预防措施。
如果您正在运行可公开访问的服务器,请确保使用合适的防火墙防止外部访问关闭端口。更改 CATALINA_HOME/conf/server.xml 中的关闭命令,并确保该文件只能由 tomcat 用户读取。
关机端口
1
|
< Server port = "8005" shutdown = "ReallyComplexWord" >
|
由于 Tomcat 是一个活跃的开源项目,提高实例安全性的最简单方法是使您的版本保持最新并与 Tomcat 邮件列表保持同步。每个版本都添加了新的错误修复和安全补丁,并且可能适用于您的基础架构的新问题在 Tomcat 邮件列表中进行了讨论。Apache 还通过 Tomcat Announce 邮件列表通知社区成员主要的安全威胁和补丁。始终尽快升级到 Tomcat 的最新稳定版本。
维护良好的访问日志是识别安全漏洞和攻击源的重要工具。在开发环境中,您应该防御哪些类型的恶意活动并不总是很明显。在投入生产后维护日志将有助于确保在开发中看起来安全的应用程序在现实世界中保持安全。
日志应该在多个级别上维护——用户访问、应用程序流量、Tomcat 内部和操作系统/防火墙,并且所有系统管理员都应该同意一个用于审查和处理日志的单一过程。
要在 Tomcat 中启用网络流量记录,请使用 AccessLogValve 组件。该元素可以在主机、引擎或上下文的基础上进行配置,它将创建一个标准的 Web 服务器日志文件,用于与与其关联的任何资源的流量。Access Log Valve 支持多种属性来控制 Valve 的输出。
从 tomcat 5.5 开始,日志现在由 commons-logging 框架处理,允许您选择您喜欢的日志实现——log4j 或标准 JDK 日志。默认情况下,使用标准的 JDK 日志记录(或者更准确地说是名为 juli 的兼容扩展),将每日日志文件存储在 CATALINA_HOME/logs 中。
默认情况下,额外的 webapp 日志条目被添加到 CATALINA_HOME/logs/catalina.YYYY-MM-DD.log 并且 System.out/System.err 被重定向到 CATALINA_HOME/logs/catalina.out。要将 webapp 日志条目放在单独的日志文件中,请在 CATALINA_HOME/webapps/APP_NAME/WEB-INF/classes 中创建一个类似于以下内容的 logging.properties 文件(更改 APP_NAME 值以为每个 webapp 创建一个唯一文件)。
日志
1
2
3
4
|
handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
org.apache.juli.FileHandler.level = ALL
org.apache.juli.FileHandler.directory = ${catalina.base} /logs
org.apache.juli.FileHandler.prefix = APP_NAME.
|
如果您发现 catalina.out 中的日志输出重复,则很可能在日志配置文件中有 java.util.logging.ConsoleHandler 的不必要条目。
默认情况下,没有具有管理员角色的用户。要使用管理器 webapp,您需要将新角色和用户添加到 CATALINA_HOME/conf/tomcat-users.xml 文件中。
密码
1
2
|
< role rolename = "manager" />
< user username = "user" password = "ReallyComplexPassword" roles = "manager" />
|
当您访问受密码保护的管理器 web 应用程序时,您输入的密码将通过网络以(几乎)纯文本的形式发送,很容易被拦截。通过使用 SSL 连接,您可以安全地传输密码。幸运的是,这并不难实现。在 server.xml 中配置 SSL 连接器后,只需将以下内容添加到 CATALINA_HOME/webapps/manager/WEB-INF/web.xml。
安全约束
1
2
3
4
5
|
< security-constraint >
< user-data-constraint >
< transport-guarantee >CONFIDENTIAL transport-guarantee >
user-data-constraint >
security-constraint >
|
默认的 Tomcat 配置为大多数需求提供了良好的保护,但不能防止恶意应用程序损害在同一实例中运行的其他应用程序的安全性。为了防止这种攻击,Tomcat 可以在启用安全管理器的情况下运行,该安全管理器严格控制对服务器资源的访问。Tomcat 文档中有一个关于启用安全管理器的很好的部分。
使用“-security”参数启动tomcat 总是一个好主意。这确保(除其他外)Web 应用程序无法读取/写入/执行本地文件系统上的任何文件,除非在 catalina.policy 文件中启用它。
对 Tomcat 中的所有事务强制使用 HTTPS 是一个多步骤过程。必须配置 HTTPS 连接器,HTTP 连接器必须重定向到 HTTPS,并且 Web 应用程序的部署描述符必须将 HTTPS 指定为默认协议。
请参阅下面的常见 HTTPS 配置:
HTTPS
1
2
3
4
5
6
7
|
< Connector port = "8443" protocol = "HTTP/1.1" SSLEnabled = "true"
maxThreads = "450" scheme = "https" secure = "true"
clientAuth = "false" sslProtocol="TLS”
keystoreFile = "conf/keystore" keystorePass = "secure-pass"
proxyHost = "192.568.23.21" proxyPort = "443"
URIEncoding = "UTF-8"
maxHttpHeaderSize = "32768" />
|
Apache Tomcat 的流行总是意味着它的漏洞和漏洞被安全专业人员和恶意行为者所熟知。开箱即用的安全性永远不足以抵御当今的网络威胁,鉴于服务器平台无处不在,对 Tomcat 进行适当的强化尤为重要。