miércoles, 13 de julio de 2016

Actualización rápida de Tomcat 7

En esta breve entrada vamos a explicar cómo actualizar el Tomcat 7, la distro del Framework Dinámica en particular, cuando es liberada una nueva edición de Tomcat 7 por parte de Apache. El procedimiento es muy simple y supone una interrupción mínima de servicio, inevitable ya que es necesario actualizar los JARs básicos de Tomcat.

1) Descargue y descomprima la última versión de Tomcat 7, a la fecha es v7.0.70, no sobreescriba su instalación de producción, use una carpeta distinta pero en un disco accesible para el servidor a ser actualizado. Supongamos que lo pudo en el disco D; entonces su carpeta sería:

D:\apache-tomcat-7.0.70

2) Detenga el proceso Tomcat

3) Copie desde la instalación nueva D:\apache-tomcat-7.0.70\lib los JARs señalados en la imagen a continuación, al directorio /tomcat/lib de su servidor, reemplazar los archivos existentes.

Los JARs que no se copian son los que no necesita Dinámica, por ejemplo el compilador de JSP y lo relacionado con JSP se deja por fuera porque Dinámica no utiliza JSPs, tampoco requerimos Ant.

4) Reinicie el servicio o proceso Tomcat, utilice el URL de diagnóstico (/action/test) de alguna de sus WebApps escritas con Dinámica, debería ver la página de diagnóstico estándar del framework Dinámica, como aparece abajo, indicando la versión de Tomcat:


¡Eso es todo! ya su instalación de Tomcat está al día.

NOTA: este proceso es para actualizar Tomcat dentro de una misma línea de versión principal, Tomcat v7 en este caso. Se recomienda respaldar toda la carpeta /lib de su Tomcat antes de actualizarlo, como medida para hacer rápidamente un "rollback" del cambio si experimentara algún problema (improbable) con esta actualización.


miércoles, 4 de mayo de 2016

Actualizar configuración de husos horarios en Java 8

Recientemente en Venezuela hubo un ajuste del huso horario, en Java ya está disponible la actualización de TimeZone para reconfigurar una instalación de Java existente, para este ejemplo usaremos Java 8.

Los pasos son los siguientes:

Descargar el tool tzupdater.jar de Oracle, se descarga desde:
http://www.oracle.com/technetwork/java/javase/downloads/tzupdater-download-513681.html

Luego se recomienda ejecutar desde consola DOS abierta como Admin local del equipo este comando:

"C:\Program Files\Java\jdk1.8.0_74\bin\java.exe" -jar tzupdater.jar -v -l http://www.iana.org/time-zones/repository/tzdata-latest.tar.gz

Claro está deberán utilizar su propia ruta de java.exe u omitirla si lo tienen instalado visible a nivel de sistema.

Al correr el update deberían ver mensajes como estos en la consola:
java.home: C:\Program Files\Java\jdk1.8.0_74\jre
java.vendor: Oracle Corporation
java.version: 1.8.0_74
Downloaded file to C:\Users\mcordova\AppData\Local\Temp\tz.tmp\tzdata.tar.gz
JRE tzdata version: tzdata2015g
tzupdater tool would update with tzdata version: tzdata2016d
Downloaded file to C:\Users\mcordova\AppData\Local\Temp\tz.tmp\sha512hash
Renaming C:\Program Files\Java\jdk1.8.0_74\jre\lib\tzdb.dat to C:\Program Files\
Java\jdk1.8.0_74\jre\lib\tzdb.dat.tzdata2015g
Renaming C:\Program Files\Java\jdk1.8.0_74\jre\lib\tzdb.dat.dynamic to C:\Program Files\Java\jdk1.8.0_74\jre\lib\tzdb.dat
Validating for : tzdata2016d
Validation complete
JRE updated to version : tzdata2016d

Con este procedimiento no necesitan esperar a una actualización de todo el JDK/JRE por parte de Oracle con el cambio correspondiente a su país.

El manual de tzupdater: http://www.oracle.com/technetwork/java/javase/tzupdater-readme-136440.html


miércoles, 13 de mayo de 2015

SSL fortalecido con Tomcat 7 y Java 8

