Introducción a la autorización de Kubernetes de Hashicorp Consul

Introducción a la autorización de Kubernetes de Hashicorp Consul

Así es, después del lanzamiento. Cónsul Hashicorp 1.5.0 A principios de mayo de 2019, en Consul se pueden autorizar aplicaciones y servicios que se ejecutan en Kubernetes de forma nativa.

En este tutorial crearemos paso a paso. POC (Prueba de concepto, PoC) que demuestra esta nueva característica. Se espera que tenga conocimientos básicos de Kubernetes y Hashicorp's Consul. Si bien puede usar cualquier plataforma en la nube o entorno local, en este tutorial usaremos la plataforma en la nube de Google.

Descripción

si vamos a Documentación del cónsul sobre su método de autorización., obtendremos una descripción general rápida de su propósito y caso de uso, así como algunos detalles técnicos y una descripción general de la lógica. Recomiendo encarecidamente leerlo al menos una vez antes de continuar, ya que ahora lo explicaré y analizaré todo.

Introducción a la autorización de Kubernetes de Hashicorp Consul

Diagrama 1: Descripción oficial del método de autorización del Cónsul

miremos dentro documentación para un método de autorización de Kubernetes específico.

Claro, hay información útil allí, pero no hay una guía sobre cómo usarla. Entonces, como cualquier persona en su sano juicio, busca orientación en Internet. Y luego... fracasas. Sucede. Arreglemos esto.

Antes de continuar con la creación de nuestra POC, volvamos a la descripción general de los métodos de autorización de Consul (Diagrama 1) y perfeccionémosla en el contexto de Kubernetes.

Arquitectura

En este tutorial, crearemos un servidor Consul en una máquina separada que se comunicará con un clúster de Kubernetes con el cliente Consul instalado. Luego crearemos nuestra aplicación ficticia en el pod y usaremos nuestro método de autorización configurado para leer desde nuestro almacén de claves/valores de Consul.

El siguiente diagrama detalla la arquitectura que estamos creando en este tutorial, así como la lógica detrás del método de autorización, que se explicará más adelante.

Introducción a la autorización de Kubernetes de Hashicorp Consul

Diagrama 2: descripción general del método de autorización de Kubernetes

Una nota rápida: no es necesario que el servidor Consul resida fuera del clúster de Kubernetes para que esto funcione. Pero sí, puede hacerlo de esta manera y de aquella.

Entonces, tomando el diagrama general de Consul (Diagrama 1) y aplicándole Kubernetes, obtenemos el diagrama anterior (Diagrama 2), y la lógica aquí es la siguiente:

  1. Cada pod tendrá una cuenta de servicio adjunta que contiene un token JWT generado y conocido por Kubernetes. Este token también se inserta en el pod de forma predeterminada.
  2. Nuestra aplicación o servicio dentro del pod inicia un comando de inicio de sesión en nuestro cliente Consul. La solicitud de inicio de sesión también incluirá nuestro token y nombre. especialmente creado método de autorización (tipo Kubernetes). Este paso #2 corresponde al paso 1 del diagrama del Cónsul (Esquema 1).
  3. Nuestro cliente Consul luego enviará esta solicitud a nuestro servidor Consul.
  4. ¡MAGIA! Aquí es donde el servidor Consul verifica la autenticidad de la solicitud, recopila información sobre la identidad de la solicitud y la compara con las reglas predefinidas asociadas. A continuación se muestra otro diagrama para ilustrar esto. Este paso corresponde a los pasos 3, 4 y 5 del diagrama general de Consul (Diagrama 1).
  5. Nuestro servidor Consul genera un token Consul con permisos de acuerdo con nuestras reglas de método de autorización especificadas (que hemos definido) con respecto a la identidad del solicitante. Luego devolverá ese token. Esto corresponde al paso 6 del diagrama del Cónsul (Diagrama 1).
  6. Nuestro cliente Consul reenvía el token a la aplicación o servicio solicitante.

Nuestra aplicación o servicio ahora puede usar este token de Consul para comunicarse con los datos de nuestro Consul, según lo determinado por los privilegios del token.

¡La magia se revela!

Para aquellos de ustedes que no están contentos con solo un conejo sacado de un sombrero y quieren saber cómo funciona... déjenme "mostrarles cuán profundo madriguera del conejo".

