For many years, there have been two dominant certificate infrastructures within the Foreman community: Puppet CA and Katello’s certificate tooling. There are on going efforts within the community that require bringing both a new design and consistency to this area. They are:
- Optional puppet
- Allowing Katello to install on an existing Foreman
- Cohesive installation experience
- Users ability to supply custom certificates to their Foreman and Katello infrastructure
The following proposal explores two options for how we can proceed. This new certificate handling will replace:
- Default use of Puppet CA
- Katello’s puppet-certs and katello-ssl-tool components
I’m trying out a few polls throughout the design to allow easier input on the structure of parts of the proposal.
Design Principles
To guide the design, I’ve put together the following principles to adhere to:
- Installations should by default provide certificate infrastructure
- Functionality must exist that can validate user provided certificates within the infrastructure
- User must be able to supply user generated server certificates
- User must be able to supply wildcard certificates
- Certificates should support alternate cnames
- Ability to generate certificates for easy Proxy installations
Proposal
Workflows
There are three overall scenarios:
- bootstrapping the CA and server certs to get Foreman up and running
- adding a foreman-proxy
- adding a feature that requires a service with certificates
The overall workflow would include a tool to:
- Generate locally or retrieve certificates remotely
- Place certificates in the right locations on disk for a service
- Create the right format when needed (e.g. PEM, keystore)
- Provide verification and debugging capabilities
Design
The tool would build upon lessons learned from Puppet CA usage and Katello’s puppet-certs usage to split the main functionality into two pieces: generate and deploy. The generate functionality would be used to create a set of default certificates when the user does not provide them. The deploy functionality would be used to place the certificates on the system, in the right places. The deployed certificates could come from the generated set or inputs from the user providing their custom certificates. The installation would be configured to point to the deployed certificate locations and have a common structure to set sane defaults. Summarizing the main principles (see command structure section for more details):
- Generate certificates if user does not supply any
- Deploy places certificates in their final locations for input to the installer
- Hand all certificates to the installer rather than having the main puppet apply generate them
- Store service certificates in a common pattern:
- /etc//pki
- Example:
- /etc/foreman/pki/certs/client_cert.pem
- /etc/candlepin/pki/certs/ca.cert
- /etc/<service>/pki
- /etc/pki/<service>
- /etc/<service>
- Other
0 voters
- Stand alone tool
- Built in to foreman-maintain
- Built in to installer
0 voters
Command Structure
- generate: creates all certificates needed into /var/lib/foreman-pki/
- Examples:
- foreman-pki generate
- Examples:
- deploy: copies certificates to their deployed locations at /etc//pki
- Examples:
- foreman-pki deploy all
- foreman-pki deploy apache
- Examples:
- view: displays x509 metadata for a certificate
- Examples:
- foreman-pki view candlepin
- foreman-pki view apache
- Examples:
- verify: verifies all deployed certificates
- Examples:
- foreman-pki verify all
- foreman-pk verify candlepin
- Examples:
- export: creates a tarball of a hostname’s certificate directory in /var/lib/foreman-pki//export
- Examples:
- foreman-pki export
- Examples:
- import: unbundles a tarball of certificates into /var/lib/foreman-pki/
- Examples:
- foreman-pki import <path_to_tarball>
- Examples:
Network Option
An additional design option is to provide certificate generation as a networked option. The tool would have the ability to reach out to a networked service that provides certificate signing to retrieve the certificates it needs. The tool would then translate these certificates and deploy them. For example, if certificates are needed for a Pulp on a proxy. Or, if a PKC12 keystore is required the tool would submit the signing request, retrieve the certificates, wrap them in a keystore and deploy to the location on disk.
This option could include support for interfacing with services like vault or certmonger. Or, this could be elevated to a first class citizen of Foreman to allow Proxies and their services to request certificates as services are spun up within the infrastructure.
This optional network support would be akin to the certmanager project within the Kubernetes ecosystem. I believe that this option could be a future option as it just adds a new way for the tool to fetch and deploy certificates rather than requiring an orthogonal design.
Technology Options
The tool will wrap native openssl constructs, so the language of choice should have good support for this, be familiar and easy to generate a CLI tool from without having to create too much boilerplate.
- Ruby
- Ansible (obsah-based)
- Python
- Ruby
- Python
- Ansible
- Other (e.g. Go, Javascript)
0 voters
Background Research
I’m including some notes around how other projects handle SSL in their workflows.
How Kubernetes handles SSL
For the main server:
- Generates a self-signed CA
a. Or user provides one - Generates a server certificate keypair
For nodes:
- Node registers itself to kubernetes with a token and CA hash:
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
- Node retrieves CA certificate from server and verifies hash of the CA
- Node sends CSR to server
- Node retrieves signed certificate
- Node retrieves CA over secure connection and verifies one final time
How Puppet handles SSL
For main server:
- Generates a self-signed CA
- Generates a server certificate keypair
For clients
- Client generates CSR and sends it to Puppet server via API
- Puppet server autosigns or manually signs and returns keypair to client to use