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.