Tomcat

出自 Arch Linux 中文维基

Tomcat 是一個由 Apache Software Foundation 開發的開源的 Java Servlet 容器

注意: 目前存在四個版本的穩定分支: 7, 8, 910, 。沒一個版本能完全替代另一個。相反,每個分支是一部分 "Servlet" 和 "JSP" Java 標準的實現。兩個版本都被 Arch Linux 官方支持:tomcat8, tomcat9 and tomcat10。選用哪個版本主要由你的 web 程序的需求來決定的。

安裝[編輯 | 編輯原始碼]

安裝 tomcat8, tomcat9, 或 tomcat10 中的一個。

如果打算部署 Tomcat 到一個生產環境,請考慮安裝 tomcat-native 。Tomcat-native 將配置伺服器來使用 Apache Portable Runtime (APR) 庫的網絡連接(socket)和 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 (defines users allowed to use administration tools and their roles), server.xml (Main Tomcat configuration file), catalina.policy (security policies configuration file)
/usr/share/tomcatn Tomcat 主文件夾。包括腳本文件及到其它文件夾的連結
/usr/share/java/tomcatn Tomcat 的 Java 庫(jar文件)
/var/log/tomcatn systemd 記錄的日誌文件 (參閱 #日誌記錄)
/var/lib/tomcatn/webapps Tomcat 部署你的 Web 程序的地方
/var/tmp/tomcatn Tomcat 存儲你的 Web 程序數據的地方

初始化配置[編輯 | 編輯原始碼]

要使用 manager 和 admin 管理界面,請編輯下面這個文件 /etc/tomcatn/tomcat-users.xml

取消 XML 聲明中"role and user"這一塊的註釋,然後根據你的需要,修改並啟用 tomcat, {{Ic|admin-{gui,script} }} 和 {{Ic|manager-{gui,script,jmx,status} }} 等角色(詳情請參閲 Configuring Manager Application Access)。

簡單來説,tomcat 用於運行 Tomcat 伺服器,manager-* 用於管理 Tomcat 伺服器上的 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 用户組

 gpasswd -a <user> tomcat<number>

啟動/停止 Tomcat[編輯 | 編輯原始碼]

啟動 tomcatn.service 服務。

一旦 Tomcat 啟動了,你可以通過訪問這個頁面來查看結果:http://localhost:8080 。如果顯示了一個漂亮的 Tomcat 本地頁面,表明你的 Servlet 容器正在運行,並且可以裝載你的 web 程序了。如果啟動腳本失敗了,又或者你在瀏覽器裏只看到了一個 Java 錯誤頁面,你可以通過 systemd的 journalctl 命令來查看啟動日誌。Google 上有 Tomcat 日誌裏常見問題的解決辦法。

注意: To improve security, Arch Linux's Tomcat packages use the jsvc binary from Apache's common-daemons. Tomcat's systemd service runs this Apache binary with root privileges which itself starts Tomcat with an underprivileged user (tomcatn:tomcatn in Arch Linux). This prevents malicious code that could be executed in a bad web application from causing too much damage. This also enables the use of ports under 1024 if needed. See man jsvc for options available and pass them through the CATALINA_OPTS environment variable declared in /etc/conf.d/tomcatn.

備用「手動」方法[編輯 | 編輯原始碼]

Tomcat 也能通過上游腳本來直接控制:

/usr/share/tomcat/bin/{startup.sh,shutdown.sh,..}

這種方法對於調試程序甚至調試 Tomcat 非常有幫助。但不要在首次啟動 Tomcat 的時候用這種方法,因為這會導致一些權限錯誤,從而使一些程序停止運行。為了使用這些腳本,可能需要做一些額外的配置。並且使用這些腳本將會阻止上面所提到的 jsvc 安全優勢。

部署和處理 Web 程序[編輯 | 編輯原始碼]

Tomcat 7 捆綁了5個已經部署了的 Web 程序(有必要的話,把 localhost 換成你的伺服器的全稱域名):

GUI 方法[編輯 | 編輯原始碼]

最簡單的方法是通過 manager 程序來部署 http://localhost:8080/manager/html。 使用你在 tomcat-users.xml 定義的 manager 角色的用户名和密碼來登錄。登錄進去後,你將看到5個已經部署了的 Web 程序。通過 「Deploy」 區域來添加你自己的 Web 程序,通過 「Applications」 區域來停止/啟動/取消部署。

CLI 方法[編輯 | 編輯原始碼]

你也可以通過複製程序的 WAR 文件到 /usr/share/tomcatn/webapps 目錄來部署。確保 autoDeploy 選項如下面所示,設置在了正確的主機:

/etc/tomcatn/server.xml
...
<Host name="localhost"  appBase="webapps"
      unpackWARs="true" autoDeploy="true">
...

把項目部署在別的目錄[編輯 | 編輯原始碼]

你也可以通過設置 Context 來把你的項目部署在別的目錄。 你需要在 /etc/tomcatn/Catalina/localhost/ 目錄下創建你的 context。Context 是一個用於指定 tomcat 查找目錄的 xml 文件,其基本格式如下:

/etc/tomcatn/Catalina/localhost/whatShouldFollowLocalhost.xml
<Context path="/whatSholdFollwLocalhost" docBase="/where/your/project/is/" reloadable="true"/>

假設項目放在用户 /home 目錄下的某個文件夾裏,則 context 像這樣寫:

/etc/tomcatn/Catalina/localhost/myProject.xml
<Context path="/myProject" docBase="/home/archie/code/jsp/myProject" reloadable="true"/>

現在項目文件可以放在 /home/archie/code/jsp/myProject/ 目錄下了。要想在瀏覽器裏查看這個項目,訪問 http://localhost:8080/myProject 。 如果 tomcat 無法加載這些文件,可能是遇到了權限問題,運行 chmod o+x /home/archie/code/jsp/myProject 應該可以解決這個問題。

日誌記錄[編輯 | 編輯原始碼]

如果使用的是 Arch Linux 官方的 Tomcat 包,則使用 systemd的 journalctl 來記錄 啟動日誌。這意味着 /var/log/tomcatn/catalina.err/var/log/tomcatn/catalina.out不會 被使用。而其它的日誌,例如作為 Valve 定義在 /etc/tomcatn/server.xml 裏的 access logs 和 business logs 則默認會記錄在 /var/log/tomcatn/ 目錄下。

為了保存上游風格的日誌,把 systemd 文件 /lib/systemd/system/tomcatn.service 複製到 /etc/systemd/system/tomcatn.service ,然後把兩處 SYSLOG 改為日誌文件的絕對路徑。

進一步設置[編輯 | 編輯原始碼]

基本的配置,可以通過虛擬主機管理程序來設置:http://localhost:8080/host-manager/html 。使用你在 tomcat-users.xml 中設置的用户名和密碼來登錄。其它選項可通過修改 /etc/tomcatn 下的配置文件來設置,最重要的莫過於 server.xml。對這些文件的修改已經超過了本入門頁面的範圍,請訪問 官方 Tomcat 7 文檔 來獲得更多支持。

從以前版本的 Tomcat 中遷移[編輯 | 編輯原始碼]

正如介紹裏説的,「Tomcat 8 並不替代 Tomcat 7」。他們都是 Servlet/JSP 標準的實現。因此,程序使用了哪個版本的 Servlet/JSP 決定了需要使用 哪個版本的 Tomcat 。如果需要遷移,官方網站 會給你建議

使用不同版本的 JRE/JDK 來運行 Tomcat[編輯 | 編輯原始碼]

除了安裝需要的 JRE/JDK 外,唯一要做的就是設置 Tomcat systemd service 文件的 TOMCAT_JAVA_HOME 變量。

安裝後,使用 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 頁面 和 這個 頁面 。這裏還是提供了一些安全方面的建議:

  • 保持你的 Tomcat 更新到了最新版,以便獲得安全問題的最新修復
  • 移除不需要的默認程序,比如 examplesdocs,默認的主頁 ROOT ("_" 在 manager 程序裏) 。這可以防止潛在的安全漏洞被利用。使用 manager 來管理。

為了更安全,你甚至可以刪除 host-manager 和 manager 應用。但是別忘了,後者對部署 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 默認顯示什麼,只需要訪問一個不存在的頁面,比如 http://localhost: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 NEW_PASSWORD

這條命令將會輸出類似於下面的信息:

NEW_PASSWORD:b7bbb48a5b7749f1f908eb3c0c021200c72738ce

然後用哈希的部分替換掉 tomcat-users.xml 裏的密碼部分,然後把下文加入到 server.xml 中:

/etc/tomcatn/server.xml
<Host
  ...
  <Realm
    ...
    className="org.apache.catalina.realm.MemoryRealm" digest="SHA"
    ...
  />
  ...
/>

注意,這個方法可能意義並不大。因為只有 root 和/或者 tomcat 能讀寫這個文件,而如果一個入侵者成功獲得了 root 權限,那麼他將不需要這些密碼來混亂你的程序和數據。請確保對這個文件的讀寫限制!永遠弄清楚你在部署什麼。

故障排除[編輯 | 編輯原始碼]

Tomcat 服務已經啟動,但是無法加載頁面[編輯 | 編輯原始碼]

首先,檢查 /etc/tomcatn/tomcat-users.xml 有沒有語法錯誤。如果一切正常並且 tomcatn 正在運行,輸入 journalctl -r 查看log,看看有沒有拋出什麼異常(參照 Logging )。 如果你看到有類似 java.lang.Exception: Socket bind failed: [98] Address already in use 的異常,説明其它服務正在監聽這個端口。例如,有可能 Apache 和 Tomcat 都在監聽同一個端口(例如你在8080端口運行的 Apache 使用在80端口運行的Nginx 作為代理)。如果是這種情況,編輯 /etc/tomcatn/server.xml 文件,然後修改 <Service name="Catalina"> 下的 Connector port 為其它的值:

/etc/tomcatn/server.xml
<?xml version='1.0' encoding='utf-8'?>
...
...
<Service name="Catalina">
    <Connector executor="tomcatThreadPool"
                 port="8090" protocol="HTTP/1.1"
                 connectionTimeout="20000"
                 redirectPort="8443" />
...
...
</Service>

最後 重啟 tomcatnhttpd 服務。

如果還沒有解決,而且是在虛擬機中,請嘗試刪除並重建 /dev/random (cf. 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/