๐ Apache Tomcat#
Overview
Apache Tomcat is a free and open-source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and WebSocket technologies. Tomcat provides a โpure Javaโ HTTP web server environment in which Java code can run.
Description#
Architecture#
Note
A Server represents the whole container.
A Service is an intermediate component which lives inside a Server and ties one or more Connectors to exactly one Engine.
A Connector handles communications with the client.
An Engine represents request processing pipeline for a specific Service.
A Host is an association of a network name to the Tomcat server.
A Context represents a web application.
Configuration Files#
$CATALINA_HOME/conf#
catalina.policy :catalina.properties :logging.properties :context.xml :server.xml :tomcat-users.xmlweb.xml :Default Webapps#
Warning
Applications that are not required should be removed so the system will not be at risk if a vulnerability is discovered.
Directory#
/bin :/conf :/server :/lib :/logs :/src :/webapps :/work :Ports#
Properties#
Multiple Instances with Systemd Template#
Downloading#
apt install default-jdk
mkdir /usr/local/tomcat
wget https://archive.apache.org/dist/tomcat/tomcat-10/v10.0.6/bin/apache-tomcat-10.0.6.tar.gz
tar xvzf apache-tomcat-10.0.6.tar.gz -C /usr/local/tomcat
cd /usr/local/tomcat
Creating two instances#
for i in 1 2;do cp -rp apache-tomcat-10.0.6/ tomcat${i}; done
rm -rf tomcat{1,2}/{bin,lib,*.txt,*.md}
rm -rf tomcat{1,2}/{LICENSE,NOTICE,RELEASE-NOTES}
rm -rf apache-tomcat-10.0.6/{conf,logs,temp,webapps,work}
mv tomcat{1,2} apache-tomcat-10.0.6/
ln -s apache-tomcat-10.0.6/ current
Creating tomcat user#
useradd -r -U -d /usr/local/tomcat -M -s /bin/false tomcat
chown -R tomcat: /usr/local/tomcat/current/
Updating server.xml#
current/tomcat1/conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
Tip
To remove the blank and commented lines from an xml file :
sed '/<!--/,/-->/d;/^$/d' current/tomcat1/conf/server.xml
diff -u current/tomcat{1,2}/conf/server.xml
--- current/tomcat1/conf/server.xml 2021-05-08 17:24:15.000000000 +0200
+++ current/tomcat2/conf/server.xml 2021-06-05 18:45:53.857036987 +0200
@@ -19,7 +19,7 @@
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
-<Server port="8005" shutdown="SHUTDOWN">
+<Server port="8006" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
@@ -65,9 +65,9 @@
AJP Connector: /docs/config/ajp.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
- <Connector port="8080" protocol="HTTP/1.1"
+ <Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
- redirectPort="8443" />
+ redirectPort="8444" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
Creating a systemd template#
/etc/systemd/system/tomcat@.service
[Unit]
Description=Tomcat - instance %i
After=syslog.target network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
WorkingDirectory=/usr/local/tomcat/current/%i
Environment="JAVA_HOME=/usr/lib/jvm/java-1.11.0-openjdk-amd64"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom"
Environment="CATALINA_PID=/usr/local/tomcat/current/%i.pid"
Environment="CATALINA_BASE=/usr/local/tomcat/current/%i"
Environment="CATALINA_HOME=/usr/local/tomcat/current"
EnvironmentFile=/usr/local/tomcat/current/.%i
ReadWritePaths=/usr/local/tomcat/
ExecStart=/usr/local/tomcat/current/bin/startup.sh -security
ExecStop=/usr/local/tomcat/current/bin/shutdown.sh
RestartSec=10
Restart=on-abort
[Install]
WantedBy=multi-user.target
/usr/local/tomcat/current/.tomcat1
CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC
/usr/local/tomcat/current/.tomcat2
CATALINA_OPTS=-Xms1024M -Xmx2048M -server -XX:+UseParallelGC
systemctl daemon-reload
systemctl start tomcat@tomcat{1,2}.service
Directory in tree-like format#
/usr/local/tomcat/
โโโ [drwxr-xr-x tomcat tomcat ] apache-tomcat-10.0.6
โย ย โโโ [drwxr-x--- tomcat tomcat ] bin
โย ย โโโ [-rw-r----- tomcat tomcat ] BUILDING.txt
โย ย โโโ [-rw-r----- tomcat tomcat ] CONTRIBUTING.md
โย ย โโโ [drwxr-x--- tomcat tomcat ] lib
โย ย โโโ [-rw-r----- tomcat tomcat ] LICENSE
โย ย โโโ [-rw-r----- tomcat tomcat ] NOTICE
โย ย โโโ [-rw-r----- tomcat tomcat ] README.md
โย ย โโโ [-rw-r----- tomcat tomcat ] RELEASE-NOTES
โย ย โโโ [-rw-r----- tomcat tomcat ] RUNNING.txt
โย ย โโโ [-rw-r----- tomcat tomcat ] .tomcat1
โย ย โโโ [drwxr-x--- tomcat tomcat ] tomcat1
โย ย โย ย โโโ [drwx------ tomcat tomcat ] conf
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] logs
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] temp
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] webapps
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] work
โย ย โโโ [-rw-r----- tomcat tomcat ] tomcat1.pid
โย ย โโโ [-rw-r----- tomcat tomcat ] .tomcat2
โย ย โโโ [drwxr-x--- tomcat tomcat ] tomcat2
โย ย โย ย โโโ [drwx------ tomcat tomcat ] conf
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] logs
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] temp
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] webapps
โย ย โย ย โโโ [drwxr-x--- tomcat tomcat ] work
โย ย โโโ [-rw-r----- tomcat tomcat ] tomcat2.pid
โโโ [lrwxrwxrwx root root ] current -> apache-tomcat-10.0.6/
Checking the instances#
pgrep -u tomcat -a
ps -L -C java -o pid,tid,pcpu,pmem,comm
awk '/java/' <(netstat -tupane)
Securing Management Applications#
current/tomcat2/webapps/host-manager/META-INF/context.xml
current/tomcat2/webapps/manager/META-INF/context.xml
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="192\.168\.122\.\d+|127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
current/tomcat2/conf/tomcat-users.xml
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="guisam" password="turlututu" roles="admin-gui,manager-gui,manager-script"/>
Note
systemctl reload tomcat
SSL/TLS Configuration#
cd /usr/local/tomcat/current/tomcat1/conf
keytool -genkey -keyalg RSA -alias debian10.guisam.lan \
-keystore debian10.guisam.lan.jks -validity 365 -keysize 2048
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: debian10.guisam.lan
What is the name of your organizational unit?
[Unknown]: guisam
What is the name of your organization?
[Unknown]: guisam
What is the name of your City or Locality?
[Unknown]: ivry
What is the name of your State or Province?
[Unknown]: 94
What is the two-letter country code for this unit?
[Unknown]: FR
Is CN=debian10.guisam.lan, OU=guisam, O=guisam, L=ivry, ST=94, C=FR correct?
[no]: y
$CATALINA_HOME/tomcat1/conf/server.xml
+ <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
+ maxThreads="150" SSLEnabled="true">
+ <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"/>
+ <SSLHostConfig>
+ <Certificate
+ certificateKeystorePassword="<mysuperpassword>"
+ certificateKeystoreFile="conf/debian10.guisam.lan.jks"
+ type="RSA" />
+ </SSLHostConfig>
+ </Connector>
$CATALINA_HOME/tomcat1/conf/web.xml
</welcome-file-list>
+ <!-- ======================= HTTP to HTTPS ============================== -->
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Protected Context</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <!-- auth-constraint goes here if you require authentication -->
+ <user-data-constraint>
+ <transport-guarantee>CONFIDENTIAL</transport-guarantee>
+ </user-data-constraint>
+ </security-constraint>
+
</web-app>
systemctl restart tomcat@tomcat1.service
curl -I http://192.168.122.232:8080
[...]
Location: https://192.168.122.232:8443/
[...]
curl -kI https://192.168.122.232:8443
HTTP/2 200
[...]
Manager Commands#
Tip
alias curl="curl -u guisam:turlututu -k"
TOMCAT1="https://192.168.122.232:8443"
TOMCAT2="https://192.168.122.232:8444"
curl $TOMCAT1/manager/text/list
curl $TOMCAT1/manager/text/serverinfo
curl $TOMCAT1/manager/text/threaddump
curl $TOMCAT1/manager/text/vminfo
curl $TOMCAT1/manager/text/sessions\?path\=/sample
OK - Session information for application at context path [/sample]
Default maximum session inactive interval is [30] minutes
Inactive for [<1] minutes: [1] sessions
curl $TOMCAT1/manager/text/expire\?path\=/sample\&idle\=num
OK - Session information for application at context path [/sample]
Default maximum session inactive interval is [30] minutes
Inactive for [1 - <2] minutes: [1] sessions
curl $TOMCAT1/manager/text/stop\?path\=/docs
OK - Stopped application at context path [/docs]
curl $TOMCAT1/manager/text/start\?path\=/docs
OK - Started application at context path [/docs]
curl $TOMCAT1/manager/text/reload\?path\=/docs
OK - Reloaded application at context path [/docs]
curl $TOMCAT1/manager/text/deploy\?path\=/sample -T sample.war
OK - Deployed application at context path [/sample]
curl $TOMCAT1/manager/text/undeploy\?path\=/sample
OK - Undeployed application at context path [/sample]