Como se mencionó anteriormente, nuestro paso "mágico" (Figura 2: Paso 4) es donde el servidor Consul autentica la solicitud, recopila información sobre la solicitud y la compara con las reglas predefinidas asociadas. Este paso corresponde a los pasos 3, 4 y 5 del diagrama general de Consul (Diagrama 1). A continuación se muestra un diagrama (Diagrama 3), cuyo propósito es mostrar claramente lo que realmente está sucediendo. bajo el capó método de autorización específico de Kubernetes.

Introducción a la autorización de Kubernetes de Hashicorp Consul

Diagrama 3: ¡La magia se revela!

  1. Como punto de partida, nuestro cliente Consul reenvía la solicitud de inicio de sesión a nuestro servidor Consul con el token de la cuenta de Kubernetes y el nombre de instancia específico del método de autorización que se creó anteriormente. Este paso corresponde al paso 3 de la explicación del circuito anterior.
  2. Ahora el servidor Cónsul (o líder) necesita verificar la autenticidad del token recibido. Por tanto, consultará el cluster de Kubernetes (a través del cliente Consul) y, con los permisos adecuados, averiguaremos si el token es genuino y a quién pertenece.
  3. Luego, la solicitud validada se devuelve al líder de Consul y el servidor de Consul busca la instancia del método de autorización con el nombre especificado en la solicitud de inicio de sesión (y el tipo de Kubernetes).
  4. El líder del cónsul identifica la instancia del método de autorización especificado (si se encuentra) y lee el conjunto de reglas vinculantes que se le atribuyen. Luego lee estas reglas y las compara con los atributos de identidad verificados.
  5. ¡TA-dah! Pasemos al paso 5 de la explicación del circuito anterior.

Ejecute Consul-server en una máquina virtual normal

De ahora en adelante, principalmente daré instrucciones sobre cómo crear esta POC, a menudo en viñetas, sin explicaciones de oraciones completas. Además, como se señaló anteriormente, usaré GCP para crear toda la infraestructura, pero puedes crear la misma infraestructura en cualquier otro lugar.

  • Inicie la máquina virtual (instancia/servidor).

Introducción a la autorización de Kubernetes de Hashicorp Consul

  • Cree una regla para el firewall (grupo de seguridad en AWS):
  • Me gusta asignar el mismo nombre de máquina tanto a la regla como a la etiqueta de red, en este caso "skywiz-consul-server-poc".
  • Busque la dirección IP de su computadora local y agréguela a la lista de direcciones IP de origen para que podamos acceder a la interfaz de usuario (UI).
  • Abra el puerto 8500 para la interfaz de usuario. Haga clic en Crear. Cambiaremos este firewall nuevamente pronto [enlace].
  • Agregue una regla de firewall a la instancia. Regrese al panel de VM en Consul Server y agregue "skywiz-consul-server-poc" al campo de etiquetas de red. Clic en Guardar.

Introducción a la autorización de Kubernetes de Hashicorp Consul

  • Instale Consul en una máquina virtual, consulte aquí. Recuerda que necesitas la versión Consul ≥ 1.5 [enlace]
  • Creemos un cónsul de un solo nodo: la configuración es la siguiente.

groupadd --system consul
useradd -s /sbin/nologin --system -g consul consul
mkdir -p /var/lib/consul
chown -R consul:consul /var/lib/consul
chmod -R 775 /var/lib/consul
mkdir /etc/consul.d
chown -R consul:consul /etc/consul.d

  • Para obtener una guía más detallada sobre cómo instalar Consul y configurar un clúster de 3 nodos, consulte aquí.
  • Cree un archivo /etc/consul.d/agent.json de la siguiente manera [enlace]:

### /etc/consul.d/agent.json
{
 "acl" : {
 "enabled": true,
 "default_policy": "deny",
 "enable_token_persistence": true
 }
}

  • Inicie nuestro servidor Cónsul:

