Tomcat
Tomcat 是由 Apache 软件基金会开发的开源 Java Servlet 容器。
安装
安装 tomcat8、tomcat9 或 tomcat10 之一。
如果将 Tomcat 部署到生产环境,请考虑安装 tomcat-native。Tomcat 的原生库配置服务器以使用 Apache Portable Runtime (APR) 库的网络连接(套接字)和 RNG 实现。它使用原生 32 位或 64 位代码来提高性能,有时在速度至关重要的生产环境中使用。默认 Tomcat 安装无需配置。更多信息请参见 官方 Tomcat 文档。
使用 tomcat-native 将消除 catalina.err
中的以下警告
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path [...]
文件系统层级
将 n
替换为您安装的版本(8、9、10)。
路径名 | 用途 |
---|---|
/etc/tomcatn |
配置文件。其中包括:tomcat-users.xml (定义允许使用管理工具的用户及其角色)、server.xml (Tomcat 主配置文件)、catalina.policy (安全策略配置文件) |
/usr/share/tomcatn |
包含脚本和指向其他目录的链接的 Tomcat 主文件夹 |
/usr/share/java/tomcatn |
Tomcat Java 库 (jars) |
/var/log/tomcatn |
未由 systemd 处理的日志文件(参见 #日志记录) |
/var/lib/tomcatn/webapps |
Tomcat 在此处部署您的 Web 应用程序 |
/var/tmp/tomcatn |
Tomcat 在此处存储您的 webapps 数据 |
初始配置
为了能够使用 manager webapp 和 admin webapp,您需要编辑 /etc/tomcatn/tomcat-users.xml
。
取消注释 “role and user” XML 声明并对其进行修改,以根据您的需要启用角色 tomcat
、admin-gui
、admin-script
和/或 manager-gui
、manager-script
、manager-jmx
、manager-status
(参见 Configuring Manager Application Access)。简而言之,tomcat
是用于运行的强制角色,manager-*
是能够管理 Web 应用程序的角色,而 admin-*
是 Tomcat 服务器上的完全权限管理员角色。
这是一个基本的配置文件,声明了其中一些角色以及用户名和密码(请务必将以下 [CHANGE_ME] 密码更改为安全的密码)
/etc/tomcatn/tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <role rolename="admin-gui"/> <role rolename="admin-script"/> <user username="tomcat" password="[CHANGE_ME]" roles="tomcat"/> <user username="manager" password="[CHANGE_ME]" roles="manager-gui,manager-script,manager-jmx,manager-status"/> <user username="admin" password="[CHANGE_ME]" roles="admin-gui"/> </tomcat-users>
请记住,每次修改此文件后都必须重启 Tomcat。
这篇 博客文章 对这些角色进行了很好的描述。
为了对配置文件具有读取权限并能与某些 IDE 良好协作,您必须将您的用户添加到 tomcatn
用户组。
启动/停止 Tomcat
启动 tomcatn.service
。
Tomcat 启动后,您可以访问此页面查看结果:https://127.0.0.1:8080。如果显示友好的 Tomcat 本地主页,则表示您的 Servlet 容器已启动并正在运行,可以托管您的 Web 应用程序。如果启动脚本失败或您只能在浏览器中看到 Java 错误,请使用 systemd 的 journalctl 查看启动日志。Google 上有很多关于 Tomcat 日志中经常出现的问题的解答。
systemd
服务以 root 权限运行此 Apache 二进制文件,该文件本身以非特权用户(Arch Linux 中的 tomcatn:tomcatn
)启动 Tomcat。这可以防止可能在不良 Web 应用程序中执行的恶意代码造成过大的损害。这也允许在需要时使用 1024 以下的端口。有关可用选项,请参阅 man jsvc
,并通过在 /etc/conf.d/tomcatn
中声明的 CATALINA_OPTS
环境变量传递它们。备选的 “手动” 方式
Tomcat 也可以使用上游脚本直接控制
/usr/share/tomcat/bin/{startup.sh,shutdown.sh,..}
这对于调试应用程序甚至调试 Tomcat 可能很有用,但不要首次使用它来启动 Tomcat,因为这样做可能会错误地设置某些权限并阻止 Web 应用程序工作。为了能够使用这些脚本,可能需要进行一些进一步的配置。请注意,使用这些脚本会阻止上述 jsvc 安全优势。
部署和处理 Web 应用程序
Tomcat 捆绑了 5 个已部署的 Web 应用程序(如果需要,请将 localhost 更改为服务器的 FQDN)
- 默认主页:https://127.0.0.1:8080/
- Tomcat 的本地文档:https://127.0.0.1:8080/docs/
- Servlet 和 JSP 示例:https://127.0.0.1:8080/examples/
- 用于处理虚拟主机的 host-manager:https://127.0.0.1:8080/host-manager/
- 用于管理 Web 应用程序的 manager:https://127.0.0.1:8080/manager/html/
图形界面方式
可能最简单的方法是使用 manager webapp https://127.0.0.1:8080/manager/html。使用您在 tomcat-users.xml
中定义为 manager
的用户名/密码。登录后,您可以看到五个已部署的 Web 应用程序。通过 “Deploy” 区域添加您的应用程序,然后使用 “Applications” 区域停止/启动/取消部署它。
命令行界面方式
也可以只将应用程序的 WAR 文件复制到目录 /usr/share/tomcatn/webapps
。为此,请确保 autoDeploy
选项仍设置为正确的 host,如此处所示
/etc/tomcatn/server.xml
... <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> ...
否则只需重启 tomcat 服务。
在 webapps 文件夹之外托管文件
如果您想将项目保留在 webapps 文件夹之外,可以通过创建 Context
来实现。转到 /etc/tomcatn/Catalina/localhost/
并创建您的 context。context 是一个简单的 xml 文件,用于指定 tomcat 应在何处查找项目。该文件的基本格式是
/etc/tomcatn/Catalina/localhost/whatShouldFollowLocalhost.xml
<Context path="/whatSholdFollwLocalhost" docBase="/where/your/project/is/" reloadable="true"/>
以下是一个工作示例。这假设项目托管在用户的 /home 文件夹中的某个位置。
/etc/tomcatn/Catalina/localhost/myProject.xml
<Context path="/myProject" docBase="/home/archie/code/jsp/myProject" reloadable="true"/>
现在可以将文件托管在 /home/archie/code/jsp/myProject/
中。要在 Web 浏览器中查看项目,请转到 https://127.0.0.1:8080/myProject。如果 tomcat 无法加载文件,则可能是权限问题。使 /home/archie/code/jsp/myProject
可执行 应该可以解决问题。
日志记录
Tomcat 与官方 Arch Linux 软件包一起使用时,使用 systemd 的 journalctl 用于启动日志。这意味着 /var/log/tomcatn/catalina.err
和 /var/log/tomcatn/catalina.out
文件不使用。在 /etc/tomcatn/server.xml
中定义为 Valve
的其他日志(例如访问日志和业务日志)仍然默认最终位于 /var/log/tomcatn/
中。
要恢复上游风格的日志记录,请使用 drop-in file 来更改 SYSLOG
以获取日志文件的绝对路径。
进一步设置
可以通过虚拟主机管理器 Web 应用程序进行基本配置:https://127.0.0.1:8080/host-manager/html。提供您在 tomcat-users.xml
中设置的用户名/密码。其他选项在 /etc/tomcatn
中的配置文件中进行调整,其中最重要的是 server.xml
。使用这些文件超出了本 101 Wiki 页面的范围。有关更多详细信息,请查看 最新的官方 Tomcat 文档。
从旧版本 Tomcat 迁移
正如引言中所述,Tomcat 10 不会弃用 Tomcat 9,Tomcat 9 不会弃用 Tomcat 8,依此类推。它们都是 Servlet/JSP 标准的实现。因此,您必须首先确定根据您的应用程序使用的 Servlet/JSP 版本,您需要 哪个版本 的 Tomcat。如果您需要迁移,官方网站提供了 关于如何处理此类过程的说明。
将 Tomcat 与不同的 JRE/JDK 结合使用
除了安装所需的 JRE/JDK 之外,唯一的要求是使用 drop-in file 设置 TOMCAT_JAVA_HOME
变量
/etc/systemd/system/tomcatn.service.d/start.conf
[Service] Environment=TOMCAT_JAVA_HOME=/usr/lib/jvm/java-8-openjdk
安全配置
本页面提供了使您的第一个 Web 应用程序在 Tomcat 上运行的最基本信息。它并非旨在成为管理 Tomcat 的权威指南(这本身就是一项工作)。官方 Tomcat 网站将提供所有必要的官方资料。也可以参考这篇 O'Reilly 页面 和这篇 unidata 页面。不过,这里有一些安全提示可帮助您入门
- 保持 Tomcat 安装为最新版本,以获取针对安全问题的最新修复程序
- 删除不需要的默认应用程序,例如
examples
、docs
、默认主页ROOT
(manager
webapp 中的 “_”)。这可以防止潜在的安全漏洞被利用。为此,请使用manager
。
为了更高的安全性,您甚至可以删除 host-manager 和 manager Web 应用程序。请记住,后者对于部署 Web 应用程序很有用。
- 禁用 WAR 自动部署选项。这将防止获得服务器受限访问权限的人员将 WAR 复制到
/usr/share/java/webapps
目录以使其运行。编辑server.xml
并将autoDeploy
设置为false
/etc/tomcatn/server.xml
... <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false"> ...
- 匿名化 Tomcat 的默认错误页面,以防止潜在的攻击者检索 Tomcat 的版本。要查看 Tomcat 默认显示的内容,只需访问一个不存在的页面,例如 https://127.0.0.1:8080/I_dont_exist。您将获得一个 404 错误页面,底部显示 Tomcat 的版本。
要匿名化此页面,请编辑/打开以下 JAR(像 vim
这样的编辑器可以直接编辑 zip 文件)
/usr/share/tomcatn/lib/catalina.jar
并编辑以下文件
org/apache/catalina/util/ServerInfo.properties
... server.info= server.number= server.built= ...
- 禁用
server.xml
中未使用的connectors
- 保持对
/etc/tomcatn/server.xml
的受限访问。只有tomcat
用户和/或root
应该能够读取和写入此文件。 - 保留
jsvc
的使用。除非有特殊原因,否则不要使用上游启动脚本,如上面的安全说明中所述。 - 为
tomcat-users.xml
中的每个用户使用强而不同的密码,为真正需要的用户分配角色,甚至禁用您不使用/不需要的用户名/角色。
甚至可以使用以下上游脚本加密 tomcat-users.xml
密码
/usr/share/tomcatn/bin/digest.sh -a sha-512 -h org.apache.catalina.realm.MessageDigestCredentialHandler NEW_PASSWORD
这将输出类似以下内容
NEW_PASSWORD:58adca01951a24aebce28f4d7a759aa30ef2f38bc54e41e51071c257ed4a1a9b$1$b4ccaafa86c26dea13825d35da73f9d11ce63f5deae15a13aafb835bdaf710d38922843c8065f35f245a20b1d2df9b20ddf2c005990512c598a62514f78cf3d2
将哈希部分粘贴到 tomcat-users.xml
中的明文密码的位置,并将以下内容添加到 server.xml
/etc/tomcatn/server.xml
<Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"> <CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler" algorithm="sha-512"/> </Realm> </Realm> ... />
请注意,这可能无关紧要,因为只有 root 和/或 tomcat 应该具有对该文件的读/写访问权限。如果入侵者设法获得 root 访问权限,他们无论如何都不需要这些密码来破坏您的应用程序/数据。请务必保持对该文件的受限读写访问权限,并始终了解您正在部署的内容!
故障排除
Tomcat 服务已启动,但页面未加载
首先,检查 /etc/tomcatn/tomcat-users.xml
是否有任何语法错误。如果一切正常且 tomcatn
正在正确运行,请以 root 身份运行 journalctl -r
以检查日志中是否有任何异常抛出(参见 #日志记录)。如果您看到类似 java.lang.Exception: Socket bind failed: [98] Address already in use
的内容,这是由于某些其他服务正在侦听同一端口。例如,Apache HTTP Server 和 Tomcat 可能正在侦听同一端口(例如,如果您的 Apache 在端口 8080 上运行,而 Nginx 在端口 80 上将其用作代理)。如果是这种情况,请编辑 /etc/tomcatn/server.xml
文件,并将 Connector 端口更改为 <Service name="Catalina">
下的其他端口。
/etc/tomcatn/server.xml
<?xml version='1.0' encoding='utf-8'?> ... ... <!-- Change port from 8080 to something else, like 8090 --> <Service name="Catalina"> <Connector executor="tomcatThreadPool" port="8090" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> ... ... </Service>
最后,重启 tomcatn
和 httpd
服务。
如果您没有解决方案并且您在 VM 中,则删除 /dev/random
并重新创建它可能会有所帮助(参见 Solution: FUTEX_WAIT hangs Java on Linux / Ubuntu in vmware or virtual box)
# rm /dev/random # mknod -m 644 /dev/random c 1 9
或者,即使在重启后也要保留它的另一个解决方案是修改 /usr/lib/jvm/java-8-openjdk/jre/lib/security/java.security
(例如)以指向 /dev/urandom
/