
En pleno 2019 securizar el tráfico de las aplicaciones con HTTPS debería ser prácticamente una obligación, tanto para accesos internos como externos. Por ello, en el presente artículo se pretende detallar las distintas posibilidades existentes en OpenShift para llevarlo a cabo así como las ventajas y desventajas de cada uno. ¡Comenzamos!
Caso de uso
Se dispone en OpenShift de un microservicio Java desarrollado con Spring Boot que se quiere securizar con HTTPS.
¿Que es HTTPS?
HTTPS es el acrónimo de Hypertext Transfer Protocol Secure o lo que es lo mismo, la versión segura de HTTP, el archiconocido protocolo de transferencia de datos.
La principal diferencia entre ambos es evidente: Con el protocolo HTTP los datos viajan en claro y son legibles o susceptibles de ser manipulados por todo aquel que los capture, mientras que con HTTPS van cifrados, por lo que de nada sirve interceptarlos (Siempre y cuando se implemente con un algoritmo seguro claro está).
Adicionalmenteaquellos dominios protegidos con HTTPS que cuenten con un certificado valido(no autofirmado ni expirado) garantizan que el usuario accede realmente a la páginaweb deseada.
OpenShift
En la plataforma de orquestación de contenedores de Red Hat se disponen las siguientes opciones para securizar el tráfico.
Secured Routes
Un route es un mecanismo de OpenShift para exponer un service en un hostname (por ejemplo, http://www.myapp.com) y hacerloaccesible a clientes externos a través de dicho dominio. Dicho de otra forma,en el caso de uso planteado permite exponer una URL pública para interactuarcon el microservicio en cuestión.
Un service en cambio es un balanceador de carga interno que redirige las peticiones entre las distintas réplicas de la aplicación. Al tratarse de un balanceador interno, no es accesible desde fuera de OpenShift y de ahí a la necesidad de los routes.
Dicho esto,OpenShift permite configurar los routes para funcionar con HTTPS. Basta conproporcionar un certificado y una clave pública. (En caso de no proporcionarninguno, se hará uso del certificado interno de la plataforma)
apiVersion: v1 kind: Route metadata: name: myapp-route spec: host: www.myapp.com to: kind: Service name: myapp-service tls: termination: edge key: |- -----BEGIN PRIVATE KEY----- [...] -----END PRIVATE KEY----- certificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- caCertificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE-----
La principal ventaja de esta solución es que la seguridad se gestiona de forma centralizada a nivel de plataforma y es completamente transparente para las aplicaciones.
Por contra, la comunicación no es segura de punto a punto. Es decir, la conexión únicamente está cifrada desde el cliente hasta el route, mientras que el tramo entre el route y la aplicación funciona bajo HTTP. Dependiendo de los requisitos de seguridad puede no ser suficiente.
Adicionalmente comentar que los routes no son compatibles con two-way SSL authentication, requisito que imponen muchas de las nubles publicas hoy en día.
Service Mesh (Istio)
Un service mesh es un software que normalmente se despliega junto a los microservicios y que se encarga de gestionar las comunicaciones hacia este. Trabaja a nivel de capa de red proporcionando funcionalidades tan necesarias como service discovery, load balancing, encryption, authentication/authorization, circuit breaker, monitoring o tracing entre otros, abstrayendo a los microservicios de ello.
Istio es el service mesh open source que ha irrumpido con fuerza en los meses y que está impulsado por Google. La versión 1.0 fue liberada el pasado 31 de Julio.

Para securizar el trafico HTTPS en Istio es necesario crear un objeto de tipo Gateway y proporcionar un certificado y una clave pública.
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: myapp-gateway spec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE serverCertificate: /etc/istio/ingressgateway-certs/tls.crt privateKey: /etc/istio/ingressgateway-certs/tls.key hosts: - "httpbin.myapp.com"
Al igual que con los routes de OpenShift, la principal ventaja de esta solución es que la seguridad se gestiona de forma centralizada a nivel de service mesh y es completamente transparente para las aplicaciones.
Por contra, la comunicación no es segura de punto a punto. Es decir, la conexión únicamente está cifrada desde el cliente hasta el pod en el que conviven el microservicio y el service mesh. La comunicación restante, a pesar de ser local, no está securizada y dependiendo de los requisitos de seguridad puede no ser suficiente.
App
La última alternativa es configurar la propia aplicación para funcionar bajo HTTPS, algo que en el caso de Spring es relativamente sencillo.
# SERVER server: port:8443 ssl: key-store: /deployments/config/security/tls-certificate.jks key-store-password: changeit keyStoreType: JKS keyAlias: myapp trust-store: /deployments/config/security/tls-certificate.jks trust-store-password: changeit
El truststore no es posible definirlo a través de la configuración, por lo que una posibilidad es hacerlo vía código.
@Configuration @ConditionalOnProperty(value = "server.ssl.trust-store", matchIfMissing = false) @EnableConfigurationProperties(SSLProperties.class) @AllArgsConstructor public class SecurityConfig implements WebMvcConfigurer { /** The ssl properties. */ private SSLProperties ssl; /** Trust Store Configuration Properties **/ @PostConstruct public void setProperty() { System.setProperty("javax.net.ssl.trustStore", ssl.getTrustStore()); System.setProperty("javax.net.ssl.trustStorePassword", ssl.getTrustStorePassword()); } }
Adicionalmente es necesario definir un route de OpenShift configurado como passthrough para permitir accesos externos.
apiVersion: v1 kind: Route metadata: name: myapp-route spec: host: www.myapp.com to: kind: Service name: myapp-service tls: termination: passthrough
La principal ventaja de esta solución es que la conexión esta securizada de punto a punto, inclusive el tramo relativo al pod.
Por contra, la gestión de esta recae sobre las propias aplicaciones, por lo que cada una es responsable de su implementación y mantenimiento.
Conclusiones
En conclusión, el caso de uso y los requisitos de seguridad determinan que soluciones se ajusta mejor a cada uno, pero para un humilde servidor el futuro se dibuja en forma de service mesh.