Securizar el puerto ‘shutdown’ de Tomcat

Para realizar el apagado ordenado del servidor de aplicaciones Tomcat se utiliza un puerto TCP, el cual responde al apagado del servicio cuando se le envía un «SHUTDOWN«.

Por defecto, el puerto utilizado es el 8005 TCP y escucha únicamente en 127.0.0.1:

# netstat -natp | grep 8005
tcp        0      0 ::ffff:127.0.0.1:8005       :::*      LISTEN   1519/java

Por suerte, como decía antes sólo escucha en localhost así que un problema menos. Lo que pasa es que con la configuración por defecto, cualquier usuario del sistema puede conectarse al puerto y ejecutar el shutdown sin ningun tipo de restricción.

Tomcat en ejecución como root:

[foo@localhost ~]$ ps -ef | grep tomcat
root      1519     1  2 18:47 pts/0    00:00:10 /usr/bin/java -Djava.util.logging.config.file=/root/apache-tomcat-7.0.59/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/root/apache-tomcat-7.0.59/endorsed -classpath /root/apache-tomcat-7.0.59/bin/bootstrap.jar:/root/apache-tomcat-7.0.59/bin/tomcat-juli.jar -Dcatalina.base=/root/apache-tomcat-7.0.59 -Dcatalina.home=/root/apache-tomcat-7.0.59 -Djava.io.tmpdir=/root/apache-tomcat-7.0.59/temp org.apache.catalina.startup.Bootstrap start
foo       1568  1548  0 18:54 pts/0    00:00:00 grep tomcat

Paramos tomcat como usuario «foo»:

[foo@localhost ~]$ telnet localhost 8005
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SHUTDOWN
Connection closed by foreign host.

Tomcat parado…

[foo@localhost ~]$ ps -ef | grep tomcat
foo       1575  1548  0 18:55 pts/0    00:00:00 grep tomcat

En el ejemplo anterior el usuario «foo», que no tienen ningún tipo de privilegio respecto a Tomcat se conecta al puerto TCP 8005 y para el servicio.

Modificar la string «shutdown» por una más compleja

La forma más rápida de securizar esta situación es modificar el comando a enviar para realizar el apagado de Tomcat a través del puerto de shutdown. En el archivo de configuración «server.xml» podemos especificar una string específica para sustituir a «SHUTDOWN» así como modificar el puerto de escucha:

$CATALINA_HOME/conf/server.xml

Antes:

 <Server port="8005" shutdown="SHUTDOWN">

Después:

 <Server port="8005" shutdown="90asjk3sLA23d3dgg4hasad">

Una string compleja ser la solución más rápida a este problema. Después nos aseguramos de que únicamente tomcat tiene permiso de lectura para el archivo de configuración:

-rw-------. 1 tomcat root   6613 ene 28 16:54 server.xml

Deshabilitar el puerto de Shutdown

Si configuramos el puerto como «-1» el apagado de Tomcat a través del puerto TCP quedará deshabilitado:

 <Server port="-1" ...>

De este modo Tomcat sólo puede ser parado por el usuario que lo está ejecutando a través de un kill:

[root@localhost bin]# ./shutdown.sh 
Using CATALINA_BASE:   /root/apache-tomcat-7.0.59
Using CATALINA_HOME:   /root/apache-tomcat-7.0.59
Using CATALINA_TMPDIR: /root/apache-tomcat-7.0.59/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /root/apache-tomcat-7.0.59/bin/bootstrap.jar:/root/apache-tomcat-7.0.59/bin/tomcat-juli.jar
mar 23, 2015 19:07:26 PM org.apache.catalina.startup.Catalina stopServer
SEVERE: No shutdown port configured. Shut down server through OS signal.
Server not shut down.
[root@localhost bin]# kill 1638