Repository navigation
Support bringing your own CA key/certificate - #105
Saeid-Abadi wants to merge 5 commits into
Conversation
Add ca_own_ca, ca_own_ca_key and ca_own_ca_cert so operators can install an existing CA key/certificate instead of having the role generate a new one. CA key/cert generation and the role's own CA renewal logic are skipped when ca_own_ca is enabled.
1ea83c3 to
11f8029
Compare
The "Fetch CA certificate" task ran for every host and fetched ca.crt to the same flat destination on the controller. With hosts running in parallel this races on the local file and intermittently fails with "checksum mismatch". The CA certificate is identical for all hosts, so fetch it once with run_once.
afeefghannam89
left a comment
There was a problem hiding this comment.
One more thought: there's no molecule scenario with ca_own_ca: true yet, Maybe you want so configure one to catch possible problems while providing own ca .
Side note: moving to a new CA later should work. x509_certificate signs a host cert again by itself when the CA changed. So put in the new key and cert, run the role again, and every host gets a new cert. The keys stay the same. Might be good to say that in the README.
| that: | ||
| - ca_own_ca_key is defined and ca_own_ca_key | length > 0 | ||
| - ca_own_ca_cert is defined and ca_own_ca_cert | length > 0 | ||
| fail_msg: "ca_own_ca is enabled but ca_own_ca_key/ca_own_ca_cert are not set" |
There was a problem hiding this comment.
Might be worth checking the files a bit more here. Right now only the paths are checked, so if key and cert don't match or the cert isn't a CA you only find out later when the first host cert gets signed. Comparing the public_key from openssl_privatekey_info and x509_certificate_info, plus a look for CA:TRUE in basic_constraints, would catch that right after the copy.
| dest: "{{ ca_ca_dir }}/ca.key" | ||
| owner: root | ||
| group: root | ||
| mode: 0600 |
There was a problem hiding this comment.
nit: when someone switches an existing setup over, this overwrites the generated CA key without a copy. backup: true would keep one around, up to you.
| mode: 0600 | |
| mode: 0600 | |
| backup: true |
| dest: "{{ ca_ca_dir }}/ca.crt" | ||
| owner: root | ||
| group: root | ||
| mode: 0644 |
There was a problem hiding this comment.
Same idea here if you add it above.
| mode: 0644 | |
| mode: 0644 | |
| backup: true |
| * `ca_email`: E-Mail address for certificates (default: `root@{{ ansible_fqdn }}`) | ||
| * `ca_altname_1`: First alt name (default: `{{ ansible_fqdn }}`) | ||
| * `ca_ca_keylength`: CA keylength (default: `2048`) | ||
| * `ca_own_ca`: Use an existing/external CA instead of letting the role generate one. When enabled, `ca_own_ca_key` and `ca_own_ca_cert` are copied to `ca_ca_dir` as `ca.key`/`ca.crt` instead of running the CA key/certificate generation. `ca_ca_password` must still match the passphrase of the provided key, since it's used to sign leaf certificates. The role's own CA renewal (`ca_renew`) does not apply to a provided CA; renewing it is up to the operator. (default: `false`) |
There was a problem hiding this comment.
I you like you can check the passphrase directly after copying the private key, something linke this:
openssl_privatekey_info with passphrase: "{{ ca_ca_password }}" returns can_parse_key: false for both an unencrypted key and a wrong passphrase, so one assert on that would catch it early than getting this error while creating the client certificate
| * `ca_ca_keylength`: CA keylength (default: `2048`) | ||
| * `ca_own_ca`: Use an existing/external CA instead of letting the role generate one. When enabled, `ca_own_ca_key` and `ca_own_ca_cert` are copied to `ca_ca_dir` as `ca.key`/`ca.crt` instead of running the CA key/certificate generation. `ca_ca_password` must still match the passphrase of the provided key, since it's used to sign leaf certificates. The role's own CA renewal (`ca_renew`) does not apply to a provided CA; renewing it is up to the operator. (default: `false`) | ||
| * `ca_own_ca_key`: Path on the Ansible control host to the CA private key to install when `ca_own_ca` is `true`. Consider encrypting it with `ansible-vault`. (no default) | ||
| * `ca_own_ca_cert`: Path on the Ansible control host to the CA certificate to install when `ca_own_ca` is `true`. (no default) |
There was a problem hiding this comment.
Maybe a short note on intermediates? Putting the intermediate first and the root after it in this file works for signing (issuer is the intermediate then) and the clients get the whole chain in ca.crt. With just the intermediate in ca.crt, openssl verify fails with unable to get issuer certificate.
Add ca_own_ca, ca_own_ca_key and ca_own_ca_cert so operators can install an existing CA key/certificate instead of having the role generate a new one. CA key/cert generation and the role's own CA renewal logic are skipped when ca_own_ca is enabled.