consul agent 
-server 
-ui 
-client 0.0.0.0 
-data-dir=/var/lib/consul 
-bootstrap-expect=1 
-config-dir=/etc/consul.d

  • Debería ver un montón de resultados y terminar con "... actualización bloqueada por ACL".
  • Busque la dirección IP externa del servidor Consul y abra un navegador con esta dirección IP en el puerto 8500. Asegúrese de que se abra la interfaz de usuario.
  • Intente agregar un par clave/valor. Debe haber un error. Esto se debe a que cargamos el servidor Consul con una ACL y desactivamos todas las reglas.
  • Regrese a su shell en el servidor Consul e inicie el proceso en segundo plano o de alguna otra forma para que se ejecute e ingrese lo siguiente:

consul acl bootstrap

  • Busque el valor "SecretID" y regrese a la interfaz de usuario. En la pestaña ACL, ingrese el ID secreto del token que acaba de copiar. Copie SecretID en otro lugar, lo necesitaremos más tarde.
  • Ahora agregue un par clave/valor. Para esta prueba de concepto, agregue lo siguiente: clave: “custom-ns/test_key”, valor: “¡Estoy en la carpeta custom-ns!”

Lanzando un cluster de Kubernetes para nuestra aplicación con el cliente Consul como Daemonset

  • Cree un clúster K8s (Kubernetes). Lo crearemos en la misma zona que el servidor para un acceso más rápido y así podremos usar la misma subred para conectarnos fácilmente con direcciones IP internas. Lo llamaremos "skywiz-app-with-consul-client-poc".

Introducción a la autorización de Kubernetes de Hashicorp Consul

  • Como nota al margen, aquí hay un buen tutorial que encontré mientras configuraba un clúster POC Consul con Consul Connect.
  • También usaremos el gráfico de timón de Hashicorp con un archivo de valores extendido.
  • Instalar y configurar Helm. Pasos de configuración:

kubectl create serviceaccount tiller --namespace kube-system
kubectl create clusterrolebinding tiller-admin-binding 
   --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
./helm init --service-account=tiller
./helm update

### poc-helm-consul-values.yaml
global:
 enabled: false
 image: "consul:latest"
# Expose the Consul UI through this LoadBalancer
ui:
 enabled: false
# Allow Consul to inject the Connect proxy into Kubernetes containers
connectInject:
 enabled: false
# Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect.
client:
 enabled: true
 join: ["<PRIVATE_IP_CONSUL_SERVER>"]
 extraConfig: |
{
  "acl" : {
 "enabled": true,   
 "default_policy": "deny",   
 "enable_token_persistence": true 
  }
}
# Minimal Consul configuration. Not suitable for production.
server:
 enabled: false
# Sync Kubernetes and Consul services
syncCatalog:
 enabled: false

  • Aplicar tabla de timón:

./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc

  • Cuando intente ejecutarse, necesitará permisos para el servidor Consul, así que agreguémoslos.
  • Tenga en cuenta el "Rango de direcciones del pod" ubicado en el panel del clúster y consulte nuestra regla de firewall "skywiz-consul-server-poc".
  • Agregue el rango de direcciones del pod a la lista de direcciones IP y abra los puertos 8301 y 8300.

Introducción a la autorización de Kubernetes de Hashicorp Consul

  • Vaya a la interfaz de usuario de Consul y después de unos minutos verá aparecer nuestro clúster en la pestaña de nodos.

Introducción a la autorización de Kubernetes de Hashicorp Consul

Configurar un método de autorización integrando Consul con Kubernetes

  • Regrese al shell del servidor Consul y exporte el token que guardó anteriormente:

export CONSUL_HTTP_TOKEN=<SecretID>

  • Necesitaremos información de nuestro clúster de Kubernetes para crear una instancia del método de autenticación:
  • anfitrión de kubernetes

kubectl get endpoints | grep kubernetes

  • cuenta-de-servicio-kubernetes-jwt

kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "- name:"
kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:

  • El token está codificado en base64, así que descifralo usando tu herramienta favorita [enlace]
  • certificado-kubernetes-ca

kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:

  • Tome el certificado "ca.crt" (después de la decodificación base64) y escríbalo en el archivo "ca.crt".
  • Ahora cree una instancia del método de autenticación, reemplazando los marcadores de posición con los valores que acaba de recibir.

consul acl auth-method create 
-type "kubernetes" 
-name "auth-method-skywiz-consul-poc" 
-description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc" 
-kubernetes-host "<k8s_endpoint_retrieved earlier>" 
[email protected] 
-kubernetes-service-account-
jwt="<decoded_token_retrieved_earlier>"

  • A continuación, debemos crear una regla y adjuntarla al nuevo rol. Para esta parte puedes usar Consul UI, pero usaremos la línea de comando.
  • escribe una regla

