Skip to content

Commit

Permalink
spiffe-step-ssh server (#198)
Browse files Browse the repository at this point in the history
* Initial prototype of spire-step-ssh integration

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Ingress work, image cleanup and misc cleanup

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More values rework

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Rename chart spiffe-step-ssh

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Update to use shared lib

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Update spiffe-helper

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Use URLSAN rather then CN

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Lookup the sans.

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Make trust domain configurable

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add flag

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Make driver configurable

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add more configurables. Fix up docs to pass test.

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add some metadata

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix metadata

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add default values for lint

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Forgot values updates

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix metadata

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Start working on integration test

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Test

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Test

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix names

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More test bits

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More test bits

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More test bits

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More test bits

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More test bits

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More test bits

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More fixes

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More fixes

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More fixes

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix name conflict. Align naming

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix name

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add more logging

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Disable unneeded test. Add missing file.

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Setup more things

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add missing conf file

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix multiple svids

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix ci defaults

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix filename

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Try and get the linter to stop complaining...

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix perms

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More logs

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More setup

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fixes

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fixes

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add wait

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More logging

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Test ssh

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Restart fetchca on updates too

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix formating

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add missing file flag

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Increase timeout

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More flags

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix name

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Finish end to end test

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix ingress setting

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More logging/tests

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More testing

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix namespace

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fetch correct bundle

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Chart testing will fail as it depends on spire to be preinstalled. Weird dependency loop.

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Dont skip tls for testing

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More logging

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More debug

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More debug

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Pass intermediates

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix trustdomain

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add ca authority prefix

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* fix

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* fix

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* fix

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* ci test is just broken. Revert trying to fix it.

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Update charts/spiffe-step-ssh/files/ssh_x5c.tpl

Signed-off-by: kfox1111 <Kevin.Fox@pnnl.gov>

* Self review feedback

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Switch ingress to our more functional/easy type

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Simplify the template

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add cast

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add install notes

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix test

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Update tests for updated client

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix logging and entry

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Add missing dir

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix file location

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Update timeout

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* More logging

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix filename

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Fix perms

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>

* Update charts/spiffe-step-ssh/README.md

Signed-off-by: kfox1111 <Kevin.Fox@pnnl.gov>

* Apply suggestions from code review

Co-authored-by: Faisal Memon <fymemon@yahoo.com>
Signed-off-by: kfox1111 <Kevin.Fox@pnnl.gov>

---------

Signed-off-by: Kevin Fox <Kevin.Fox@pnnl.gov>
Signed-off-by: kfox1111 <Kevin.Fox@pnnl.gov>
Co-authored-by: Faisal Memon <fymemon@yahoo.com>
  • Loading branch information
kfox1111 and faisal-memon authored Nov 8, 2024
1 parent d5777c3 commit ec72596
Show file tree
Hide file tree
Showing 31 changed files with 1,405 additions and 1 deletion.
10 changes: 10 additions & 0 deletions .github/tests/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ while true; do
done
)
common_test_file_exists () (
count=20
while true; do
if [ -f "$1" ]; then exit 0; fi
sleep 2
count=$((count-1))
[ $count -le 0 ] && exit 1
done
)
# Used just for testing. You should provide your own values as described in the install instructions.
common_test_your_values () {
cat > /tmp/$$.example-your-values.yaml <<EOF
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/helm-chart-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ jobs:
- name: Run chart-testing (install)
run: |
helm install -n spire-server spire-crds charts/spire-crds
ct install --config ct.yaml --excluded-charts spire-crds \
ct install --config ct.yaml --excluded-charts spire-crds,spiffe-step-ssh \
--target-branch ${{ github.base_ref }}
- name: Test summary
Expand Down
42 changes: 42 additions & 0 deletions charts/spiffe-step-ssh/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
apiVersion: v2
name: spiffe-step-ssh
description: sshd signed host certificates using SPIFFE for trust and step CA

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.0.1

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

keywords: ["spiffe", "step", "step-ca", "ssh"]
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spiffe-step-ssh
sources:
- https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spiffe-step-ssh
icon: https://spiffe.io/img/logos/spire/icon/color/spire-icon-color.png
maintainers:
- name: kfox1111
email: Kevin.Fox@pnnl.gov

dependencies:
- name: spire-lib
repository: file://../spire/charts/spire-lib
version: 0.1.0
- name: step-certificates
alias: step
repository: https://smallstep.github.io/helm-charts/
version: 1.27.4
65 changes: 65 additions & 0 deletions charts/spiffe-step-ssh/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
spire-values.yaml
```
spire-server:
nodeAttestor:
httpChallenge:
enabled: true
controllerManager:
identities:
clusterSPIFFEIDs:
spiffe-step-ssh-config:
type: raw
namespaceSelector:
matchLabels:
"kubernetes.io/metadata.name": default
podSelector:
matchLabels:
app: spiffe-step-ssh
component: config
spiffe-step-ssh-fetchca:
type: raw
namespaceSelector:
matchLabels:
"kubernetes.io/metadata.name": default
podSelector:
matchLabels:
app: spiffe-step-ssh
component: fetchca
dnsNameTemplates:
- "spiffe-step-ssh-fetchca.{{ .TrustDomain }}"
```

```shell
helm upgrade --install -n spire-server spire-crds spire-crds --repo https://spiffe.github.io/helm-charts-hardened/ --create-namespace
helm upgrade --install -n spire-server spire spire --repo https://spiffe.github.io/helm-charts-hardened/ -f spire-values.yaml --set global.spire.ingressControllerType=ingress-nginx,spire-server.ingress.enabled=true
```

```shell
helm upgrade --install ingress-nginx ingress-nginx -n ingress-nginx --create-namespace --repo https://kubernetes.github.io/ingress-nginx --set controller.service.type=ClusterIP,controller.service.externalIPs[0]=$(minikube ip) --set controller.watchIngressWithoutClass=true --set controller.extraArgs.enable-ssl-passthrough=
```

```shell
PASSWORD=$(openssl rand -base64 48)
echo "$PASSWORD" > spiffe-step-ssh-password.txt
step ca init --helm --deployment-type=Standalone --name='My CA' --dns spiffe-step-ssh.example.org --ssh --address :8443 --provisioner default --password-file spiffe-step-ssh-password.txt > spiffe-step-ssh-values.yaml
```

ingress-values.yaml
```yaml
global:
spiffe:
ingressControllerType: ingress-nginx
stepIngress:
enabled: true
fetchCA:
ingress:
enabled: true
```
```shell
helm upgrade --install spiffe-step-ssh . --set caPassword=`cat spiffe-step-ssh-password.txt` -f spiffe-step-ssh-values.yaml -f ingress-values.yaml --set trustDomain=example.org
```

<!-- The parameters section is generated using helm-docs.sh and should not be edited by hand. -->

## Parameters
1 change: 1 addition & 0 deletions charts/spiffe-step-ssh/ci/default-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
trustDomain: example.org
13 changes: 13 additions & 0 deletions charts/spiffe-step-ssh/files/ssh_x5c.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- if eq (len .AuthorizationCrt.URIs) 1 }}
{{- $san := printf "%s" (index .AuthorizationCrt.URIs 0) }}
{{- if hasPrefix "spiffe://@TRUST_DOMAIN@/@PREFIX@/" $san }}
{{- $name := trimPrefix "spiffe://@TRUST_DOMAIN@/@PREFIX@/" $san }}
{
"type": {{ toJson .Type }},
"keyId": {{ toJson $name }},
"principals": [{{ toJson $name }}],
"extensions": {{ toJson .Extensions }},
"criticalOptions": {{ toJson .CriticalOptions }}
}
{{- end }}
{{- end }}
5 changes: 5 additions & 0 deletions charts/spiffe-step-ssh/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Installed {{ .Chart.Name }}…

Configure your ssh clients with known_hosts file with:

@cert-authority *.{{ .Values.trustDomain }} {{ .Values.inject.certificates.ssh_host_ca }}
83 changes: 83 additions & 0 deletions charts/spiffe-step-ssh/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "spiffe-step-ssh.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "spiffe-step-ssh.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "spiffe-step-ssh.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "spiffe-step-ssh.labels" -}}
helm.sh/chart: {{ include "spiffe-step-ssh.chart" . }}
{{ include "spiffe-step-ssh.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "spiffe-step-ssh.selectorLabels" -}}
app.kubernetes.io/name: {{ include "spiffe-step-ssh.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "spiffe-step-ssh.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "spiffe-step-ssh.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{/* Takes in a dictionary with keys:
* global - the standard global object
* ingress - a standard format ingress config object
*/}}
{{- define "spiffe-step-ssh.ingress-controller-type" }}
{{- $type := "" }}
{{- if ne (len (dig "spiffe" "ingressControllerType" "" .global)) 0 }}
{{- $type = .global.spiffe.ingressControllerType }}
{{- else if ne .ingress.controllerType "" }}
{{- $type = .ingress.controllerType }}
{{- else if (dig "openshift" false .global) }}
{{- $type = "openshift" }}
{{- else }}
{{- $type = "other" }}
{{- end }}
{{- if not (has $type (list "ingress-nginx" "openshift" "other")) }}
{{- fail "Unsupported ingress controller type specified. Must be one of [ingress-nginx, openshift, other]" }}
{{- end }}
{{- $type }}
{{- end }}
25 changes: 25 additions & 0 deletions charts/spiffe-step-ssh/templates/config-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "spiffe-step-ssh.fullname" . }}-config-deployment
labels:
{{- include "spiffe-step-ssh.labels" . | nindent 4 }}
data:
spiffe-helper.conf: |
agent_address = "/spiffe-workload-api/spire-agent.sock"
cmd = "sh"
cmd_args = "/config-deployment/update.sh"
cert_dir = "/certs"
svid_file_name = "tls.crt"
svid_key_file_name = "tls.key"
svid_bundle_file_name = "ca.pem"
add_intermediates_to_bundle = false
update.sh: |
#!/bin/sh
export ROOTS=$(base64 /certs/ca.pem | tr '\n' ' ' | sed 's/ //g')
echo Updating Roots to "$ROOTS"
cat /config/ca.json > /work/ca.json
yq e -i -ojson '.authority.provisioners |= map(select(.name == "x5c@spiffe").roots = env(ROOTS))' /work/ca.json
/helper/kubectl create configmap {{ include "spiffe-step-ssh.fullname" . }}-config -n "{{ .Release.Namespace }}" --from-file=/work/ca.json --from-file=/config/defaults.json --from-file=/config/ssh_x5c.tpl --dry-run=client -o yaml | /helper/kubectl apply -f -
/helper/kubectl rollout restart statefulset {{ include "spiffe-step-ssh.fullname" . }} -n "{{ .Release.Namespace }}"
echo $?
Loading

0 comments on commit ec72596

Please sign in to comment.