Tanto por seguridad como para salir bien parado en las auditorias (común en instalaciones corporativas), es importante tener bien configurado el SSL en Tomcat. En nuestro caso (instalaciones del Framework Dinámica) usamos Tomcat 7 sin Apache por delante, cuando mucho un Load Balancer o un Firewall, así que en este artículo nos concentramos en cómo configurar el SSL en Tomcat 7 para obtener un grado aceptable de seguridad.

El punto de referencia lo marca el riguroso test de SSL Labs:
https://www.ssllabs.com/ssltest/

Actualmente con esta configuración logramos obtener un "A", dejando aparte los temas del certificado no confiable que usamos para la prueba:


Como se puede apreciar arriba, este Tomcat también soporta HTTP Strict Transport Security, más adelante explicamos cómo hacerlo.

Actualizando los Certificados SSL

Viene una gran migración a certificados con algoritmo de firma SHA2,  ya los navegadores comenzaron a quejarse de los certificados firmados con SHA1, y pronto dejarán de soportarlos. Esto no tiene que ver con al configuración SSL de Tomcat 7 sino con el proceso de crear el KeyStore y solicitar la firma del certificado. Es bueno saber que al migrar a un certificado actualizado con firma SHA2 (SHA256withRSA) se dejan de soportar clientes viejos como IE 8 en XP SP2 o inferior, con XP SP3 se puede soportar IE8.

En todo caso, es importante actualizar el certificado para que sea ampliamente aceptado y no levante advertencias de seguridad, para ello se usa el algoritmo de firma SHA256withRSA con keytool de Java.

Usar Java 8

Para fortalecer SSL en Tomcat es necesario migrar a Java 8, porque esta versión contiene mejoras importantes en el componente JSSE (el que provee soporte SSL) que no están en versiones anteriores.

En particular se activan estas opciones para el proceso Java que correrá a Tomcat:

-Djdk.tls.rejectClientInitiatedRenegotiation=true
-Djdk.tls.ephemeralDHKeySize=2048

Por otro lado es MUY IMPORTANTE actualizar la instalación de Java 8 con las políticas de encriptamiento fuerte, que son dos JARs que se descargan desde el website oficial de Java en Oracle. El componente se denomina "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8" y se descarga aquí:

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

Los JARs se copian en:

C:\Program Files\Java\jdk1.8.0_XX\jre\lib\security

reemplazando los existentes.

Usar Tomcat 7.0.61

Es necesario usar Tomcat 7.0.61 o superior, porque es a partir de esta versión que Tomcat permite indicar que se respete el orden de los Ciphers especificados del lado server, en el test de SSL Labs esto se puede comprobar:



En server.xml, en el bloque "Connector" donde configuramos SSL se añade este atributo:

useServerCipherSuitesOrder="true"

Anular ataques POODLE

En server.xml indicamos el uso de protocolos TLS únicamente:

sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"



El ataque BEAST es algo que no se puede evitar a menos que se elimine el uso de TLS 1.0 (afectando potencialmente la compatibilidad con una base amplia de navegadores) o se utilice RC4, lo cual es peor porque el protocolo no se considera seguro, su uso levanta alertas de seguridad y rebaja la calificación en el test, así que de los males el menor. De hecho a pesar de aparecer que no se mitiga BEAST del lado server (es un ataque que se orquesta desde el lado cliente), aun así la calificación es "A". Si solo se soporta TLS 1.2 (para los navegadores modernos únicamente) entonces se elimina el riesgo del BEAST.

Configuración de Ciphers fuerte y minimalista

Por defecto un servidor SSL en Java 8 soporta una gama amplia de protocolos, algunos considerados inseguros y su uso rebaja la calificación en el test de SSL Labs, además de levantar alertas de auditoria de seguridad de servidores, se sugiere usar una lista restringida de protocolos. Nosotros usamos la configuración de Ciphers que aparece abajo y obtenemos amplia compatibilidad con los navegadores más populares, soportando "Forward Secrecy"  donde es posible, lo cual fortalece la seguridad del protocolo, e incluso se soporta IE8 a partir de XP SP3, con lo que se gana un SSL robusto y amplia base de clientes soportados. El orden de los ciphers es importante y hace que los navegadores selecciones un Cipher fuerte antes que uno débil cuando inician la "conversación" con el servidor:

ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA"