### kv-custom-ns-policy.hcl
key_prefix "custom-ns/" {
 policy = "write"
}

  • aplicar la regla

consul acl policy create 
-name kv-custom-ns-policy 
-description "This is an example policy for kv at custom-ns/" 
-rules @kv-custom-ns-policy.hcl

  • Busque el ID de la regla que acaba de crear a partir del resultado.
  • Crea un rol con una nueva regla.

consul acl role create 
-name "custom-ns-role" 
-description "This is an example role for custom-ns namespace" 
-policy-id <policy_id>

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-ns-role' 
-selector='serviceaccount.namespace=="custom-ns"'

Por último configuraciones

Derechos de acceso

  • Crear derechos de acceso. Necesitamos darle permiso a Consul para verificar e identificar la identidad del token de la cuenta de servicio K8s.
  • Escribe lo siguiente en el archivo. [enlace]:

###skywiz-poc-consul-server_rbac.yaml
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: review-tokens
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: system:auth-delegator
 apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: service-account-getter
 namespace: default
rules:
- apiGroups: [""]
 resources: ["serviceaccounts"]
 verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: get-service-accounts
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: service-account-getter
 apiGroup: rbac.authorization.k8s.io

  • Creemos derechos de acceso

kubectl create -f skywiz-poc-consul-server_rbac.yaml

Conexión al cliente cónsul

  • Como se ha señalado aquíHay varias opciones para conectarse a daemonset, pero pasaremos a la siguiente solución simple:
  • Aplique el siguiente archivo [enlace].

### poc-consul-client-ds-svc.yaml
apiVersion: v1
kind: Service
metadata:
 name: consul-ds-client
spec:
 selector:
   app: consul
   chart: consul-helm
   component: client
   hasDNS: "true"
   release: skywiz-app-with-consul-client-poc
 ports:
 - protocol: TCP
   port: 80
   targetPort: 8500

  • Luego use el siguiente comando incorporado para crear un mapa de configuración [enlace]. Tenga en cuenta que nos referimos al nombre de nuestro servicio, sustitúyalo si es necesario.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
 labels:
   addonmanager.kubernetes.io/mode: EnsureExists
 name: kube-dns
 namespace: kube-system
data:
 stubDomains: |
   {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]}
EOF

Probando el método de autenticación

¡Ahora veamos la magia en acción!

  • Cree varias carpetas de claves más con la misma clave de nivel superior (es decir, /sample_key) y un valor de su elección. Cree políticas y roles apropiados para nuevas rutas clave. Haremos las fijaciones más tarde.

Introducción a la autorización de Kubernetes de Hashicorp Consul

Prueba de espacio de nombres personalizado:

  • Creemos nuestro propio espacio de nombres:

kubectl create namespace custom-ns

  • Creemos un pod en nuestro nuevo espacio de nombres. Escriba la configuración para el pod.

###poc-ubuntu-custom-ns.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-ns
 namespace: custom-ns
spec:
 containers:
 - name: poc-ubuntu-custom-ns
   image: ubuntu
   command: ["/bin/bash", "-ec", "sleep infinity"]
 restartPolicy: Never

  • Crear en:

kubectl create -f poc-ubuntu-custom-ns.yaml

  • Una vez que el contenedor se esté ejecutando, vaya allí e instale curl.

kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash
apt-get update && apt-get install curl -y

  • Ahora enviaremos una solicitud de inicio de sesión a Consul utilizando el método de autorización que creamos anteriormente [enlace].
  • Para ver el token ingresado desde su cuenta de servicio:

cat /run/secrets/kubernetes.io/serviceaccount/token

  • Escriba lo siguiente en un archivo dentro del contenedor:

### payload.json
{
 "AuthMethod": "auth-method-test",
 "BearerToken": "<jwt_token>"
}

  • ¡Iniciar sesión!

