2020-09-25 00:55:53 +00:00
|
|
|
# Deploying local-user-authenticator
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
## What is local-user-authenticator?
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
The local-user-authenticator app is an identity provider used for integration testing and demos.
|
2020-09-10 02:06:39 +00:00
|
|
|
If you would like to demo Pinniped, but you don't have a compatible identity provider handy,
|
2020-09-25 00:55:53 +00:00
|
|
|
you can use Pinniped's local-user-authenticator identity provider. Note that this is not recommended for
|
2020-09-10 02:06:39 +00:00
|
|
|
production use.
|
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
The local-user-authenticator is a Kubernetes Deployment which runs a webhook server that implements the Kubernetes
|
2020-09-10 02:06:39 +00:00
|
|
|
[Webhook Token Authentication interface](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication).
|
|
|
|
|
|
|
|
User accounts can be created and edited dynamically using `kubectl` commands (see below).
|
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
## Installing the Latest Version with Default Options
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
```bash
|
|
|
|
kubectl apply -f https://github.com/vmware-tanzu/pinniped/releases/download/$(curl https://api.github.com/repos/vmware-tanzu/pinniped/releases/latest -s | jq .name -r)/install-local-user-authenticator.yaml
|
|
|
|
```
|
|
|
|
|
|
|
|
## Installing an Older Version with Default Options
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number
|
|
|
|
and use it to replace the version number in the URL below.
|
2020-09-10 13:50:17 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
```bash
|
|
|
|
# Replace v0.2.0 with your preferred version in the URL below
|
|
|
|
kubectl apply -f https://github.com/vmware-tanzu/pinniped/releases/download/v0.2.0/install-local-user-authenticator.yaml
|
|
|
|
```
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
## Installing with Custom Options
|
|
|
|
|
|
|
|
Creating your own deployment YAML file requires `ytt` from [Carvel](https://carvel.dev/) to template the YAML files
|
|
|
|
in the [deploy-local-user-authenticator](../deploy-local-user-authenticator) directory.
|
|
|
|
Either [install `ytt`](https://get-ytt.io/) or use the [container image from Dockerhub](https://hub.docker.com/r/k14s/image/tags).
|
|
|
|
|
|
|
|
1. `git clone` this repo and `git checkout` the release version tag of the release that you would like to deploy.
|
|
|
|
1. The configuration options are in [deploy-local-user-authenticator/values.yml](values.yaml).
|
|
|
|
Fill in the values in that file, or override those values using additional `ytt` command-line options in
|
|
|
|
the command below. Use the release version tag as the `image_tag` value.
|
2020-09-10 22:20:02 +00:00
|
|
|
2. In a terminal, cd to this `deploy-local-user-authenticator` directory
|
2020-09-25 00:55:53 +00:00
|
|
|
3. To generate the final YAML files, run `ytt --file .`
|
2020-09-10 02:06:39 +00:00
|
|
|
4. Deploy the generated YAML using your preferred deployment tool, such as `kubectl` or [`kapp`](https://get-kapp.io/).
|
2020-09-10 22:20:02 +00:00
|
|
|
For example: `ytt --file . | kapp deploy --yes --app local-user-authenticator --diff-changes --file -`
|
2020-09-10 02:06:39 +00:00
|
|
|
|
|
|
|
## Configuring After Installing
|
|
|
|
|
|
|
|
### Create Users
|
|
|
|
|
2020-09-10 13:50:17 +00:00
|
|
|
Use `kubectl` to create, edit, and delete user accounts by creating a `Secret` for each user account in the same
|
2020-09-25 00:55:53 +00:00
|
|
|
namespace where local-user-authenticator is deployed. The name of the `Secret` resource is the username.
|
2020-09-10 02:06:39 +00:00
|
|
|
Store the user's group membership and `bcrypt` encrypted password as the contents of the `Secret`.
|
2020-09-10 13:50:17 +00:00
|
|
|
For example, to create a user named `ryan` with the password `password123`
|
2020-09-10 02:06:39 +00:00
|
|
|
who belongs to the groups `group1` and `group2`, use:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
kubectl create secret generic ryan \
|
2020-09-10 22:20:02 +00:00
|
|
|
--namespace local-user-authenticator \
|
2020-09-10 02:06:39 +00:00
|
|
|
--from-literal=groups=group1,group2 \
|
2020-09-10 20:37:25 +00:00
|
|
|
--from-literal=passwordHash=$(htpasswd -nbBC 10 x password123 | sed -e "s/^x://")
|
2020-09-10 02:06:39 +00:00
|
|
|
```
|
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
Note that the above command requires a tool capable of generating a `bcrypt` hash. It uses `htpasswd`,
|
|
|
|
which is installed on most macOS systems, and can be
|
|
|
|
installed on some Linux systems via the `apache2-utils` package (e.g., `apt-get install apache2-utils`).
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
### Get the local-user-authenticator App's Auto-Generated Certificate Authority Bundle
|
|
|
|
|
|
|
|
Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint.
|
2020-09-10 02:06:39 +00:00
|
|
|
|
|
|
|
```bash
|
Rename many of resources that are created in Kubernetes by Pinniped
New resource naming conventions:
- Do not repeat the Kind in the name,
e.g. do not call it foo-cluster-role-binding, just call it foo
- Names will generally start with a prefix to identify our component,
so when a user lists all objects of that kind, they can tell to which
component it is related,
e.g. `kubectl get configmaps` would list one named "pinniped-config"
- It should be possible for an operator to make the word "pinniped"
mostly disappear if they choose, by specifying the app_name in
values.yaml, to the extent that is practical (but not from APIService
names because those are hardcoded in golang)
- Each role/clusterrole and its corresponding binding have the same name
- Pinniped resource names that must be known by the server golang code
are passed to the code at run time via ConfigMap, rather than
hardcoded in the golang code. This also allows them to be prepended
with the app_name from values.yaml while creating the ConfigMap.
- Since the CLI `get-kubeconfig` command cannot guess the name of the
CredentialIssuerConfig resource in advance anymore, it lists all
CredentialIssuerConfig in the app's namespace and returns an error
if there is not exactly one found, and then uses that one regardless
of its name
2020-09-18 22:56:50 +00:00
|
|
|
kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \
|
2020-09-10 02:06:39 +00:00
|
|
|
-o jsonpath={.data.caCertificate} \
|
|
|
|
| base64 -d \
|
2020-09-10 22:20:02 +00:00
|
|
|
| tee /tmp/local-user-authenticator-ca
|
2020-09-10 02:06:39 +00:00
|
|
|
```
|
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
### Configuring Pinniped to Use local-user-authenticator as an Identity Provider
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
When installing Pinniped on the same cluster, configure local-user-authenticator as an Identity Provider for Pinniped
|
2020-09-10 22:20:02 +00:00
|
|
|
using the webhook URL `https://local-user-authenticator.local-user-authenticator.svc/authenticate`
|
2020-09-25 00:55:53 +00:00
|
|
|
along with the CA bundle fetched by the above command. See [doc/demo.md](../doc/demo.md) for an example.
|
|
|
|
|
|
|
|
## Optional: Manually Testing the Webhook Endpoint After Installing
|
2020-09-10 02:06:39 +00:00
|
|
|
|
2020-09-25 00:55:53 +00:00
|
|
|
The following steps demonstrate the API of the local-user-authenticator app. Typically, a user would not need to
|
|
|
|
interact with this API directly. Pinniped will automatically integrate with this API if the local-user-authenticator
|
|
|
|
is configured as an identity provider for Pinniped.
|
2020-09-10 02:06:39 +00:00
|
|
|
|
|
|
|
1. Start a pod from which you can curl the endpoint from inside the cluster.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
kubectl run curlpod --image=curlimages/curl --command -- /bin/sh -c "while true; do echo hi; sleep 120; done"
|
|
|
|
```
|
|
|
|
|
|
|
|
1. Copy the CA bundle that was fetched above onto the new pod.
|
|
|
|
|
|
|
|
```bash
|
2020-09-10 22:20:02 +00:00
|
|
|
kubectl cp /tmp/local-user-authenticator-ca curlpod:/tmp/local-user-authenticator-ca
|
2020-09-10 02:06:39 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
1. Run a `curl` command to try to authenticate as the user created above.
|
|
|
|
|
|
|
|
```bash
|
2020-09-10 22:20:02 +00:00
|
|
|
kubectl -it exec curlpod -- curl https://local-user-authenticator.local-user-authenticator.svc/authenticate \
|
|
|
|
--cacert /tmp/local-user-authenticator-ca \
|
2020-09-10 02:06:39 +00:00
|
|
|
-H 'Content-Type: application/json' -H 'Accept: application/json' -d '
|
|
|
|
{
|
|
|
|
"apiVersion": "authentication.k8s.io/v1beta1",
|
|
|
|
"kind": "TokenReview",
|
|
|
|
"spec": {
|
|
|
|
"token": "ryan:password123"
|
|
|
|
}
|
|
|
|
}'
|
|
|
|
```
|
|
|
|
|
|
|
|
When authentication is successful the above command should return some JSON similar to the following.
|
|
|
|
Note that the value of `authenticated` is `true` to indicate a successful authentication.
|
|
|
|
|
|
|
|
```json
|
|
|
|
{"apiVersion":"authentication.k8s.io/v1beta1","kind":"TokenReview","status":{"authenticated":true,"user":{"username":"ryan","uid":"19c433ec-8f58-44ca-9ef0-2d1081ccb876","groups":["group1","group2"]}}}
|
|
|
|
```
|
|
|
|
|
2020-09-10 13:50:17 +00:00
|
|
|
Trying the above `curl` command again with the wrong username or password in the body of the request
|
2020-09-10 02:06:39 +00:00
|
|
|
should result in a JSON response which indicates that the authentication failed.
|
|
|
|
|
|
|
|
```json
|
|
|
|
{"apiVersion":"authentication.k8s.io/v1beta1","kind":"TokenReview","status":{"authenticated":false}}
|
|
|
|
```
|
|
|
|
|
|
|
|
1. Remove the curl pod.
|
2020-09-10 13:50:17 +00:00
|
|
|
|
2020-09-10 02:06:39 +00:00
|
|
|
```bash
|
|
|
|
kubectl delete pod curlpod
|
|
|
|
```
|