Este es un atributo del Connector en server.xml claro está, A continuación un ejemplo completo de la configuración del conector SSL en Tomcat:

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="500" scheme="https" secure="true"
clientAuth="false" keystoreType="JKS" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"
useServerCipherSuitesOrder="true"
keystoreFile="${catalina.home}/conf/localhost.jks"
keystorePass="xyz123*"
ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA"
>

Solo desde que salió Java 8 y sumado a la última actualización de Tomcat 7 se puede lograr una configuración de SSL razonablemente robusta, sin necesidad de utilizar ningún software por delante de Tomcat.

Hay una protección que JSSE en Java 8 no soporta: TLS Fallback SCSV, que en pocas palabras se trata de evitar que un cliente pueda negociar usar un protocolo más antiguo con la intención de vulnerar la seguridad. Sin embargo si se utilizan ciphers fuertes e incluso si solo se soporta TLS 1.2 este riesgo se reduce o incluso desaparece.

jueves, 26 de febrero de 2015

Acelerando el arranque de Tomcat 7

Regresamos con un mini-artículo sobre como mejorar los tiempos de arranque del servicio Tomcat, específicamente de la distribución de Tomcat 7 para el Framework Dinámica, que por correr aplicaciones creadas con este framework, no necesita JSPs, TagLibs, anotaciones de Servlet Spec 3.x ni otros artificios. Dinámica es minimalista, usa un solo Servlet (el Controller) y algunos filtros/listeners, nada ajeno a la especificación de servlets 3.0. Por este motivo hay varias cosas que se pueden desactivar en Tomcat para que arranque considerablemente más rápido.

La velocidad de arranque del servicio es importante para mantener la interrupción del mismo en un mínimo aceptable, sea por controles de cambio o contingencias.

Paso 1

En ${tomcat.home}/conf/catalina.properties se definen las reglas de scanning de anotaciones en los JARs, es el primer punto a tocar. La configuración por defecto pecha bastante el tiempo de arranque haciendo revisiones innecesarias (para Dinámica) en los JARs. El tiempo de arranque en nuestro Tomcat 7 con 4 WebApps instaladas es el siguiente:

[2015-02-25 16:01:57] INFORMACIËN: Initializing ProtocolHandler ["http-bio-80"]
[2015-02-25 16:01:57] INFORMACIËN: Initialization processed in 300 ms
[2015-02-25 16:01:57] INFORMACIËN: Arrancando servicio Catalina
[2015-02-25 16:01:57] INFORMACIËN: Starting Servlet Engine: Apache Tomcat/7.0.59
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\admin de la aplicaci¾n web
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\devel de la aplicaci¾n web
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\nws de la aplicaci¾n web
[2015-02-25 16:01:57] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\ROOT de la aplicaci¾n web
[2015-02-25 16:02:00] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\ROOT has finished in 2.367 ms
[2015-02-25 16:02:00] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\nws has finished in 2.517 ms
[2015-02-25 16:02:00] INFORMACIËN: [Dinamica] SecurityFilter started for context: AdminConsole
[2015-02-25 16:02:00] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\admin has finished in 2.690 ms
[2015-02-25 16:02:01] INFORMACIËN: WSSERVLET14: inicializando el servlet de JAX-WS
[2015-02-25 16:02:01] INFORMACIËN: WSSERVLET12: inicializando el listener de contexto de JAX-WS
[2015-02-25 16:02:01] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\devel has finished in 3.220 ms
[2015-02-25 16:02:01] INFORMACIËN: Starting ProtocolHandler ["http-bio-80"]
[2015-02-25 16:02:01] INFORMACIËN: Server startup in 3256 ms

Lo que vamos a hacer es desactivar el scanning de los JARs, configurando estos parámetros con los valores mostrados abajo:

tomcat.util.scan.DefaultJarScanner.jarsToSkip=*.jar
org.apache.catalina.startup.ContextConfig.jarsToSkip=*.jar
org.apache.catalina.startup.TldConfig.jarsToSkip=*.jar

Con este no se desactiva el uso de anotaciones muy útiles, como @WebService y @MultipartConfig.
Si reiniciamos Tomcat obtenemos estos tiempos:

[2015-02-25 16:09:21] INFORMACIËN: Initializing ProtocolHandler ["http-bio-80"]
[2015-02-25 16:09:21] INFORMACIËN: Initialization processed in 287 ms
[2015-02-25 16:09:21] INFORMACIËN: Arrancando servicio Catalina
[2015-02-25 16:09:21] INFORMACIËN: Starting Servlet Engine: Apache Tomcat/7.0.59
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\admin de la aplicaci¾n web
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\devel de la aplicaci¾n web
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\nws de la aplicaci¾n web
[2015-02-25 16:09:21] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\ROOT de la aplicaci¾n web
[2015-02-25 16:09:22] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\ROOT has finished in 610 m
s
[2015-02-25 16:09:22] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\nws has finished in 770 ms

[2015-02-25 16:09:22] INFORMACIËN: [Dinamica] SecurityFilter started for context: AdminConsole
[2015-02-25 16:09:22] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\admin has finished in 1.01
1 ms
[2015-02-25 16:09:23] INFORMACIËN: WSSERVLET14: inicializando el servlet de JAX-WS
[2015-02-25 16:09:23] INFORMACIËN: WSSERVLET12: inicializando el listener de contexto de JAX-WS
[2015-02-25 16:09:23] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\devel has finished in 1.59
1 ms
[2015-02-25 16:09:23] INFORMACIËN: Starting ProtocolHandler ["http-bio-80"]
[2015-02-25 16:09:23] INFORMACIËN: Server startup in 1617 ms

Una reducción de aproximadamente el 50%, nada mal.

Paso 2

A nivel de cada WebApp es necesario desactivar el scanning de TLDs, No sirve hacerlo en el context.xml global de Tomcat 7, ya lo probamos y no tiene efecto. Es necesario hacerlo en el context.xml privado de cada WebApp que está en /META-INF. Las WebApps creadas con Dinámica para correr en Tomcat usan la definición de su pool de conexiones a BD dentro de este archivo. Y el plugin del Framework para crear WebApps en Eclipse ya incluye esta entonación cuando crea el proyecto. Se trata de añadir el siguiente elemento (resaltado en amarillo):

<Context processTlds="false">

... el pool se define aquí ...

</Context>

Antes de esta optimización podríamos ver con JConsole el tiempo gastado en procesar TLDs aunque no los estemos usando:


Luego de aplicar el cambio en TODAS las WebApps instaladas, observamos que el tiempo del atributo tldScanTime=0 para cada WebApp.


Y el log de arranque del servicio muestra el resultado final de la entonación:

[2015-02-25 16:11:34] INFORMACIËN: Initializing ProtocolHandler ["http-bio-80"]
[2015-02-25 16:11:34] INFORMACIËN: Initialization processed in 297 ms
[2015-02-25 16:11:34] INFORMACIËN: Arrancando servicio Catalina
[2015-02-25 16:11:34] INFORMACIËN: Starting Servlet Engine: Apache Tomcat/7.0.59
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\admin de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\devel de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\ROOT de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Despliegue del directorio C:\tomcat7\webapps\nws de la aplicaci¾n web
[2015-02-25 16:11:34] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\nws has finished in 441 ms

[2015-02-25 16:11:34] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\ROOT has finished in 441 m
s
[2015-02-25 16:11:34] INFORMACIËN: [Dinamica] SecurityFilter started for context: AdminConsole
[2015-02-25 16:11:34] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\admin has finished in 561
ms
[2015-02-25 16:11:35] INFORMACIËN: WSSERVLET14: inicializando el servlet de JAX-WS
[2015-02-25 16:11:35] INFORMACIËN: WSSERVLET12: inicializando el listener de contexto de JAX-WS
[2015-02-25 16:11:35] INFORMACIËN: Deployment of web application directory C:\tomcat7\webapps\devel has finished in 1.15
3 ms
[2015-02-25 16:11:35] INFORMACIËN: Starting ProtocolHandler ["http-bio-80"]
[2015-02-25 16:11:35] INFORMACIËN: Server startup in 1179 ms

¡El tiempo de arranque se redujo en 64%! Otra ventaja de usar el estilo Dinámica de programación simple, sin las complicaciones asociadas usualmente al desarrollo web con Java.

