# Asegurando el acceso a nuestros Clusters Kubernetes con Teleport

Si no saben lo que es Teleport y por que me gusta, tal vez leyendo esta [entrada](https://blog.santiagoagustinfernandez.com/acceso-seguro-a-nuestro-servidores-ssh-via-teleport) se den cuenta. No solo encontrarán la explicación del producto, si no que tambien sabran conectarse a servidores, internos, de manera segura.

## Instalación de Teleport

Casi todas las organizaciones tienen más de un Cluster de Kubernetes, vamos a acceder de una manera sencilla vía **Teleport**. Algunas cosas que vamos a parametrizar, por un lado tenemos que poner nuestro correo para el **Challange** de LetsEncrypt y el nombre del Cluster, que no será ni más ni menos que el FQDN que queremos que sea alcanzado de manera pública.

```bash
helm install teleport-cluster \
--set acme=true \
--set acmeEmail=sfernandez@ironbox.com.ar \
--set clusterName=teleport.esprueba.com \
--create-namespace \
--namespace=teleport-cluster \
teleport/teleport-cluster
```

Ahora vemos el despliegue en nuestro Cluster, importante obtener la dirección de nuestro balanceador. En mi caso, es un Cluster Vanila por ende estoy usando [Metallb](https://metallb.universe.tf/).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707943401811/60a208b7-4c41-4467-97de-6109de95f23d.png align="center")

## Registro DNS

Es importante que nuestro registro DNS apunte a nuestro dirección pública. Para que funcione mi **prueba de concepto**, agregue el registro a mi DNS y luego abri el puerto 443 de mi firewall contra la dirección del balanceador. Si estas aca, leyendo, esto lo sabes hacer. Les hago un paneo de las configuraciones.

¿Cómo conocer mi direccion ip, publica?

```bash
curl ifconfig.me
181.XX.XX.XX
```

Agregamos el registro.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707944320284/6d4cd9bd-19ca-43c4-8915-bea8d7c4b39f.png align="center")

Ahora el Port Forwarding.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707944347944/fdbb8c9a-96e5-4078-8fde-9be75d00c09e.png align="center")

Podemos decir que tenemos nuestro Teleport configurado, listo para usar. Para tenerlo 100% funcionando, debemos abrir los demás puertos como el 3023, 3026, etc.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707944411063/346f9028-a39e-4096-aeba-92bb80198a88.png align="center")

Vamos a crear un usuario para poder administrar Teleport, para ello nos vamos a guardar el ID del Pod, con el siguiente comando, y luego mostrarlo.

```bash
POD=$(kubectl get pod -l app=teleport-cluster -o jsonpath='{.items[0].metadata.name}' -n teleport-cluster)
> echo $POD
teleport-cluster-auth-6bfc69dfb9-tlw66
```

Ahora que sabemos que el Pod de autenticación es **teleport-cluster-auth-6bfc69dfb9-tlw66**, vamos a crear el usuario teleport-admin e ingresamos al link que nos arroja.

```bash
kubectl exec -ti ${POD?} -n teleport-cluster  -- tctl users add teleport-admin --roles=editor,access --logins=root,teleport-admin
User "teleport-admin" has been created but requires a password. Share this URL with the user to complete user setup, link is valid for 1h:
https://teleport.esprueba.com:443/web/invite/d193d90c789a2cc616251f337f0b7182

NOTE: Make sure teleport.esprueba.com:443 points at a Teleport proxy which users can access.
```

Vamos a configurar la cuenta, al final necesitaremos agregar el 2FA. Yo utilice Google Authenticator.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707944992204/7bb1d844-52ad-44de-9d15-5e346dafc115.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945001620/4ac71181-4044-4931-9c51-7ba1ded88213.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945009842/152ca0a2-e074-4f32-b7e9-cc93bbc7bdc0.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945017661/731308ae-13a1-4599-b46e-b73e097d7a87.png align="center")

Ya tenemos lista nuestra cuenta, para ingresar. Una vez que realizamos el SingIn tenemos nuestro recurso disponible y listo para usar.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945345398/55b335b3-8586-499c-9c85-90dfa198d908.png align="center")

Aca los patrones de conexión al cluster.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945363975/2814c552-f467-4b41-8942-8dcd58c24d6e.png align="center")

Uala! Estamos listo para manejar nuestro cluster, de manera segura, desde el exterior.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945432177/164a8445-7354-4d7a-abeb-f025edb5c745.png align="center")

Aca vemos la auditoría de Teleport, con los pasos que acabamos de realizar. Una buena idea sería enviar todos estos logs a un SIEM, para tener un IR sobre cualquier inconveniente que podríamos llegar a tener.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707945563674/2837822c-3428-4eb6-9970-fa9028b23ac6.png align="center")