curl 
--request POST 
--data @payload.json 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Para completar los pasos anteriores en una línea (ya que ejecutaremos varias pruebas), puede hacer lo siguiente:

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • ¡Obras! Al menos debería hacerlo. Ahora tome el SecretID e intente acceder a la clave/valor al que deberíamos tener acceso.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: <SecretID_from_prev_response>”

  • Puede decodificar en base64 "Valor" y ver que coincide con el valor en custom-ns/test_key en la interfaz de usuario. Si utilizó el mismo valor anterior en este tutorial, su valor codificado sería IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.

Prueba de cuenta de servicio de usuario:

  • Cree una cuenta de servicio personalizada usando el siguiente comando [enlace].

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
 name: custom-sa
EOF

  • Cree un nuevo archivo de configuración para el pod. Tenga en cuenta que incluí la instalación de curl para ahorrar mano de obra :)

###poc-ubuntu-custom-sa.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-sa
 namespace: default
spec:
 serviceAccountName: custom-sa
 containers:
 - name: poc-ubuntu-custom-sa
   image: ubuntu
   command: ["/bin/bash","-ec"]
   args: ["apt-get update && apt-get install curl -y; sleep infinity"]
 restartPolicy: Never

  • Después de eso, ejecute un shell dentro del contenedor.

kubectl exec -it poc-ubuntu-custom-sa /bin/bash

  • ¡Iniciar sesión!

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Permiso denegado. Oh, nos olvidamos de agregar nuevas reglas vinculantes con los permisos apropiados, hagámoslo ahora.

Repita los pasos anteriores anteriores:
a) Cree una Política idéntica para el prefijo “custom-sa/”.
b) Cree un rol, llámelo "custom-sa-role"
c) Adjuntar la Política al Rol.

  • Cree un enlace de reglas (solo es posible desde cli/api). Tenga en cuenta el significado diferente de la bandera del selector.

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-sa-role' 
-selector='serviceaccount.name=="custom-sa"'

  • Inicie sesión nuevamente desde el contenedor "poc-ubuntu-custom-sa". ¡Éxito!
  • Consulte nuestro acceso a la ruta de clave personalizada-sa/.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: <SecretID>”

  • También puede asegurarse de que este token no otorgue acceso a kv en "custom-ns/". Simplemente repita el comando anterior después de reemplazar "custom-sa" con el prefijo "custom-ns".
    Permiso denegado.

Ejemplo de superposición:

  • Vale la pena señalar que todas las asignaciones vinculantes de reglas se agregarán al token con estos derechos.
  • Nuestro contenedor "poc-ubuntu-custom-sa" está en el espacio de nombres predeterminado, así que usémoslo para una vinculación de reglas diferente.
  • Repita los pasos anteriores:
    a) Cree una política idéntica para el prefijo de clave “predeterminado/”.
    b) Cree una función, asígnele el nombre "default-ns-role"
    c) Adjuntar la Política al Rol.
  • Crear un enlace de reglas (solo es posible desde cli/api)

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='default-ns-role' 
-selector='serviceaccount.namespace=="default"'

  • Regrese a nuestro contenedor "poc-ubuntu-custom-sa" e intente acceder a la ruta kv "default/".
  • Permiso denegado.
    Puede ver las credenciales especificadas para cada token en la interfaz de usuario en ACL > Tokens. Como puede ver, nuestro token actual solo tiene un "rol personalizado" adjunto. El token que estamos usando actualmente se generó cuando iniciamos sesión y solo había una vinculación de reglas que coincidía en ese momento. Necesitamos iniciar sesión nuevamente y usar el nuevo token.
  • Asegúrese de poder leer desde las rutas kv "custom-sa/" y "default/".
    Éxito!
    Esto se debe a que nuestro "poc-ubuntu-custom-sa" coincide con los enlaces de reglas "custom-sa" y "default-ns".

Conclusión

¿Gestión de tokens TTL?

Al momento de escribir este artículo, no existe una forma integrada de determinar el TTL para los tokens generados por este método de autorización. Sería una oportunidad fantástica para proporcionar una automatización segura de la autorización del Cónsul.

Existe una opción para crear manualmente un token con TTL:

Con suerte, en un futuro próximo podremos controlar cómo se generan los tokens (por regla o método de autorización) y agregar TTL.

Hasta entonces, se sugiere que utilice un punto final de cierre de sesión en su lógica.

Lea también otros artículos en nuestro blog:

Fuente: habr.com

Añadir un comentario