Ciberseguridad en la infraestructura
Cómo protege Eurmes lo que nunca debe ver nadie de fuera: contraseñas, claves de API y credenciales de los servicios que usa, quién puede acceder a ellas y cómo llegan a la aplicación sin pasar de mano en mano.
Gestión de secretos con Infisical
7 capítulos
Por qué repartir archivos .env entre el equipo es un riesgo y cómo lo sustituimos por un gestor de secretos centralizado y autoalojado: la elección de Infisical frente a HashiCorp Vault u OpenBao, su despliegue con Docker detrás de Nginx y SSH, el control de acceso por roles y la inyección de secretos al arrancar cada contenedor. Vídeo en castellano, con subtítulos en castellano, inglés, francés, alemán e italiano.
Ver transcripción del vídeoTranscripción
Muy buenas y bienvenidos a este vídeo donde voy a compartir con vosotros cómo podemos gestionar los secretos, API keys, variables de entorno sensibles, etcétera, de nuestro proyecto software siguiendo mejores prácticas de ciberseguridad, en vez de tener todos esos secretos distribuidos entre diferentes compañeros del equipo, o incluso teniendo el riesgo de que se filtren en nuestros repositorios de código. Para ello vamos a empezar con esta diapositiva. Lo primero que vemos al caer en esta diapositiva es que nuestro proyecto va a consumir de muchos servicios externos y además tiene variables de configuración internas muy sensibles. Por ejemplo, si nosotros queremos consumir la base de datos Mongo, tenemos que autenticarnos para gestionarla con un usuario y un password. Lo mismo para hacer copias de seguridad: necesitamos una clave para cifrar y descifrar los datos sobre los que hacemos una copia de seguridad. También para consumir proveedores de envío de email a nuestros usuarios, o para utilizar modelos de inteligencia artificial, tenemos que demostrar de alguna manera que somos quienes decimos ser mediante un token, un client ID, un secret o lo que sea. Entonces, una de las formas en las que se suele hacer esto, siguiendo malas prácticas, es repartir entre diferentes compañeros de equipo las variables de entorno. Vamos a ver directamente un ejemplo. Vale, lo primero que vemos en este proyecto es que en la parte de infraestructura tenemos un archivo que se suele llamar .env que va a tener las variables sensibles de nuestro proyecto. Estas variables nunca se van al repositorio de código. Normalmente lo que se hace es guardarlas en un archivo .env y la distribuimos entre los compañeros de equipo. Muchas veces como la distribuimos no es de la manera más segura, y de ahí este vídeo. Aquí lo que podemos ver es que tenemos diferentes contraseñas, identificadores, que nos permiten utilizar los servicios de infraestructura. Dentro del backend tenemos 2 microservicios: uno con Python, más orientado a la inteligencia artificial y al cloud, donde tenemos todas esas variables más asociadas a consumir modelos de inteligencia artificial o guardar datos en el cloud, consultar datos en el cloud. También tenemos un backend más orientado a lógica de negocio, donde aquí sobre todo lo que se busca es, pues, envío y manejo de usuarios, gestión de usuarios, progresos en la aplicación, exámenes, etcétera. Y también para todo esto tenemos contraseñas: cuánto dura una sesión, cómo se firman los tokens de la sesión y cómo se comprueba su integridad. Entonces vamos a ver las desventajas de este enfoque, donde guardamos en múltiples archivos todos estos secretos. En esta diapositiva hacemos el contraste entre utilizar múltiples archivos distribuidos entre diferentes compañeros del equipo con esas credenciales sensibles y utilizar un gestor de secretos centralizado. En el primer caso vemos que si de repente ha habido una fuga de datos donde un secreto ha sido comprometido, o añadimos un nuevo secreto, tenemos que estar avisando a cada uno de nuestros compañeros que tienen una copia de esos archivos .env de que actualicen, y muchas veces algunos se quedan desfasados, o tenemos que estar haciendo cambios manuales para que todos nos sincronicemos. E incluso cuando yo paso a un miembro del equipo una clave nueva porque ha habido una filtración o porque hay una nueva funcionalidad, a veces no se utilizan medios seguros. Entonces, la alternativa a esto es utilizar un gestor de secretos centralizado, donde tenemos una única fuente de verdad donde están todos esos secretos y controlamos quién puede leer, quién puede escribir, qué entorno puedes consultar, etcétera. Y además tenemos un control de historial de cambios, así como una auditoría de quién ve qué y cuándo. También añadir nuevos usuarios y quitar usuarios es muy fácil, y la rotación de claves también: si la cambio en un sitio, ya todos los compañeros de equipo se enteran. Podemos rotar una clave, bien porque ha sido comprometida o bien porque ha caducado, y al cambiarla, pues, listo: todo el mundo tiene ya esa clave actualizada. En la siguiente diapositiva vamos a ver por qué he elegido Infisical. Yo siempre lo que voy a buscar es ahorrar costes lo máximo posible, pero no solo hay que pensar en el ahora, sino también en el futuro, cuando el proyecto crezca mucho. Entonces, para lograr esto, tenemos que ser un poco independientes del proveedor. Si acoplamos todo nuestro sistema a, por ejemplo, las soluciones de Amazon o de HashiCorp Vault, lo que vemos es que al principio todo muy barato, pero después, cuando nuestra aplicación crece, vienen las facturas muy gordas, y tenemos que intentar evitar eso. Entonces, al final, lo que buscamos es que nosotros mismos hospedemos ese software que se encarga de la gestión de secretos centralizada. También buscamos que haya una comunidad software amplia y que sea fácil de configurar. Dentro de diferentes soluciones open source, lo que podemos ver es que tenemos esta. Yo recomiendo que, si tu proyecto crece mucho y empiezas a tener un equipo de infraestructura, o un equipo de backend más infraestructura, vayan más a OpenBao, porque tiene muchísimas más herramientas, y si hay un equipo que esté detrás podemos justificar que sea mucho más complejo configurarlo y montarlo, porque hay un equipo específico para esto. Yo, como estoy empezando, en fases tempranas, montando todo el proyecto, pues al final busco algo que sea más fácil de configurar y que a medio-largo plazo se mantenga gratis para la mayoría de las funcionalidades que busco, y ahí es donde entra Infisical. En esta diapositiva vamos a ver cómo funciona todo el ecosistema de Infisical. Nosotros vamos a tener 3 Dockers: uno de Infisical para gestionar esos secretos, un Postgres, donde guardamos los secretos de manera cifrada con una llave maestra que no está en el ecosistema de Infisical sino en otro, y además de eso tenemos una caché de Redis. Y además nosotros vamos a tener 3 Dockers para producción y otros para desarrollo, separados. Vale, 3, es decir, 3 Dockers por cada entorno, vale. Pero realmente, cuando nuestro proyecto es pequeñito, no hace falta hacer sobreingeniería separando en producción y desarrollo, sino simplemente con tener 2 proyectos en Infisical separados dentro de estos 3 Dockers ya es suficiente. Además, Nginx actúa como primera barrera de Infisical, de tal manera que cuando nosotros tenemos aislado producción, solo vamos a admitir IPs conocidas del servidor de producción para leer secretos, y solo cuando entramos a ese servidor vía SSH permitimos administrar. E incluso cuando Nginx lo sorteamos porque entramos por SSH, dentro de Infisical tenemos diferentes barreras para controlar que solo puedan entrar usuarios con determinado email y password. También en Infisical tenemos que desactivar que se puedan crear cuentas nuevas, aparte de la telemetría. La telemetría es muy importante desactivarla en el Docker de Infisical porque, si no, estaríamos mandando datos sensibles a terceros, y no hay nada más crítico que toda esta gestión de secretos. Además, cualquier identidad que sea diferente del servidor de producción, donde está toda la lógica de negocio y toda la aplicación desplegada, o de un administrador, debe ser bloqueada. Por eso es interesante tener aislado producción de desarrollo, porque en el caso de producción tenemos muy fino saber quién no está autorizado: una IP que sea diferente de la del servidor de producción donde desplegamos nuestra aplicación. Sin embargo, en el entorno de desarrollo, si somos 20 desarrolladores o somos 5 desarrolladores, son 5 máquinas, y estar controlando cada IP de cada máquina, que eso se va actualizando si reinicia alguien el router o lo que sea, es un poco más complicado. Por eso es interesante tener el entorno de de producción separado. Vamos a ver Infisical en acción. Lo primero que hay que aclarar es que la única manera de acceder a esta interfaz gráfica es mediante el protocolo SSH con nuestro servidor de producción; es decir, solo conectándonos de manera segura al servidor en el que se encuentra Infisical. Además hay una segunda barrera, que es que tenemos que poner un email y un password. Una vez entramos en Infisical, vemos una interfaz bastante amigable, y dentro de la gestión de secretos tenemos 3 proyectos: Eurmes en modo producción, Eurmes en modo desarrollo y un tutorial, que es el que vamos a ver. Normalmente las claves de desarrollo y de producción tienen que ser diferentes, y los usuarios y los roles que pueden leer o pueden configurar también tienen que ser diferentes. Dentro del proyecto de tutorial podemos ver que tenemos diferentes microservicios, y cada uno tendrá sus credenciales diferentes. Y aquí vemos que de manera muy fácil podemos gestionarlo todo, y que al cambiar una credencial en algún sitio podemos ver que afectará a todos los usuarios que consuman vía API todas las credenciales. O sea, tenemos todo centralizado en un único sitio. Además tenemos control de acceso: quién puede ver y quién solo puede administrar. Vale, aquí vemos el rol de ver, el rol de administrar, y se pueden crear muchos más roles con permisos más granulares en una versión de pago, aunque la versión gratis la verdad es que tiene bastantes cosas. Aquí vemos modo desarrollador y modo propietario. El propietario puede crear, eliminar, consultar, etcétera, y cada uno de estos roles puede autenticarse de muchísimas maneras diferentes para poder leer esos secretos, o los permisos que les demos. Y también los tokens que les demos tienen un tiempo de vida. Por ejemplo, el método clásico, con un client ID y un secreto: pues al final lo único que tenemos que tener es estas 2 variables para poder leer las variables de entorno, que es lo que normalmente vamos a darle a los diferentes compañeros del equipo de desarrollo. Además vemos aquí que tenemos muchísimos diferentes tipos de roles. Infisical tiene muchísimas más funcionalidades, tanto gratis como de pago. Yo siempre voy a lo gratis, y te animo a explorarla. La última pregunta que nos queda por responder es en qué momento inyectamos todos estos secretos. Normalmente nosotros vamos a tener un ecosistema de Dockers, es decir, de contenedores que ejecutan diferentes servicios de nuestra aplicación, y en cada uno de ellos vamos, en el momento de arranque, a inyectar secretos. ¿Cómo lo hacemos? Pues con un entrypoint .sh, que es un script que se ejecuta cuando levantamos nuestro servicio, y en ese momento, con las credenciales de Infisical, tocamos la puerta de Infisical y obtenemos todos los secretos, API keys, variables de entorno que tengamos, y las inyectamos en el proceso que se está ejecutando, por ejemplo para un backend o para un servicio de IA. Entonces pasamos de tener más de 50 variables de entorno distribuidas entre diferentes microservicios a tener un único punto accesible únicamente con 2 credenciales, normalmente el client ID y el password, o, si se te da un mecanismo de autenticación más complejo, pues también. Y controlamos quién accede y cuándo. Es mucho más fácil sincronizar entre diferentes compañeros esas credenciales que nos permiten acceder a Infisical, y cada una de esas credenciales tiene acceso a determinadas variables, no a todas. Entonces también es importante que, cuando el Docker arranca, intente obtener todos los secretos asociados a la aplicación; una vez los tengamos, hagamos un unset, es decir, borremos las credenciales de Infisical, y ya la aplicación puede arrancar con todas esas credenciales y funcionar normalmente. Bueno, espero que te haya gustado este vídeo, y lo último que me gustaría resaltar es que hay muchísimas más soluciones open source con muchas más herramientas. Yo lo he elegido sobre todo porque es muy fácil de configurar, tiene una interfaz gráfica muy amigable y una gestión muy amigable, y también tiene bastante funcionalidad gratis cuando lo hospedamos nosotros mismos en nuestros servidores, aunque es verdad que a largo plazo, si queremos 100 % gratis y tenemos suficiente equipo de infraestructura como para gestionarlo, recomiendo más OpenBao. Pues nada, espero que te haya gustado este vídeo y nos vemos pronto.