Ofuscando datos con Kubeless

Ofuscando datos con Kubeless

Como usar Serverless en Kubernetes con Kubeless

Hace unos días estaba jugando con Lambdas, en AWS, y me dio curiosidad probar Kubeless. No es ni más ni menos que Serverless en su estado agnóstico. Existen diferentes proyectos como OpenFaaS o Apache OpenWhisk. Si todavía no tuviste un acercamiento a Serverless, es un buen momento para empezar.

¿Que es Serverless?

Si bien significa sin servidor no es tan así. Dejas de usar un servidor físico o uno en la nube, identificable, para pasar a utilizar contenedores efímeros, temporales y sin estado donde se ejecutan los códigos de las aplicaciones. Estos contenedores se crean en el momento que ejecutas la aplicación y luego desaparecen, por lo que el servidor pasa a ser una parte menos visible del sistema.

Deberíamos verlo como funciones que se ejecutaran antes nuestra llamada. Pasamos de arquitecturas monolíticas a arquitecturas de micro servicios y seguramente pasaremos toda o casi toda nuestra arquitectura a este esquema de funciones, mas tarde o mas temprano.

Prueba de Concepto

Tenía ganas de probar algo agnóstico, para salirme del vendor Lock In. Lo que vamos hacer es lo siguiente: Vamos a instalar, en nuestro cluster de Kubernetes, Kubeless. A través de funciones consultar una Base de Datos MySQL y ofuscar parte del resultado. En este caso de uso lo que vamos a hacer es lo siguiente, vamos a presentar datos de negocio, como un OCR o PAM, ofuscados por la función.

Primero vamos a revisar nuestra base de datos, que es la siguiente:

Instalación de Kubeless, UI & Cliente

En este caso voy a realizar la PoC con Minikube. Vamos a instalar en el cluster bajo el namespace kubeless.

export RELEASE=$(curl -s https://api.github.com/repos/kubeless/kubeless/releases/latest | grep tag_name | cut -d '"' -f 4)
kubectl create ns kubeless
kubectl create -f https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless-$RELEASE.yaml

Revisamos nuestros pods.

Para instalar el cliente ejecutamos los siguientes comandos.

export OS=$(uname -s| tr '[:upper:]' '[:lower:]')
curl -OL https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless_$OS-amd64.zip && \
  unzip kubeless_$OS-amd64.zip && \
  sudo mv bundles/kubeless_$OS-amd64/kubeless /usr/local/bin/

Ahora vamos a instalar nuestra interfaz gráfica y acceder. Para ello deberemos conocer la dirección ip del cluster minikube y el puerto de NodePort. En este caso es 192.168.172.17 con el puerto 32361.

¡Accedemos a la Interfaz!

Aca les dejo el proyecto, para que tengan de guia. Es momento de subir nuestra función Python. Temas importantes, el nombre del programa es app.py y el handler es all. El programa conectará a la Base de Datos MySQL, para traer los datos, y luego con la función ofuscar realizaremos bloqueo de ciertos caracteres. Vamos a revisar el programa y subiremos la función. Siempre digo lo mismo: NO SOY DEV. ¡Es solo para jugar!

import pymysql, json

host = '172.17.0.8' # Direccion IP del Pod con MySQL
name = 'root'
password = 'password'
db_name = 'cards'
port = 3306

conn = pymysql.connect(host=host, port=port,user=name, passwd=password, db=db_name, connect_timeout=5)

def ofuscar(pam):
    # Posiciones a Cambiar
    posiciones = [5, 6, 7, 8, 10, 11, 12, 13]
    # Caracter de Reemplazo
    repl_char = '#'
    temp = list(pam)
    pam_ofuscado = [repl_char if idx in posiciones else ele for idx, ele in enumerate(temp)]
    pam_ofuscado = ''.join(pam_ofuscado)
    return pam_ofuscado


def all(event, context):
    with conn.cursor() as cur:
        cur.execute("select * from cardholder")
        rv = cur.fetchall()
        cardholder = []
        content = {}
        for result in rv:
            content = {'id': result[0], 'name': result[2], 'surname': result[1], 'pam': result[3], 'cvv': result[4]}
            content['pam'] = ofuscar(content['pam'])
            cardholder.append(content)
            content = {}
        jsonStr = json.dumps(cardholder)
        print(jsonStr)
    return jsonStr

¡Llego el momento de subirla! Para ello utilizamos el siguiente comando. El deploy que haremos se llamara cards, con el handler app.all y haremos referencia a la ruta del programa y el archivo de dependencias requeriments.txt.

kubeless function deploy cards --runtime python3.7 --handler app.all --from-file app.py --dependencies requirements.txt --servicePort 80 --namespace kubeless

Realizamos el deploy & listamos.

Revisamos en la UI y observaremos cómo se generó el Pod que ejecutara nuestra función. Por ejemplo: cards-7ffbdccf7-nktjf. Segun nuestro consumo y nuestras configuraciones tendremos un escalamiento horizontal para poder soportar todas las consultas a nuestras funciones.

¡Lista la magia! Ahora haremos la consulta vi CLI y uala, tenemos el dato ofuscado. El JSON que nos devuelve, la función, tiene el campo PAM con caracteres ocultos.

Como pueden ver con muy poco podemos agregar una capa mas de seguridad, cuando compartimos datos. Las maneras de utilizar las funciones son inimaginables, depende de nosotros. Espero que les haya gustado y tengan ganas de investigar como asegurar esas funciones, consumirlas por HTTP, etc.

¡Saludos!

Si te gusta jugar con Kubernetes te dejo este enlace para que te diviertas con Okteto, un cluster gratis.