Plataforma utilizada:

  • Tomcat 7.0.59
  • Java 1.8 update 31 x64
  • Windows 7 Home Premium x64


Esperamos les resulte de utilidad este mini blog, sobre todo a los suscriptores del Framework (Dinámica se vende por suscripción), aprovechamos de celebrar con esto los 11 años de Dinámica en producción, utilizado a escala global en docenas de proyectos que traspasan dominios de negocios y le ha permitido nutrirse y robustecerse como herramienta de hiper productividad.

miércoles, 23 de abril de 2014

Usando Apache Commons DBCP V2 en Tomcat 7

El componente por defecto para el manejo del pool de conexiones a base de datos en Tomcat 7 es DBCP v1.4, que si bien tiene varias mejoras de estabilidad con respecto a la versión que usa Tomcat 6, igual padece problemas de concurrencia, que se evidenciarán con alta carga de threads solicitando conexiones al pool, ya que el DBCP tiene que sincronizar el acceso al pool. Esto ha sido una fuente de problemas y cuellos de botella en Tomcat, más crítico en la v6 que en la v7.

A partir de Tomcat 7 hay un componente de Connection Pooling alternativo, Tomcat JDBC Pool, que provee acceso concurrente al pool y varias otras mejoras, sin embargo no viene configurado por defecto (ni siquiera en Tomcat 8) y es un proyecto relativamente nuevo. Su guía de configuración:

http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

El viejo proyecto Apache DBCP se renovó de forma importante el 2014 con su versión 2.0, que ahora usa el nuevo Apache Commons Pool, con mejoras de escalabilidad y desempeño, apoyándose en el paquete java.util.concurrent, requiere Java 7. Esta versión es el nuevo pool por defecto en Tomcat 8, y dice resolver los problemas de concurrencia de las versiones 1.2 y 1.4.

En Tomcat 7 se puede reemplazar el uso del DBCP v1.4 por el v2.0, es necesario añadir los siguientes JARs a la carpeta /lib de Tomcat:

commons-dbcp2-2.0.jar
commons-pool2-2.2.jar
commons-logging-1.1.3.jar

Los proyectos respectivos para descargar (en sus últimas versiones) cada JAR son:

http://commons.apache.org/proper/commons-dbcp/
http://commons.apache.org/proper/commons-pool/
http://commons.apache.org/proper/commons-logging/

En la definición del pool de conexiones en META-INF/context.xml de la WebApp se debe indicar el atributo factory, para que use el nuevo pool DBCP 2:



<Resource auth="Container" name="jdbc/dinamica" type="javax.sql.DataSource"> factory="org.apache.commons.dbcp2.BasicDataSourceFactory"
initialSize="3" maxIdle="10" maxWait="3000" maxTotal="100"
username="postgres" password="basica"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost/demodb"/>



El atributo maxActive ahora se llama maxTotal, esto requirió un cambio en la clase dinamica.SysInfo del framework Dinámica, para poder reportar correctamente en su página de estatus (/action/test) la información de los pools, sin importar si utilza DBCP v1.4 o DBCP v2. El resto es transparente para las WebApps.

Ahora puede utilizar la tecnología -supuestamente- superior de DBCP v2 en un producto solido como Tomcat 7, sin esperar a que salga Tomcat 8 o recurrir a un componente menos probado con el Tomcat JDBC Pool (por algo tampoco es el pool manager por defecto en Tomcat 8).

Los pools de conexiones concurrentes son "la nueva tendencia" en este tipo de componentes, porque hace tiempo que junto con sus ventajas también introdujeron el problema de la sincronización para acceder al pool, creando cuellos de botella. Hay varios productos de diversa calidad que ya usan esta técnica, facilitada desde hace pocos años por el paquete java.util.concurrent de Java SE, pero adolecen de un problema básico en relación a Tomcat, no vienen preparados para ser configurados como un Factory de DataSources, un reemplazo a lo "plugin" para el pool manager por defecto de Tomcat 7. El Apache DBCP v2 si puede ser usado de esa manera, como lo mostramos arriba.

Existe en este nuevo ecosistema de Pool Managers un producto que destaca, se llama HikariCP, y su documentación es muy interesante, aunque lamentablemente no provee configuración nativa como un Resource en Tomcat 7:

http://brettwooldridge.github.io/HikariCP/

Actualización del 26/04/2014

El autor de HikariCP nos proveyó de una versión de desarrollo (HikariCP-1.3.7-SNAPSHOT.jar) que incluye el DataSource Factory que permite usar este componente dentro de Tomcat 7 de forma transparente a las aplicaciones.

<Resource name="jdbc/dinamica" auth="Container" type="javax.sql.DataSource"
factory="com.zaxxer.hikari.HikariJNDIFactory"
username="postgres" password="basica"
driverClassName="org.postgresql.Driver"
jdbcUrl="jdbc:postgresql://localhost/demodb"/>

Lo malo es que no es compatible en cuanto a los nombres de los atributos, así que requiere nuevos atributos para indicar máximo de conexiones, tamaño inicial del pool, etc. Esto también supone un problema ya que no se puede monitorear este pool vía JMX con las facilidades de diagnóstico del framework Dinámica, y no tenemos planes de soportarlo en el corto plazo, además carece de atributos tan básicos y útiles como numActive y numIdle, que te dan de inmediato una radiografía del uso del pool. De todos modos el experimento con HikariCP ha sido positivo, en la medida que este producto vaya madurando y cumpla su promesa de estabilidad y velocidad, será una alternativa importante para mejorar el desempeño de un servidor Tomcat 7. Nuestro agradecimiento a Brett Wooldridge, el creador de HikariCP, por su rápido apoyo para implementar el soporte a Tomcat 7.

Saludos,
El Team Dinámica

jueves, 19 de septiembre de 2013

Actualizando el Java de un Tomcat 7 en Linux

Volvemos con un mini blog útil para los usuarios del Framework Dinámica que mantienen servidores Tomcat 7 en Linux.

Se asume que el Tomcat 7 está instalado en /opt/tomcat7 de acuerdo a nuestros lineamientos y viene de nuestra distribución para Dinámica:
http://www.martincordova.com/files/tomcat7.tgz

Oracle ahora provee paquetes TGZ con JRE para servidores de 64 bits en Linux y Windows. Solo hay que descomprimir y listo, no hay programa de instalación para ejecutar.

Esta conveniente distribución de la JVM y sus herramientas se descarga desde este link:
http://www.oracle.com/technetwork/java/javase/downloads/server-jre7-downloads-1931105.html

Escoja la opción "Linux x64".

Una vez que se copia el comprimido TGZ al directorio /opt, se procede a descomprimirlo con este comando, asumiendo que ya está en el directorio /opt:

sudo tar -xzf server-jre*
Esto creará el directorio /opt/jdk1.7.0_40

Ahora solo resta configurar el servicio Tomcat para que use este Java. Editar el archivo /opt/tomcat7/bin/catalina.sh y cambie la línea donde se define el JAVA_HOME al inicio del archivo:

JAVA_HOME=/opt/jdk1.7.0_40

Ya está listo, ahora reinicie el servicio Tomcat 7, la interrupción de servicio será mínima:

sudo /etc/init.d/tomcat stop (espere por el [OK])
sudo /etc/init.d/tomcat start
Ahora con el navegador puede solicitar la página de diagnóstico /action/test que tienen todas las Webapps construidas con Dinámica, debería ver un mensaje como este:


Listo. Para desinstalar este Java basta con eliminar la carpeta /opt/jdk1.7.0_40.

Actualización del 2014/04/23: Descargar directo desde Oracle al servidor Linux

Como saben, ya salió el Java 8, y hace pocos días salió una actualización crítica de seguridad de Java 6, 7 y 8 inclusive (1.8.0_5), para eliminar un conjunto de vulnerabilidades. Si tienen un hosting en USA y en su región tienen un ancho de banda pobre (como es nuestro caso en Caracas), saben que es tedioso subir al servidor una nueva versión del JRE que puede pesar unos 50MB. Sin embargo nuestro hosting en USA tiene muy alta velocidad para descargarse archivos de Oracle, así que con este comando logramos bajar el último update de Java 8 en 5 segundos, directo a nuestro server en USA, ingresamos con putty, nos colocamos en el directorio /opt y procedemos a ejecutar el comando:

wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u5-b13/server-jre-8u5-linux-x64.tar.gz"

