Tomcat, Amazon EC2 y el puerto 80... ménage à trois

Tantas bromas que se gasta @devsidestory sobre los sysadmins, y al final va a resultar que es un arte arcano sólo accesible a semidioses. Por lo menos, esa es la cara que se te queda cuando arrancas tu instancia de EC2 con su Amazon Linux recién instaladito, descargas Tomcat e intentas acceder a la página de prueba.

No conecta. F5. Joder, si he revisado la configuración dos veces. F5...

En Linux y Unix, los puertos por debajo del 1024 sólo están disponibles para escucha por el usuario root (y "sudoers"). Dicho de otra forma, si quieres arrancar un servidor http en el puerto 80 con su usuario enclaustrado sin permisos (y todas esas cosas raras que hacen los sysadmins), vas a encontrar problemas. Todo sea dicho, yo no recuerdo haberme topado con esto cuando servía un Wordpress desde mi casa, pero claro, era Ubuntu y era un Apache HTTPd.

Somos ciudadanos de segunda. Estoy seguro de que no habría que hacer ninguna movida para instalar un Apache, por mucho que la distribución preferida en EC2 sea la propia Amazon Linux. Pero bueno, afortunadamente, la solución es bastante fácil...

Si planeas instalar un Tomcat, no te molestes en cambiar los puertos por defecto, ya que el 80 no va a funcionar. En vez de eso, intenta acceder a la web de prueba en el 8080 y, si funciona, tienes vía libre. Existen varias soluciones para obtener el acceso al puerto 80 (y al 443), aunque la más simple es usar la utilidad de iptables, que permite redirigir el tráfico de un puerto externo al que te salga de las narices y viene con la distro de Amazon. Las reglas para los puertos 80 y 443 son las siguientes:

sudo /sbin/iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

sudo /sbin/iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

Ahora, para que pille las redirecciones, hay que reiniciar el firewall con:

sudo /etc/init.d/iptables restart

Por último, hay que guardar la configuración para que no se pierda al reiniciar la instancia:

sudo /sbin/service iptables save

Un pequeño inconveniente de esta solución es que la redirección es transparente al Tomcat, el cual sigue pensando que todo le viene por el puerto 8080 y construirá mal las URLs que no sean relativas (por ejemplo, los redirects). Para arreglar este estropicio, basta con añadir una propiedad a cada conector http que haya definido en el server.xml:

<Connector port="8080" proxyPort="80" .../>

¡Y ojo a las actualizaciones del paquete de ipfilters, que pueden borrar la tabla de reglas sin avisar!

Visto en StackOverflow, que lleva al blog de Charlie Wu