Kubernetes Secrets Decoder

Secrets Base64 Decoder

Keyring

Kubernetes Cluster zu managen bedeutet auch hin und wieder mit Secrets in Berührung zu kommen. Um den aktuellen Stand dieser kontrollieren zu können genügen die verfügbaren Aufrufe von kubectl alleine oft nicht. So ist der Inhalt im nicht menschlich lesbaren Format Base64 schwer zu überblicken und zu dekodieren. Die folgenden Zeilen soll dabei helfen diese Lücken auszufüllen und schneller an die gewünschten Informationen zu gelangen.

Aufbau der Secret Datei

Die Einträge in einer Secret Datei bestehen aus Schlüssel-Werte Paaren. Dabei ist der Wert eines Secret im Base64 Format anzugeben.

So sieht die Beispieldatei db-login-secret.yml Datei aus:

apiVersion: v1
kind: Secret
metadata:
   name: db-login
type: Opaque
data:
   MYSQL_ROOT_PASSWORD: dG9wc2VjcmV0
   MYSQL_PASSWORD: aXRzYXNlY3JldA==
   MYSQL_DATABASE: bXlkYg==
   MYSQL_USER: Zm9vYmFy
 

Nach einem apply Kommando steht das erstellte Secret für eine Einbindung in Container zur Verfügung.
kubectl apply -f db-login-secret.yml

Die Informationen aus einem describe Aufruf lassen dabei nicht auf den Inhalt schließen. Der Aufruf von

kubectl describe secret db-login

ergibt lediglich die Ausgabe:

Name:         db-login
Namespace:    default
Labels:       <none>
Annotations:  
Type:         Opaque

Data
====
MYSQL_DATABASE:       4 bytes
MYSQL_PASSWORD:       10 bytes
MYSQL_ROOT_PASSWORD:  9 bytes
MYSQL_USER:           6 bytes
 

Aufrufe mit Werten

Der Aufruf in einem definierten Format wie yaml oder json gibt hingegen auch den Wert des Secret zurück.

kubectl get secret db-login -o yaml

Unabhängig davon für welches Format man sich entscheidet, die Ausgabe der Werte sind immer in Base64.

apiVersion: v1
data:
 MYSQL_DATABASE: bXlkYg==
 MYSQL_PASSWORD: aXRzYXNlY3JldA==
 MYSQL_ROOT_PASSWORD: dG9wc2VjcmV0
 MYSQL_USER: Zm9vYmFy
kind: Secret
...
 

Werte dekodiert erhalten

Eine Methode die Werte als Klartext zu bekommen ist über das Tool jq zu gehen. Dieses muss allerdings installiert sein, um per Pipe benutzbar zu sein:

sudo apt-get install jq
kubectl get secret db-login -o json | jq '.data | map_values(@base64d)'

Die Ausgabe sieht bereits aus wie erwünscht
{
 "MYSQL_DATABASE": "mydb",
 "MYSQL_PASSWORD": "itsasecret",
 "MYSQL_ROOT_PASSWORD": "topsecret",
 "MYSQL_USER": "foobar"
}

Werte bekommen ohne externe Tools

Der Aufruf oben gelingt nur mit dem zusätzlich installierten Paket js. Wenn die Aufrufe über einen zentralen Server laufen und es so Einschränkungen für die Nutzern gibt eignet sich eher eine Variante über Bordmittel des Servers. Diese Variante ist auch portabler und funktioniert im Prinzip überall.


Einzelne Werte auslesen

Über das Ausgabeformat go-template ist eine einzelne Ausgabe eines Wertes menschenlesbar möglich. Um alle Werte zu erhalten müsste der Befehl für jeden Eintrag wiederholt werden.

kubectl get secret db-login -o go-template='{{.data.MYSQL_PASSWORD | base64decode}}'

alternativ

kubectl get secrets/db-pw-xplorer --template={{.data.MYSQL_PASSWORD}} | base64 -d


Alle Werte ausgeben über Skript

Um endgültig alle Werte in schöner Darstellungsform zu bekommen ist ein Aufruf über einen kleines Skript möglich. Für den Aufruf

decode_secret.sh db-login

wäre dieser kommentierte Inhalt nötig:

#!/usr/bin/env bash

# Set IFS to empty for having seperated lines to operate
IFS=

# call in yaml format
TEMP="$(kubectl get secret $1 -o yaml)"

# get number of first line of secrets
POS1=$(echo $TEMP | grep -n "^data:" | head -1 | cut -f1 -d:)
((POS1++))

# crop text before first secret
TEMP=$(echo $TEMP | tail +$POS1)

# get number of last line of secrets
POS2=$(echo $TEMP | grep -n '^[^[:blank:]]' | head -1 | cut -f1 -d:)
((POS2--))

# crop text after last secret and get rid of spaces
TEMP=$(echo $TEMP | head -$POS2 | sed -e "s/ //g")

# print decoded line
while IFS=$'\n' read -r LINE; do
       echo "$(echo $LINE | cut -f1 -d:): $(echo $LINE | cut -f2 -d: | base64 -d -w 0;)"
done <<< $TEMP
 

Die Ausgabe sieht damit aus wie folgt:

MYSQL_DATABASE: mydb
MYSQL_PASSWORD: itsasecret
MYSQL_ROOT_PASSWORD: topsecret
MYSQL_USER: foobar
 

Jeder kann sich nun die Methode die am besten zur Situation passt aussuchen.

Timo Hohmann - Serveradministrator



 

Viel Spaß beim ausprobieren.
Euer Timo. 

siehe auch:
Managed Kubernetes
Kubernetes Schulungen

Wenn ihr Fragen habt, meldet euch: info@mobilistics.de

Im Blog oder auf unserer Homepage könnt ihr gerne schauen, was wir sonst noch so machen.