smallstep / helm-charts

Helm packages for Kubernetes
Apache License 2.0
46 stars 72 forks source link

Step-Certificates: Inject without SSH keys #52

Open jodygilbert opened 3 years ago

jodygilbert commented 3 years ago

Currently if we enable inject when using the helm chart for step-certificates, I'm forced to include SSH keys. I don't need to use SSH keys in my environment, so can this be changed so that we do not need them with using inject?

opencommits commented 3 years ago

Yeah, had to create it with inject.enabled=false, took the ssh keys and did a helm upgrade with injection. This is really not a good way.. But thanks for the helm-charts anyway. 👍

estenrye commented 3 years ago

Yes, this can be changed. When I added the feature, I didn't consider that use case.

I might take a look a little bit later and see what I might be able to come up with.

estenrye commented 3 years ago

@jodygilbert I don't think you have to inject any ssh keys at all.

The default ca.json does not configure an SSH provisioner.

https://github.com/smallstep/helm-charts/blob/754c407e602965a2a0df30a56b0d58526405b46a/step-certificates/values.yaml#L44-L85

The helm chart sets the ssh certificate values as empty strings by default. Are you running into issues when you try to deploy the chart with those default values?

Here's an example Ansible Jinja2 template for configuring the helm chart values to deploy with the SSH provisioner enabled.

autocert:
  enabled: false
ca:
  db:
    enabled: false
    persistent: false
bootstrap:
  enabled: false
inject:
  enabled: true
  config:
    files:
      ca.json:
        root: /home/step/certs/root_ca.crt
        federateRoots: []
        crt: /home/step/certs/intermediate_ca.crt
        key: /home/step/secrets/intermediate_ca_key
        ssh:
          hostKey: /home/step/secrets/ssh_host_ca_key
          userKey: /home/step/secrets/ssh_user_ca_key
        address: 0.0.0.0:9000
        dnsNames:
          - "{{ step_certificates.helm_values.certificate_authority_url }}"
          - "{{ step_certificates.helm.name }}-step-certificates.{{ step_k8s_namespace }}.svc.cluster.local"
          - 127.0.0.1
        db:
          type: mysql
          datasource: "{{ step_mariadb.helm_values.auth.username }}:{{ step_mariadb.helm_values.auth.password }}@tcp({{ step_mariadb.helm.name }}:3306)/"
          database: "{{ step_mariadb.helm_values.auth.database }}"
        logger:
          format: json
        authority:
          claims:
            {{ step_certificates.helm_values.claims | to_nice_yaml | indent(12) }}
          provisioners:
            - type: ACME
              name: acme
              forceCN: true
              claims: {}
            - type: SSHPOP
              name: sshpop
              claims:
                enableSSHCA: true
            - type: JWK
              name: ansible_automation_token
              key: 
                alg: "{{ jwk_provisioner_pub.alg }}"
                crv: "{{ jwk_provisioner_pub.crv }}"
                kid: "{{ jwk_provisioner_pub.kid }}"
                kty: "{{ jwk_provisioner_pub.kty }}"
                use: "{{ jwk_provisioner_pub.use }}"
                x: "{{ jwk_provisioner_pub.x }}"
                'y': "{{ jwk_provisioner_pub.y }}"
              encryptedKey: "{{ jwk_provisioner_key.content | b64decode }}"
              claims:
                enableSSHCA: true
            - type: OIDC
              name: oidc
              clientID: "{{ step_certificates.helm_values.oidc.clientid }}"
              clientSecret: "{{ step_certificates.helm_values.oidc.clientsecret }}"
              configurationEndpoint: "{{ step_certificates.helm_values.oidc.configuration_endpoint }}"
              admins: {{ step_certificates.helm_values.oidc.admins | to_yaml }}
              domains: {{ step_certificates.helm_values.oidc.domains | to_yaml }}
              listenAddress: 127.0.0.1:{{ step_certificates.helm_values.oidc.ssh_client_listen_port }}
              ssh: true
              claims:
                enableSSHCA: true
        tls:
          cipherSuites:
            - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
            - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
            - TLS_AES_128_GCM_SHA256
          minVersion: 1.2
          maxVersion: 1.3
          renegotiation: false
        templates:
          ssh:
            user:
              - name: include.tpl
                type: snippet
                template: /home/step/config/ssh_user_include.tpl
                path: ~/.ssh/config
                comment: "#"
              - name: config.tpl
                type: file
                template: /home/step/config/ssh_user_config.tpl
                path: ssh/config
                comment: "#"
              - name: known_hosts.tpl
                type: file
                template: /home/step/config/ssh_user_known_hosts.tpl
                path: ssh/known_hosts
                comment: "#"
            host:
              - name: sshd_config.tpl
                type: snippet
                template: /home/step/config/ssh_host_sshd_config.tpl
                path: /etc/ssh/sshd_config
                comment: "#"
                requires:
                  - Certificate
                  - Key
              - name: ca.tpl
                type: snippet
                template: /home/step/config/ssh_host_sshd_ca.tpl
                path: /etc/ssh/ca.pub
                comment: "#"
      defaults.json:
        ca-url: https://{{ step_certificates.helm.name }}-step-certificates.{{ step_k8s_namespace }}.svc.cluster.local
        ca-config: /home/step/config/ca.json
        fingerprint: "{{ root_ca_fingerprint.stdout }}"
        root: /home/step/certs/root_ca.crt
    templates:
      ssh_user_include.tpl: |-
        {{ lookup('file', 'ssh_user_include.tpl') | indent(8) }}
      ssh_user_config.tpl: |-
        {{ lookup('file', 'ssh_user_config.tpl') | indent(8) }}
      ssh_user_known_hosts.tpl: |-
        {{ lookup('file', 'ssh_user_known_hosts.tpl') | indent(8) }}
      ssh_host_sshd_config.tpl: |-
        {{ lookup('file', 'ssh_host_sshd_config.tpl') | indent(8) }}
      ssh_host_sshd_ca.tpl: |-
        {{ lookup('file', 'ssh_host_sshd_ca.tpl') | indent(8) }}
  secrets:
    enabled: true
    ca_password: "{{ certificate_intermediate_ca.password | b64encode }}"
    provisioner_password: "{{ jwk_provisioner.password | b64encode }}"
    x509:
      intermediate_ca_key: |-
        {{ intermediate_ca_key.content | b64decode | indent(8) }}
      root_ca_key: |-
        {{ root_ca_key.content | b64decode | indent(8) }}
    ssh:
      host_ca_key: |-
        {{ ssh_host_ca_key.content | b64decode | indent(8) }}
      user_ca_key: |-
        {{ ssh_user_ca_key.content | b64decode | indent(8) }}
  certificates:
    enabled: true
    intermediate_ca: |-
      {{ intermediate_ca_certificate.content | b64decode | indent(6) }}
    root_ca: |-
      {{ root_ca_certificate.content | b64decode | indent(6) }}
    ssh_host_ca: |-
      {{ ssh_host_ca_certificate.content | b64decode | indent(6) }}
    ssh_user_ca: |-
      {{ ssh_user_ca_certificate.content | b64decode | indent(6) }}
service:
  type: NodePort
  port: 443
  targetPort: 9000
  nodePort: 32400
jodygilbert commented 3 years ago

Thanks for the example Jinja2 template. I do indeed run into issues if I deploy the chart with an empty string, here's the error I get:

Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: [unknown object type "nil" in ConfigMap.data.ssh_host_ca_key.pub, unknown object type "nil" in ConfigMap.data.ssh_user_ca_key.pub]

For now I'm adding dummy certs as I'm not using ssh, it would be nice to not have to include any though.

estenrye commented 3 years ago

@jodygilbert you might want to checkout 1.16.1. I added the capability to optionally inject SSH keys.