From f5b11a02391e13e28c0d7d48b8198a5a55e7279f Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Mon, 24 May 2021 19:08:01 -0700 Subject: [PATCH] New docs: 1) Concierge with Supervisor, and 2) Supervisor with OpenLDAP --- .../configure-concierge-supervisor-jwt.md | 104 ++++++ .../howto/configure-supervisor-with-gitlab.md | 7 +- .../howto/configure-supervisor-with-okta.md | 7 +- .../configure-supervisor-with-openldap.md | 298 ++++++++++++++++++ .../docs/howto/configure-supervisor.md | 3 +- 5 files changed, 412 insertions(+), 7 deletions(-) create mode 100644 site/content/docs/howto/configure-concierge-supervisor-jwt.md create mode 100644 site/content/docs/howto/configure-supervisor-with-openldap.md diff --git a/site/content/docs/howto/configure-concierge-supervisor-jwt.md b/site/content/docs/howto/configure-concierge-supervisor-jwt.md new file mode 100644 index 00000000..2f1bc3ec --- /dev/null +++ b/site/content/docs/howto/configure-concierge-supervisor-jwt.md @@ -0,0 +1,104 @@ +--- +title: Configure the Pinniped Concierge to validate JWT tokens issued by the Pinniped Supervisor +description: Set up JSON Web Token (JWT) based token authentication on an individual Kubernetes cluster using the Pinniped Supervisor as the OIDC Provider. +cascade: + layout: docs +menu: + docs: + name: Configure Concierge JWT Authentication with the Supervisor + weight: 25 + parent: howtos +--- +The Concierge can validate [JSON Web Tokens (JWTs)](https://tools.ietf.org/html/rfc7519), which are commonly issued by [OpenID Connect (OIDC)](https://openid.net/connect/) identity providers. + +This guide shows you how to use this capability in conjunction with the Pinniped Supervisor. +Each FederationDomain defined in a Pinniped Supervisor acts as an OIDC issuer. +By installing the Pinniped Concierge on multiple Kubernetes clusters, +and by configuring each cluster's Concierge as described below +to trust JWT tokens from a single Supervisor's FederationDomain, +your clusters' users may safely use their identity across all of those clusters. +Users of these clusters will enjoy a unified, once-a-day login experience for all the clusters with their `kubectl` CLI. + +If you would rather not use the Supervisor, you may want to [configure the Concierge to validate JWT tokens from other OIDC providers]({{< ref "configure-concierge-jwt" >}}) instead. + +## Prerequisites + +This how-to guide assumes that you have already [installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress, +and that you have [configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). + +## Create a JWTAuthenticator + +Create a JWTAuthenticator describing how to validate tokens from your Supervisor's FederationDomain: + +```yaml +apiVersion: authentication.concierge.pinniped.dev/v1alpha1 +kind: JWTAuthenticator +metadata: + name: my-supervisor-authenticator +spec: + # The value of the `issuer` field should exactly match the `issuer` + # field of your Supervisor's FederationDomain. + issuer: https://my-issuer.example.com/any/path + # You can use any `audience` identifier for your cluster, but it is + # important that it is unique for security reasons. + audience: my-unique-cluster-identifier-da79fa849 + # If the TLS certificate of your FederationDomain is not signed by + # a standard CA trusted by the Concierge pods, then specify its CA + # as a base64-encoded PEM. + tls: + certificateAuthorityData: LS0tLS1CRUdJTiBDRVJUSUZJQ0...0tLQo= +``` + +If you've saved this into a file `my-supervisor-authenticator.yaml`, then install it into your cluster using: + +```sh +kubectl apply -f my-supervisor-authenticator.yaml +``` + +Do this on each cluster in which you would like to allow users from that FederationDomain to log in. +Don't forget to give each cluster a unique `audience` value for security reasons. + +## Generate a kubeconfig file + +Generate a kubeconfig file for one of the clusters in which you installed and configured the Concierge as described above: + +```sh +pinniped get kubeconfig > my-cluster.yaml +``` + +This creates a kubeconfig YAML file `my-cluster.yaml`, unique to that cluster, which targets your JWTAuthenticator +using `pinniped login oidc` as an [ExecCredential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins). + +## Use the kubeconfig file + +Use the kubeconfig with `kubectl` to access your cluster: + +```sh +kubectl --kubeconfig my-cluster.yaml get namespaces +``` + +You should see: + +- The `pinniped login oidc` command is executed automatically by `kubectl`. + +- Pinniped directs you to login with whatever identity provider is configured in the Supervisor, either by opening + your browser (for upstream OIDC Providers) or by prompting for your username and password (for upstream LDAP providers). + +- In your shell, you see your clusters namespaces. + + If instead you get an access denied error, you may need to create a ClusterRoleBinding for username of your account + in the Supervisor's upstream identity provider, for example: + + ```sh + kubectl create clusterrolebinding my-user-admin \ + --clusterrole admin \ + --user my-username@example.com + ``` + +## Other notes + +- Pinniped kubeconfig files do not contain secrets and are safe to share between users. + +- Temporary session credentials such as ID, access, and refresh tokens are stored in: + - `~/.config/pinniped/sessions.yaml` (macOS/Linux) + - `%USERPROFILE%/.config/pinniped/sessions.yaml` (Windows). diff --git a/site/content/docs/howto/configure-supervisor-with-gitlab.md b/site/content/docs/howto/configure-supervisor-with-gitlab.md index e81d9e59..cd6bafa0 100644 --- a/site/content/docs/howto/configure-supervisor-with-gitlab.md +++ b/site/content/docs/howto/configure-supervisor-with-gitlab.md @@ -9,7 +9,8 @@ menu: weight: 35 parent: howtos --- -The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single "upstream" OIDC identity provider to many "downstream" cluster clients. +The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single +"upstream" identity provider to many "downstream" cluster clients. This guide shows you how to configure the Supervisor so that users can authenticate to their Kubernetes cluster using their GitLab credentials. @@ -17,7 +18,7 @@ cluster using their GitLab credentials. ## Prerequisites This how-to guide assumes that you have already [installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress, -and that you have [configured a `FederationDomain` to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). +and that you have [configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). ## Configure your GitLab Application @@ -137,4 +138,4 @@ spec: ## Next Steps -Now that you have configured the Supervisor to use GitLab, you may want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-jwt" >}}). +Now that you have configured the Supervisor to use GitLab, you will want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}}). diff --git a/site/content/docs/howto/configure-supervisor-with-okta.md b/site/content/docs/howto/configure-supervisor-with-okta.md index 46cc6ae7..5f39a5da 100644 --- a/site/content/docs/howto/configure-supervisor-with-okta.md +++ b/site/content/docs/howto/configure-supervisor-with-okta.md @@ -9,7 +9,8 @@ menu: weight: 35 parent: howtos --- -The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single "upstream" OIDC identity provider to many "downstream" cluster clients. +The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single +"upstream" identity provider to many "downstream" cluster clients. This guide shows you how to configure the Supervisor so that users can authenticate to their Kubernetes cluster using their Okta credentials. @@ -17,7 +18,7 @@ cluster using their Okta credentials. ## Prerequisites This how-to guide assumes that you have already [installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress, -and that you have [configured a `FederationDomain` to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). +and that you have [configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). ## Create an Okta Application @@ -107,4 +108,4 @@ Look at the `status` field. If it was configured correctly, you should see `phas ## Next steps -Now that you have configured the Supervisor to use Okta, you may want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-jwt" >}}). +Now that you have configured the Supervisor to use Okta, you will want to [configure the Concierge to validate JWTs issued by the Supervisor]({{< ref "configure-concierge-supervisor-jwt" >}}). diff --git a/site/content/docs/howto/configure-supervisor-with-openldap.md b/site/content/docs/howto/configure-supervisor-with-openldap.md new file mode 100644 index 00000000..9bd1e519 --- /dev/null +++ b/site/content/docs/howto/configure-supervisor-with-openldap.md @@ -0,0 +1,298 @@ +--- +title: Configure the Pinniped Supervisor to use OpenLDAP as an LDAP Provider +description: Set up the Pinniped Supervisor to use OpenLDAP login. +cascade: + layout: docs +menu: + docs: + name: Configure Supervisor With OpenLDAP + weight: 35 + parent: howtos +--- +The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single +"upstream" identity provider to many "downstream" cluster clients. + +[OpenLDAP](https://www.openldap.org) is a popular open source LDAP server for Linux/UNIX. + +This guide shows you how to configure the Supervisor so that users can authenticate to their Kubernetes +cluster using their identity from an OpenLDAP server. + +## Prerequisites + +This how-to guide assumes that you have already [installed the Pinniped Supervisor]({{< ref "install-supervisor" >}}) with working ingress, +and that you have [configured a FederationDomain to issue tokens for your downstream clusters]({{< ref "configure-supervisor" >}}). + +## An Example of Deploying OpenLDAP on Kubernetes + +*Note: If you already have an OpenLDAP server installed and configured, please skip to the next section to configure the Supervisor.* + +There are many ways to configure and deploy OpenLDAP. In this section we document a simple way to stand up an OpenLDAP +server in a way that would only be appropriate for a demo or testing environment. +**Following the steps below to deploy and configure OpenLDAP is not appropriate for production use.** +If you are interested in using OpenLDAP in a production setting, there are many other configuration and deployment +guides available elsewhere online which would be more appropriate. + +We will use [Bitnami's OpenLDAP container image](https://www.openldap.org) deployed on Kubernetes as a Deployment +in the same cluster as the Supervisor. We will enable TLS and create some test user accounts on the OpenLDAP server. + +First we'll need to create TLS serving certs for our OpenLDAP server. In this example, we'll use the `cfssl` CLI tool, +but they could also be created with other tools (e.g. `openssl` or `step`). + +```sh +cfssl print-defaults config > /tmp/cfssl-default.json + +echo '{"CN": "Pinniped Test","hosts": [],"key": {"algo": "ecdsa","size": 256},"names": [{}]}' > /tmp/csr.json + +cfssl genkey \ + -config /tmp/cfssl-default.json \ + -initca /tmp/csr.json \ + | cfssljson -bare ca + +cfssl gencert \ + -ca ca.pem -ca-key ca-key.pem \ + -config /tmp/cfssl-default.json \ + -profile www \ + -cn "ldap.openldap.svc.cluster.local" \ + -hostname "ldap.openldap.svc.cluster.local" \ + /tmp/csr.json \ + | cfssljson -bare ldap +``` + +The above commands will create the following files in your current working directory: +`ca-key.pem`, `ca.csr`, `ca.pem`, `ldap-key.pem`, `ldap.csr`, and `ldap.pem`. + +Next, create a namespace for the OpenLDAP deployment. + +```sh +kubectl create namespace openldap +``` + +Next, load some of those certificate files into a Kubernetes Secret in the new namespace, +so they can be available to the Deployment in the following step. + +```sh +kubectl create secret generic -n openldap certs \ + --from-file=ldap.pem --from-file=ldap-key.pem --from-file=ca.pem +``` + +Finally, create this Deployment for the OpenLDAP server. Also create a Service to expose the OpenLDAP +server within the cluster on the service network so the Supervisor can connect to it. + +```yaml +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ldap + namespace: openldap + labels: + app: ldap +spec: + replicas: 1 + selector: + matchLabels: + app: ldap + template: + metadata: + labels: + app: ldap + spec: + containers: + - name: ldap + image: docker.io/bitnami/openldap + imagePullPolicy: Always + ports: + - name: ldap + containerPort: 1389 + - name: ldaps + containerPort: 1636 + resources: + requests: + cpu: "100m" + memory: "64Mi" + readinessProbe: + tcpSocket: + port: ldap + initialDelaySeconds: 2 + timeoutSeconds: 90 + periodSeconds: 2 + failureThreshold: 9 + env: + - name: BITNAMI_DEBUG + value: "true" + - name: LDAP_ADMIN_USERNAME + value: "admin" + - name: LDAP_ADMIN_PASSWORD + # Rather than hard-coding passwords, please consider + # using a Secret with a random password! + # We are hard-coding the password to keep this example + # as simple as possible. + value: "admin123" + - name: LDAP_ROOT + value: "dc=pinniped,dc=dev" + - name: LDAP_USER_DC + value: "users" + - name: LDAP_USERS + value: "pinny,wally" + - name: LDAP_PASSWORDS + # Rather than hard-coding passwords, please consider + # using a Secret with random passwords! + # We are hard-coding the passwords to keep this example + # as simple as possible. + value: "pinny123,wally123" + - name: LDAP_GROUP + value: "users" + - name: LDAP_ENABLE_TLS + value: "yes" + - name: LDAP_TLS_CERT_FILE + value: "/var/certs/ldap.pem" + - name: LDAP_TLS_KEY_FILE + value: "/var/certs/ldap-key.pem" + - name: LDAP_TLS_CA_FILE + value: "/var/certs/ca.pem" + volumeMounts: + - name: certs + mountPath: /var/certs + readOnly: true + volumes: + - name: certs + secret: + secretName: certs +--- +apiVersion: v1 +kind: Service +metadata: + name: ldap + namespace: openldap + labels: + app: ldap +spec: + type: ClusterIP + selector: + app: ldap + ports: + - protocol: TCP + port: 636 + targetPort: 1636 + name: ldaps +``` + +If you've saved this into a file `openldap.yaml`, then install it into your cluster using: + +```sh +kubectl apply -f openldap.yaml +``` + +## Configure the Supervisor cluster + +Create an [LDAPIdentityProvider](https://github.com/vmware-tanzu/pinniped/blob/main/generated/1.20/README.adoc#ldapidentityprovider) in the same namespace as the Supervisor. + +For example, this LDAPIdentityProvider configures the LDAP entry's `uid` as the Kubernetes username, +and the `cn` (common name) of each group to which the user belongs as the Kubernetes group names. + +The specific values in this example are appropriate for the OpenLDAP server deployed by the previous section's steps, +but the values could be customized for your pre-existing LDAP server if you skipped the previous section. +We'll use the CA created in the steps above to trust the TLS certificates of the OpenLDAP server. + +```sh +cat <}}). +Then you'll be able to log into those clusters as any of the users from the OpenLDAP directory. diff --git a/site/content/docs/howto/configure-supervisor.md b/site/content/docs/howto/configure-supervisor.md index a5ddf342..f219c4b7 100644 --- a/site/content/docs/howto/configure-supervisor.md +++ b/site/content/docs/howto/configure-supervisor.md @@ -9,7 +9,8 @@ menu: weight: 35 parent: howtos --- -The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single "upstream" OIDC identity provider to many "downstream" cluster clients. +The Supervisor is an [OpenID Connect (OIDC)](https://openid.net/connect/) issuer that supports connecting a single +"upstream" identity provider to many "downstream" cluster clients. This guide show you how to use this capability to issue [JSON Web Tokens (JWTs)](https://tools.ietf.org/html/rfc7519) that can be validated by the [Pinniped Concierge]({{< ref "configure-concierge-jwt" >}}).