Al finalizar la segunda parte de este artículo habíamos visto como las aplicaciones en Go y Java están Up & Running, al mismo tiempo que teníamos pareadas ambas con el SuperLacth Docker en nuestra aplicación móvil.
A partir de este momento podemos ver que cuando activamos Latch para poner el estado en OFF de nuestra app SuperLatch Docker las aplicaciones pasan a estar deshabilitadas y no funcionan, tal y como se puede ver en las imágenes siguientes.
El funcionamiento descrito en este proceso está disponible en el siguiente vídeo, donde se puede observar todo el proceso activación y bloqueo de la aplicación utilizando Latch:
Como podéis observar, cada segundo (tiempo preestablecido para que la aplicación compruebe el estado) se activa el popup en la aplicación Latch, indicando que se ha bloqueado una aplicación. Esto ocurre porque estamos utilizando la versión Comunidad de Latch (en la versión comercial se puede desactivar este popup con un simple flag).
SuperLatch en Kuberneters
Para correr esta misma idea sobre kubernetes, usaremos minikube. Uno de los cambios que haremos con respecto a la versión de docker-compose es que los valores que necesitamos para conectar con Latch (secret, account_id y app_id) se almacenarán en secretos de kubernetes, en vez de en variables de entorno. Para ello tenemos que modificar el fichero secrets.yaml que se encuentra dentro del directorio kube.
Los datos de los secretos se asignan codificados en Base64, así que lo primero que necesitamos hacer es codificar nuestros valores:
Account id:
Una vez minikube esté arrancado, ejecutamos:
Como se puede observar en la columna READY, los tres contenedores están corriendo (3/3). Una vez echo esto pues acceder a los servicios, para ello tenemos que ver que puertos a mapeado kubernetes:
Vemos que el servicio latch-poc-service tiene dos puertos mareados, pero no sabemos cuál es cuál. Podemos abrir nuestro navegador y probar a ver que puerto esta mapeado al servicio Java y cuál al servicio Go. O podemos ver la descripción del servicio:
Aquí podemos ver que el servido Java está mapeado al puerto del nodo 30823 y el de Go al 31723. A continuación podéis ver un vídeo completo de la PoC de SuperLatch Kubernetes:
En el caso de kubernetes estamos desplegando los tres contenedores en un mismo Pod. Si el servicio latch-master estuviera protegiendo sólo un servicio, desplegar ambos contenedores en un mismo Pod sería aceptable. En este caso donde tenemos dos contenedores (servicios) que proteger, idealmente se desplegaría cada contenedor en un Pod distinto y el volumen se haría global (PersistentVolume) o el estado de latch se almacenaría en algún lugar global dentro del cluster. En nuestro caso y para mostrar la prueba de concepto, lo consideramos aceptable poner todos los contenedores en un mismo Pod por temas de simplicidad.
Conclusiones finales
En esta prueba de concepto no sólo podemos ver como añadir una capa más de seguridad protegiendo nuestros contenedores con Latch, si no que además, como los contenedores que queremos proteger sólo necesitan leer de un fichero del sistema y no tienen que acceder a los servidores de Latch para comprobar el estado del mismo, a menos que estos se tuvieran que conectar con otros servidores externos, podrías bloquear las conexiones outbound, es decir, que no podrían salir a Internet como comentamos al principio de este artículo, lo cual añade una capa más de seguridad.
Otro beneficio que esta PoC nos muestra, éste desde el punto de vista del programador, es al ahorro en código y dependencias. Es decir, los servicios protegidos por Latch cómo no necesitan conectar y hablar el “protocolo Latch”, no tienes que añadir las dependencias de las SDK de Latch y por lo tanto no tienes que escribir código para integrar la misma. Esto, además, nos permitiría proteger con Latch cualquier servicio ser necesario un SDK de Latch específico para el lenguaje utilizado. Vamos que podrías crear un servicio en COBOL y protegerlo con Latch sin ningún tipo de problemas :)
Esperamos que esta PoC sirva tanto como idea para implementarlo en alguna aplicación con Docker o como simplemente una forma de aprender un poco más de Docker y kubernetes. Y por supuesto, en nuestro libro Docker: SecDevOps también puedes aprender más de Docker y kubernetes ;)
Happy Hacking Hackers!!!
***********************************************************************************
- SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps (1 de 3)
- SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps (2 de 3)
- SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps (3 de 3)
***********************************************************************************
Autores:
Fran Ramírez, (@cyberhadesblog) miembro del equipo de Crazy Ideas en CDO en Telefónica, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" y del blog Cyberhades.
Rafael Troncoso (@tuxotron) es DevOps Tech Lead en USCIS/DHS, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" y del blog Cyberhades.
Figura 17: SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus aplicaciones (3 de 3); |
A partir de este momento podemos ver que cuando activamos Latch para poner el estado en OFF de nuestra app SuperLatch Docker las aplicaciones pasan a estar deshabilitadas y no funcionan, tal y como se puede ver en las imágenes siguientes.
Figura 18: Aplicación Go se deshabilita porque el SuperLatch Docker está cerrado |
Figura 19: Aplicación Java deshabilitada también desde el SuperLatch Docker |
El funcionamiento descrito en este proceso está disponible en el siguiente vídeo, donde se puede observar todo el proceso activación y bloqueo de la aplicación utilizando Latch:
Figura 20: Demo de Activación y Desactivación de SuperLatch Docker
Como podéis observar, cada segundo (tiempo preestablecido para que la aplicación compruebe el estado) se activa el popup en la aplicación Latch, indicando que se ha bloqueado una aplicación. Esto ocurre porque estamos utilizando la versión Comunidad de Latch (en la versión comercial se puede desactivar este popup con un simple flag).
SuperLatch en Kuberneters
Para correr esta misma idea sobre kubernetes, usaremos minikube. Uno de los cambios que haremos con respecto a la versión de docker-compose es que los valores que necesitamos para conectar con Latch (secret, account_id y app_id) se almacenarán en secretos de kubernetes, en vez de en variables de entorno. Para ello tenemos que modificar el fichero secrets.yaml que se encuentra dentro del directorio kube.
Figura 21: Arquitectura de SuperLatch Kubernetes |
Los datos de los secretos se asignan codificados en Base64, así que lo primero que necesitamos hacer es codificar nuestros valores:
Account id:
echo -n "QNmcFJuPdqG3fdAUy2GqBw2Ehn2VF8ranuzFbvMHj2h27WPgbrnMmyGTwzqBFvda" | base64 UU5tY0ZKdVBkcUczZmRBVXkyR3FCdzJFaG4yVkY4cmFudXpGYnZNSGoyaDI3V1BnYnJuTW15R1R3enFCRnZkYQ==app_id:
echo -n "PAyrhmA3Hb8Qmf84N2Js" | base64 UEF5cmhtQTNIYjhRbWY4NE4ySnM=secret key:
echo -n "isiBUL6PMXgc7EfkVkZgbZirwfK9d7gPtfDVKrDt" | base64 aXNpQlVMNlBNWGdjN0Vma1ZrWmdiWmlyd2ZLOWQ3Z1B0ZkRWS3JEdA==Ahora ponemos esos valores en nuestro secrets.yaml:
apiVersion: v1Una vez tenemos dicho fichero modificado y grabado, lo siguiente sería crear nuestros objetos. Para ello asegúrate que minikube está arrancado:
kind: Secret
metadata:
name: latch-secrettype: Opaque
data:
app_id: UEF5cmhtQTNIYjhRbWY4NE4ySnM=
account_id: UU5tY0ZKdVBkcUczZmRBVXkyR3FCdzJFaG4yVkY4cmFudXpGYnZNSGoyaDI3V1BnYnJuTW15R1R3enFCRnZkYQ==
key: aXNpQlVMNlBNWGdjN0Vma1ZrWmdiWmlyd2ZLOWQ3Z1B0ZkRWS3JEdA==
minikube start Starting local Kubernetes v1.10.0 cluster... Starting VM... Getting VM IP address... Moving files into cluster... Setting up certs... Connecting to cluster... Setting up kubeconfig... Starting cluster components... Kubectl is now configured to use the cluster. Loading cached images from config file.
Una vez minikube esté arrancado, ejecutamos:
kubectl create -f secrets.yaml -f deployment.yaml -f service.yamlAsumiendo que estamos situado dentro del directorio kube, si estamos en otro directorio distinto al de nuestros ficheros yaml, pues tendrás que prefijar el fichero con la ruta correcta. Para comprobar que nuestro Pod se ha creado de forma correcta:
kubectl get pod NAME READY STATUS RESTARTS latch-poc-deployment-66d8f6c966-vslf7 3/3 Running 0
Como se puede observar en la columna READY, los tres contenedores están corriendo (3/3). Una vez echo esto pues acceder a los servicios, para ello tenemos que ver que puertos a mapeado kubernetes:
minikube service list |-------------|----------------------|--------------------------------| | NAMESPACE | NAME | URL | |-------------|----------------------|--------------------------------| | default | kubernetes | No node port | | default | latch-poc-service | http://192.168.99.100:30823 | | | | http://192.168.99.100:31723 | | kube-system | kube-dns | No node port | | kube-system | kubernetes-dashboard | No node port | |-------------|----------------------|--------------------------------|
Vemos que el servicio latch-poc-service tiene dos puertos mareados, pero no sabemos cuál es cuál. Podemos abrir nuestro navegador y probar a ver que puerto esta mapeado al servicio Java y cuál al servicio Go. O podemos ver la descripción del servicio:
kubectl describe service latch-poc-service Name: latch-poc-service Namespace: default Labels:Annotations: Selector: app=latch-poc-deployment Type: NodePort IP: 10.99.73.112 Port: java-port 8080/TCP TargetPort: 8080/TCP NodePort: java-port 30823/TCP Endpoints: 172.17.0.5:8080 Port: go-port 8081/TCP TargetPort: 8081/TCP NodePort: go-port 31723/TCP Endpoints: 172.17.0.5:8081 Session Affinity: None External Traffic Policy: Cluster Events: <none>
Aquí podemos ver que el servido Java está mapeado al puerto del nodo 30823 y el de Go al 31723. A continuación podéis ver un vídeo completo de la PoC de SuperLatch Kubernetes:
Figura 22 : PoC de SuperLatch Kubernetes
En el caso de kubernetes estamos desplegando los tres contenedores en un mismo Pod. Si el servicio latch-master estuviera protegiendo sólo un servicio, desplegar ambos contenedores en un mismo Pod sería aceptable. En este caso donde tenemos dos contenedores (servicios) que proteger, idealmente se desplegaría cada contenedor en un Pod distinto y el volumen se haría global (PersistentVolume) o el estado de latch se almacenaría en algún lugar global dentro del cluster. En nuestro caso y para mostrar la prueba de concepto, lo consideramos aceptable poner todos los contenedores en un mismo Pod por temas de simplicidad.
Conclusiones finales
En esta prueba de concepto no sólo podemos ver como añadir una capa más de seguridad protegiendo nuestros contenedores con Latch, si no que además, como los contenedores que queremos proteger sólo necesitan leer de un fichero del sistema y no tienen que acceder a los servidores de Latch para comprobar el estado del mismo, a menos que estos se tuvieran que conectar con otros servidores externos, podrías bloquear las conexiones outbound, es decir, que no podrían salir a Internet como comentamos al principio de este artículo, lo cual añade una capa más de seguridad.
Otro beneficio que esta PoC nos muestra, éste desde el punto de vista del programador, es al ahorro en código y dependencias. Es decir, los servicios protegidos por Latch cómo no necesitan conectar y hablar el “protocolo Latch”, no tienes que añadir las dependencias de las SDK de Latch y por lo tanto no tienes que escribir código para integrar la misma. Esto, además, nos permitiría proteger con Latch cualquier servicio ser necesario un SDK de Latch específico para el lenguaje utilizado. Vamos que podrías crear un servicio en COBOL y protegerlo con Latch sin ningún tipo de problemas :)
Esperamos que esta PoC sirva tanto como idea para implementarlo en alguna aplicación con Docker o como simplemente una forma de aprender un poco más de Docker y kubernetes. Y por supuesto, en nuestro libro Docker: SecDevOps también puedes aprender más de Docker y kubernetes ;)
Happy Hacking Hackers!!!
***********************************************************************************
- SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps (1 de 3)
- SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps (2 de 3)
- SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps (3 de 3)
***********************************************************************************
Autores:
Fran Ramírez, (@cyberhadesblog) miembro del equipo de Crazy Ideas en CDO en Telefónica, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" y del blog Cyberhades.
Rafael Troncoso (@tuxotron) es DevOps Tech Lead en USCIS/DHS, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" y del blog Cyberhades.
Si las claves van en base 64 da igual si las mandan en plano
ResponderEliminarHola Mauricio,
ResponderEliminarbuena observación. La razón por la que usamos base64 es porque es la forma en que kubernetes maneja los secretos, porque en estos se pueden almacenar no solo texto si no también ficheros binarios.
Aunque kubernetes ofrece como parte de Secrets una opción llamada stringData donde podríamos poner el texto en claro.
Un saludo