Skip to content

Instantly share code, notes, and snippets.

@lpabon
Last active October 26, 2019 11:35
Show Gist options
  • Save lpabon/fbae1aa51a2750d83460e7b6d32528c5 to your computer and use it in GitHub Desktop.
Save lpabon/fbae1aa51a2750d83460e7b6d32528c5 to your computer and use it in GitHub Desktop.
Setting up Portworx with security using a single token

Overview

The following describes how to setup Portworx security with a single token. The goal is for users to be authenticated by Kubernetes, then have a Kubernetes to Portworx token used by all users. This model protects the storage system from unwanted access from outside Kubernetes.

The following is based on Portworx 2.2 with security and CSI.

Download a spec

Generating secrets

PORTWORX_AUTH_SYSTEM_KEY=$(cat /dev/urandom | base64 | fold -w 64 | head -n 1)
PORTWORX_AUTH_STORK_KEY=$(cat /dev/urandom | base64 | fold -w 64 | head -n 1)
PORTWORX_AUTH_SHARED_SECRET=$(cat /dev/urandom | base64 | fold -w 64 | head -n 1)
  • Create a secret with the information
kubectl -n kube-system create secret generic pxkeys \
   --from-literal=system-secret=$PORTWORX_AUTH_SYSTEM_KEY \
   --from-literal=stork-secret=$PORTWORX_AUTH_STORK_KEY \
   --from-literal=shared-secret=$PORTWORX_AUTH_SHARED_SECRET

Test: Retreiving a key from the secret:

kubectl -n kube-system get secret pxkeys -o json | jq -r '.data."shared-secret"' | base64 -d

Add to Portworx yaml

  • Add to Portworx config yaml file as shown in documentation
  • Checklist
    1. Stork shared key needs to be added to stork and to Portworx as shown in [3]
    2. System key needs to be added to Portworx
    3. Shared key needs to be added to Portworx
    4. The Token issuer value needs to be added. The issuer is a string value which must identify the token generator. The token generator must set this value in the token itself under the iss claim. In this example, the issuer is set to portworx.com

Example diff

170c170
<              "-x", "kubernetes"]
---
>              "-x", "kubernetes", "-jwt_issuer", "portworx.com"]
178c178,192
<             
---
>             - name: "PORTWORX_AUTH_JWT_SHAREDSECRET"
>               valueFrom:
>                 secretKeyRef:
>                   name: pxkeys
>                   key: shared-secret
>             - name: "PORTWORX_AUTH_SYSTEM_KEY"
>               valueFrom:
>                 secretKeyRef:
>                   name: pxkeys
>                   key: system-secret
>             - name: "PORTWORX_AUTH_STORK_KEY"
>               valueFrom:
>                 secretKeyRef:
>                   name: pxkeys
>                   key: stork-secret
641a656,660
>         - name: "PX_SHARED_SECRET"
>           valueFrom:
>             secretKeyRef:
>               name: pxkeys
>               key: stork-secret

Generate token

First create a user configuration yaml and save it to a file. In this example, we will save the following to a file called user.yaml:

name: Kubernetes User
email: info@portworx.com
sub: kubernetes/info@portworx.com
roles: ["system.user"]
groups: ["kubernetes"]

Now you can create a token. Notice in the example below that we have set the issuer to match the setting in Portworx to portworx.com and have set the duration of the token to one year:

/opt/pwx/bin/pxctl auth token generate \
  --auth-config=user.yaml \
  --issuer=portworx.com \
  --shared-secret=$PORTWORX_AUTH_SHARED_SECRET \
  --token-duration=1y

You can then save the token in a Kubernetes secret. In the example below, it saves it as portworx/px-k8s-user:

kubectl -n portworx create secret generic px-k8s-user --from-literal=auth-token=ey..

Storage Class

Create a storage class to use secret. The following is a CSI based storage class:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: px-storage
provisioner: pxd.portworx.com
parameters:
  repl: "1"
  csi.storage.k8s.io/provisioner-secret-name: px-k8s-user
  csi.storage.k8s.io/provisioner-secret-namespace: portworx
  csi.storage.k8s.io/node-publish-secret-name: px-k8s-user
  csi.storage.k8s.io/node-publish-secret-namespace: portworx
  csi.storage.k8s.io/controller-expand-secret-name: px-k8s-user
  csi.storage.k8s.io/controller-expand-secret-namespace: portworx
allowVolumeExpansion: true

Example application

PVC:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-data
  annotations:
    volume.beta.kubernetes.io/storage-class: px-storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

MySQL:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: mysql
spec:
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
        version: "1"
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment