En el desarrollo de un proyecto tuve que instalar un servidor Tomcat como servidor web, para dar soporte a servlets y JSPs.
Tomcat no es un servidor de aplicaciones, como JBoss o JOnAS. Incluye el compilador Jasper, que compila JSPs convirtiéndolas en servlets. El motor de servlets de Tomcat a menudo se presenta en combinación con el servidor web Apache. Existen varias aplicaciones o paquetes para instalar Apache en linux que ademas instalan también el interprete de php, el servidor MySql de base de datos y el entorno web phpMyAdmin, para gestionar la base de datos.
Además, como también estaba usando MySql como sistema de base de datos, instalé el phpMyAdmin sobre un servidor Apache.
En resumen:
Actualmente, el servidor Apache, viene intregado en un ‘sistema’ que se define como LAMP (Linux, Apache, MySql, Php). Tampoco quiero extenderme en este tema, ya que no es el tema de esta entrada.
Al tener los dos servidores web instalados en la misma máquina, tenía un problema: el puerto 80 estaba siendo usado por el Apache y el Tomcat usaba el 8080. Estos puertos vienen configurados por defecto en las instalaciones de los dos servidores.
Yo necesitaba que cuando se accediera al puerto 80 (el puerto que se usa generalmente en el tráfico web) se accediera al Tomcat, en lugar de acceder al Apache.
En resumén, hay dos cosas que tenemos que hacer:
Generalmente, en el entorno Linux, el apache se instala en el siguiente path: /etc/apache2.
Pues hay que cambiar el puerto 80 que viene definido por defecto en este archivo «/etc/apache2/ports.conf» en estas dos lineas donde se define el NameVirtualHost y el Listen, por el puerto que quieras (yo he usado el 8088). Debería de quedar así:
NameVirtualHost *.8088
Listen 8088
Y en /etc/apache2/sites-enabled/000-default cambias también el puerto en la linea VirtualHost, quedando la linea así:
VirtualHost *:8088
Y después de cualquier cambio en la configuración del Apache, hay que reiniciarlo:
sudo /etc/init.d/apache2 restart
Aunque a mi me gusta más parar y arrancar. ¿Por qué?. Por que a veces me he encontrado con problemas de caché o similares que me volvían loco y no se solucionaba hasta hacer un stop & start, y no un restart.
sudo /etc/init.d/apache2 stop
sudo /etc/init.d/apache2 start
Bueno, pues con esto, ya hemos cambiado el puerto de escucha del servidor Apache. Comprobamos que funciona.
Ha sido sencillo. Pues vamos a cambiar la configuración del Tomcat, que en principio parece igual de sencillo.
Si necesitamos cambiar el puerto del Tomcat (por defecto es 8080), lo podemos hacer fácilmente a través del archivo server.xml. Hay que buscarlo dentro de la instalación de Tomcat. En mi caso está en /etc/tomcat7, pero tambien lo puedes encontrar en /etc/tomcat7/conf. Esto depende de la instalación del Tomcat.
Cuando encuentres el fichero, debes buscar algo así:
<Connector port="8080" ......
y cambiar el puerto al 80 (tal como indico a continuación):
<Connector port="80" ......
Despues, reiniciar el tomcat (ya he comentado que prefiero el stop & start)
sudo /etc/init.d/tomcat7 stop
sudo /etc/init.d/tomcat7 start
Y con esto ya está. Bueno eso creía yo.
Me fui al Chrome y al intentar cargar mi página lo que me encontré fue lo siguiente:
Esto me dejo bastante perplejo, ya que buscara por donde buscara, siempre me encontraba que para cambiar el puerto del Tomcat, había que hacer lo que he descrito anteriormente.
¿Que hacer?. Pues pedir consejo. Todos tenemos un amigo, que es mucho más inteligente que uno mismo (y si no lo tienes, te recomiendo que lo busques). Así que después de comentarle mi problema, me lo solucionó.
El problema es que los puertos por debajo de 1024 en Ubuntu son puertos que sólo puedes ser usados por usuarios «privilegiados», usuarios que tienen privilegios como root. ¿Que quiere decir? Que no todos los usuarios pueden ejecutar aplicaciones que usen puertos por debajo de 1024. La solución es permitir que el usuario propietario del tomcat, pueda usar el puerto 80. Para esto hay que instalar authbind.
Authbind es una utilidad que permite el uso de los puertos menores de 1024 a usuarios que no son root.
El servidor Tomcat, generalmente se instala con el usuario tomcat7. Pero para asegurarte puedes ejecutar la siguiente sentencia:
ps -def |grep java|grep tomcat
Esta sentencia lo que hace es buscar las palabras «java» y «tomcat» en los procesos que se están ejecutando en el Linux.
En mi caso, lo que obtengo es:
tomcat7 30957 1 0 Aug27 ? 00:13:41 /usr/lib/jvm/default-java/bin/java -Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat7/endorsed -classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
Como puedes ver, el usuario que ejecuta el servidor Tomcat es el usuario tomcat7.
Bueno, pues ya sabemos quien es el usuario. Ahora necesitamos saber cual es el UID de este usuario. Esta información se encuentra en el fichero passwd ubicado en la carpeta /etc. Para visualizarlo puedes utilzar el siguiente comando:
cat /etc/passwd |grep tomcat
Esto es lo que recupero en mi caso:
tomcat7:x:104:107::/usr/share/tomcat7:/bin/false
Los diferentes campos(7) estan separados por dos puntos (:). El UID es el tercer campo, en mi caso, el UID del usuario tomcat7 es 104.
Vamos a instalar ahora authbind (como he dicho anteriormente) y configurar el puerto 80 para que sea accesible por el usuario tomcat7.
sudo apt-get install authbind
Authbind se configura en /etc/authbind/ y dentro de este directorio encontramos tres subdirectorios que permiten granularidad en la configuración. Funciona así.
Paso 1. Authbind busca primero en el directorio /etc/authbind/byport/ ficheros llamados «[num_puerto]» es decir el fichero lleva el nombre del puerto, por ejemplo «80». Si encuentra el fichero y este fichero es ejecutable por el usuario al que queremos permitir el uso del puerto, entonces se autoriza a ese usuario a usar ese puerto en particular, si no, deniega su uso y pasa al paso dos.
Paso 2. En segundo lugar busca en el directorio /etc/authbind/byaddr/ los ficheros con nombre «[ipaddress]:[num_puerto]», por ejemplo «192.168.40.125:80». Si el fichero es ejecutable para el usuario le permite su uso en la dirección especificada. Si no, deniega y pasa al punto tres.
Paso 3. En último lugar busca el en el directorio /etc/authbind/byuid/ un fichero llamado «[uid]», es decir, con el nombre del número de identificación de usuario al que queremos permitir el uso de puertos. El fichero tiene permisos de lectura, escritura y ejecución para el usuario al que se le permite el uso y 0 permisos para el grupo y otros. Si se encuentra este fichero, entonces lee linea a linea y va autorizando las direcciones y rangos de puertos que pongan en cada linea al usuario con esa uid. Las lineas tiene el formato [ipaddress]/[netmaskprefix]:[puertoinicial],[puertodestino]. Por ejemplo, la linea 192.168.40.125/32:80,100 permite el uso de los puertos 80 a 100 en la dirección 192.168.40.125. Si no se encuentra el fichero o el fichero está vacío, se deniega el uso de puertos definitivamente.
Vamos a ejecutar los siguientes comandos, y hay que hacerlo como root.
sudo touch /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80
sudo chown tomcat7 /etc/authbind/byport/80
Lo que hemos hecho es:
Con estos tres comandos hemos creado un fichero que cumple el paso 1 descrito anteriormente: un fichero llamado 80 y que es ejecutable por el usuario tomcat7. Con lo que permitimos al tomcat poder usar el puerto 80
Ahora hay que hacer que use IPv4 por defecto (authbind no admite actualmente IPv6).
En mi caso, he modificado el script de arranque del tomcat7 (/etc/init.d/tomcat7). (las lineas en amarillo son las que he añadido)
catalina_sh() {
# Escape any double quotes in the value of JAVA_OPTS
JAVA_OPTS="$(echo $JAVA_OPTS | sed 's/\"/\\\"/g')"
AUTHBIND_COMMAND=""
if [ "$AUTHBIND" = "yes" -a "$1" = "start" ]; then
JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true"
AUTHBIND_COMMAND="/usr/bin/authbind --deep /bin/bash -c "
fi
# Define the command to run Tomcat's catalina.sh as a daemon
# set -a tells sh to export assigned variables to spawned shells.
TOMCAT_SH="set -a; JAVA_HOME=\"$JAVA_HOME\"; source \"$DEFAULT\"; \
CATALINA_HOME=\"$CATALINA_HOME\"; \
CATALINA_BASE=\"$CATALINA_BASE\"; \
JAVA_OPTS=\"$JAVA_OPTS\"; \
CATALINA_PID=\"$CATALINA_PID\"; \
CATALINA_TMPDIR=\"$CATALINA_TMPDIR\"; \
LANG=\"$LANG\"; JSSE_HOME=\"$JSSE_HOME\"; \
cd \"$CATALINA_BASE\"; \
\"$CATALINA_SH\" $@"
if [ "$AUTHBIND" = "yes" -a "$1" = "start" ]; then
TOMCAT_SH="'$TOMCAT_SH'"
fi
# Run the catalina.sh script as a daemon
set +e
touch "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.out
chown $TOMCAT7_USER "$CATALINA_PID" "$CATALINA_BASE"/logs/catalina.out
start-stop-daemon --start -b -u "$TOMCAT7_USER" -g "$TOMCAT7_GROUP" \
-c "$TOMCAT7_USER" -d "$CATALINA_TMPDIR" -p "$CATALINA_PID" \
-x /bin/bash -- -c "$AUTHBIND_COMMAND $TOMCAT_SH"
status="$?"
set +a -e
return $status
}
Después de todo estos cambios, reinicar el tomcat (ya sabes: stop&start), y que funcione.
sudo /etc/init.d/tomcat7 stop
sudo /etc/init.d/tomcat7 start
En mi caso, y gracias a la ayuda recibida, funcionó.