## Agregar un nuevo Cluster

Para agregar otro cluster, tendríamos que generar un **Token** para hacer el *Join* a Teleport. Para ello, en el cluster que tiene Teleport.

```bash
> TOKEN=$(kubectl exec -ti "${POD?}" -n teleport-cluster -- tctl nodes add --roles=kube --ttl=10000h --format=json | jq -r '.[0]')
> echo $TOKEN
e67180614246d9c90bf230582b33f882
```

Ya tenemos el **Token***e67180614246d9c90bf230582b33f882*, ahora tenemos que cargar las variables

```bash
export CLUSTER='minikube'
export PROXY='teleport.esprueba.com:443'
export TOKEN='e67180614246d9c90bf230582b33f882'
```

Hacemos un Switch sobre nuevo cluster, para poder instalar

```bash
helm install teleport-agent teleport/teleport-kube-agent --set kubeClusterName=${CLUSTER?} \
  --set proxyAddr=${PROXY?} --set authToken=${TOKEN?} --create-namespace --namespace=teleport-agent
```

Revisamos si levanto, en nuestro cluster minikube, el *teleport-agent*.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707946223654/fd922427-ff34-4bce-bed4-4afc7d1f7855.png align="center")

Cree un nuevo rol con privilegios kubernetes-admin.

```yaml
kind: role
metadata:
  # insert the name of your role here:
  name: kubernetes-admin
spec:
  # This example defines a typical role. It allows listing all resources
  # with typical developer credentials.
  allow:
    # List of Kubernetes cluster users can access the k8s API
    kubernetes_labels:
      '*': '*'
    # This role is mapped to Kubernetes 'developer' group.
    kubernetes_groups:
    - '{{internal.kubernetes_groups}}'
    - developer
    - admin
    - system:masters
    kubernetes_users:
    - '{{internal.kubernetes_users}}'
    - 'dev'

    # List of Kubernetes resources users can access with this role
    # This example allows access to all resources in all namespaces
    kubernetes_resources:
    - kind: '*'
      namespace: '*'
      name: '*'
      verbs: ['*']

    # List of allowed SSH logins
    logins: ['{{internal.logins}}', ubuntu, debian]

    # List of node labels that users can SSH into
    node_labels:
      '*': '*'

    # List of application labels users can access
    app_labels:
      '*': '*'

    # List of database labels users can access database servers
    db_labels:
      '*': '*'
    # List of databases on the database server users can access
    db_names:
    - '{{internal.db_names}}'
    - '*'
    # List of database users allowed to open database connections with
    db_users:
    - '{{internal.db_users}}'
    - developer

    # List of windows desktop access labels that users can open desktop sessions to
    windows_desktop_labels:
      '*': '*'
    # Windows logins a user is allowed to use for desktop sessions.
    windows_desktop_logins:
    - '{{internal.windows_logins}}'
    - developer

    # RBAC rules for various resources within a cluster. This
    # example provides access to the Audit Log and replaying a user's own sessions.
    rules:
    - resources:
      - event
      verbs:
      - list
      - read
    - resources:
      - session
      verbs:
      - read
      - list
      where: contains(session.participants, user.metadata.name)

  # The 'deny' section can have settings that override their 'allow' counterparts
  # It uses the same format as the 'allow' section
  deny:
    logins: ['guest']

  options:
      # Limits user credentials to 8 hours. After the time to live (TTL) expires,
      # users must re-login
      max_session_ttl: 8h0m0s
version: v7
```

Ahora creamos un usuario que tenga estos derechos.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707946603633/c0b51e55-2c99-478b-9ea6-3fbe5379292a.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707946610479/bbd8fba7-6af2-4380-a8c1-eea172734edd.png align="center")

Una vez completado el registro, el usuario puede iniciar sesión en el portal.

En la sección Kubernetes, puede ver a qué clústeres Kubernetes tiene acceso, y haciendo clic en el botón de conexión obtendrá todas las instrucciones para conectarse con el Cluster Kubernetes que seleccione.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707946908214/05881a38-51c6-4e1e-8e09-d2cfa50ff0ad.png align="center")

Cree un usuario llamado santiago con permisos sobre el rol kubernetes-admin, hare el SingUp y una vez conectado al Cluster de minikube listare los recursos.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707949368561/68dbe053-7048-4190-88c4-3e702940616b.png align="center")

Hay muchas maneras de aplicar permisos sobre este usuario, que puede y que no hacer. [Esta](https://goteleport.com/docs/kubernetes-access/controls/) documentación explica a detalle, cada permiso.

Estoy seguro que les será de utilidad.