El URL de descarga lo deberían obtener de la página de descarga de Oracle una vez que aceptan la licencia, luego lo copian en su comando, el URL cambia de acuerdo a los números de versiones de Java. Este es para bajar el Server JRE para Linux de 64 bits v1.8 update 5 (el último a la fecha).

El crédito por el tip de descarga con comando WGET no va para nosotros, sino para unos cuantos sitios webs que tratan el tema, uno en particular:

https://ivan-site.com/2012/05/download-oracle-java-jre-jdk-using-a-script/

martes, 8 de mayo de 2012

Cómo encriptar las contraseñas en Tomcat 7

Las contraseñas de los pools de conexiones a base de datos y del KeyStore de certificados (cuando se usa SSL) se almacenan en archivos XML de configuración en texto claro, por defecto. Nosotros no tenemos mayor problema con esto, ya que de todos modos hay que asegurar la instalación para restringir el acceso al servidor, pero es normal que en ambientes corporativos, como Bancos o Casas de Seguros esto no esté permitido, les representa un hallazgo de seguridad y piden que estas contraseñas sean almacenadas en forma encriptada, con algún algoritmo simétrico, como TripleDES con SHA1.

Si bien esto no le añade mucha más seguridad necesariamente, porque siempre se necesita otra llave para encriptar, es normal que los clientes soliciten este tipo de cambios, algo que los desarrolladores de Tomcat no parecen entender, por lo que pude ver en los forums, encriptar estas contraseñas ha sido una petición frecuente, pero que es despreciada por ellos con el argumento de que no ofrece mayor seguridad, etc, etc, en una mezcla de arrogancia y falta de pragmatismo.

Nosotros proveemos a los suscriptores de nuestra tecnología (Dinámica Deluxe) y a nuestros clientes un JAR que le añade a Tomcat 7 la capacidad de manejar las contraseñas de los pools de BD y de Keystore en forma encriptada. El JAR se llama dinamica-tomcat.jar y contiene unas clases que reemplazan las que vienen por defecto en Tomcat y que se ocupan de leer esas contraseñas. No fue un trabajo fácil, aunque debería serlo, porque Tomcat en su diseño no provee vías muy directas para afectar esta parte y proveer un lector de contraseña encriptada, sobre todo en el caso del KeyStore.

En el caso de los pools de conexiones a base de datos es un poco más fácil, requiere solo de una clase que extiende a BasicDataSourceFactory, luego esta clase es configurada en el archivo context.xml correspondiente, usando el atributo "factory".

En el caso del KeyStore, hay que crear una clase una extensión de la clase org.apache.tomcat.util.net.SSLImplementation, la cual será luego utilizada para configurar el conector SSL usando el atributo sslImplementationName. Para ser justos con el diseño de Tomcat, si bien pudo ser más fácil, al menos existe la forma de hacerlo vía extensión y configuración. El problema en el caso del KeyStore es que se requieren 2 clases más para lograr el efecto, básicamente tuvimos que identificar las clases, copiarlas de los fuentes de Tomcat a otro paquete y hacerle los ajustes para leer el password encriptado, que van en un método específico.

El JAR que proveemos contiene unos comandos para generar la contraseña encriptada, y también para codificar la llave que se usa para encriptar y desencriptar. Por ejemplo para generar la contraseña encriptada teniendo ya la llave codificada, se usa este comando:

@java -classpath ./dinamica-tomcat.jar -Dsemilla=cGVwaXRv dinamica.tomcat.MakePassword basica
En este caso la contraseña basica queda transformada en: A31CInaRgDk=

Así queda la configuración de un pool de conexiones a base de datos con el uso de contraseña encriptada y codificada en Base64:


El atributo factory indica que vamos a usar nuestra clase para leer la configuración, en particular el atributo password.

Para el caso del KeyStore se modifica server.xml para configurar el conector SSL de esta manera:


El atributo sslImplementation le dice a Tomcat 7 que use nuestra clase, la cual permite leer el atributo password encriptado.

De esta manera proveemos a nuestros clientes una forma sencilla para resolver el problema de las contraseñas en texto claro, sin configuraciones rebuscadas y suficiente para pasar una auditoria de seguridad.

Saludos,
el Team Dinámica