-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add first guides for creating certificates.
- Loading branch information
1 parent
e9bc7c7
commit c961896
Showing
3 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
sections: | ||
- title: Scenario Guides | ||
toctree: | ||
- guide_selfsigned | ||
- guide_ownca |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
.. _ansible_collections.community.crypto.docsite.guide_ownca: | ||
|
||
How to create a small CA | ||
======================== | ||
|
||
The `community.crypto collection <https://galaxy.ansible.com/community/crypto>`_ offers multiple modules that create private keys, certificate signing requests, and certificates. This guide shows how to create your own small CA and how to use it to sign certificates. | ||
|
||
In all examples, we assume that the CA's private key is password protected, where the password is provided in the ``secret_ca_passphrase`` variable. | ||
|
||
Set up the CA | ||
------------- | ||
|
||
Any certificate can be used as a CA certificate. You can create a self-signed certificate (see :ref:`ansible_collections.community.crypto.docsite.guide_selfsigned`), use another CA certificate to sign a new certificate (using the instructions below for signing a certificate), ask (and pay) a commercial CA to sign your CA certificate, etc. | ||
|
||
The following instructions show how to set up a simple self-signed CA certificate. | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create private key with password protection | ||
community.crypto.openssl_privatekey: | ||
path: /path/to/ca-certificate.key | ||
passphrase: "{{ secret_ca_passphrase }}" | ||
|
||
- name: Create certificate signing request (CSR) for CA certificate | ||
community.crypto.openssl_csr_pipe: | ||
privatekey_path: /path/to/ca-certificate.key | ||
privatekey_passphrase: "{{ secret_ca_passphrase }}" | ||
common_name: Ansible CA | ||
use_common_name_for_san: false # since we do not specify SANs, don't use CN as a SAN | ||
basic_constraints: | ||
- 'CA:TRUE' | ||
basic_constraints_critical: yes | ||
key_usage: | ||
- keyCertSign | ||
key_usage_critical: true | ||
register: ca_csr | ||
|
||
- name: Create self-signed CA certificate from CSR | ||
community.crypto.x509_certificate: | ||
path: /path/to/ca-certificate.pem | ||
csr_content: "{{ ca_csr.csr }}" | ||
privatekey_path: /path/to/ca-certificate.key | ||
privatekey_passphrase: "{{ secret_ca_passphrase }}" | ||
provider: selfsigned | ||
|
||
Use the CA to sign a certificate | ||
-------------------------------- | ||
|
||
To sign a certificate, you must pass a CSR to the :ref:`community.crypto.x509_certificate module <ansible_collections.community.crypto.x509_certificate_module>` or :ref:`community.crypto.x509_certificate_pipe module <ansible_collections.community.crypto.x509_certificate_pipe_module>`. | ||
|
||
In the following example, we assume that the certificate to sign (including its private key) are on ``server_1``, while our CA certificate is on ``server_2``. We do not want any key material to leave each respective server. | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create private key for new certificate on server_1 | ||
community.crypto.openssl_privatekey: | ||
path: /path/to/certificate.key | ||
delegate_to: server_1 | ||
run_once: true | ||
|
||
- name: Create certificate signing request (CSR) for new certificate | ||
community.crypto.openssl_csr_pipe: | ||
privatekey_path: /path/to/certificate.key | ||
subject_alt_name: | ||
- "DNS:ansible.com" | ||
- "DNS:www.ansible.com" | ||
- "DNS:docs.ansible.com" | ||
delegate_to: server_1 | ||
run_once: true | ||
register: csr | ||
|
||
- name: Sign certificate with our CA | ||
community.crypto.x509_certificate_pipe: | ||
csr_content: "{{ ca_csr.csr }}" | ||
provider: ownca | ||
ownca_path: /path/to/ca-certificate.pem | ||
ownca_privatekey_path: /path/to/ca-certificate.key | ||
ownca_privatekey_passphrase: "{{ secret_ca_passphrase }}" | ||
ownca_not_after: +365d # valid for one year | ||
ownca_not_before: "-1d" # valid since yesterday | ||
delegate_to: server_2 | ||
run_once: true | ||
register: certificate | ||
|
||
- name: Write certificate file on server_1 | ||
copy: | ||
dest: /path/to/certificate.pem | ||
content: "{{ certificate.certificate }}" | ||
delegate_to: server_1 | ||
run_once: true | ||
|
||
Please note that the above procedure is **not idempotent**. The following extended example reads the existing certificate from ``server_1`` (if exists) and provides it to the :ref:`community.crypto.x509_certificate_pipe module <ansible_collections.community.crypto.x509_certificate_pipe_module>`, and only writes the result back if it was changed: | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create private key for new certificate on server_1 | ||
community.crypto.openssl_privatekey: | ||
path: /path/to/certificate.key | ||
delegate_to: server_1 | ||
run_once: true | ||
|
||
- name: Create certificate signing request (CSR) for new certificate | ||
community.crypto.openssl_csr_pipe: | ||
privatekey_path: /path/to/certificate.key | ||
subject_alt_name: | ||
- "DNS:ansible.com" | ||
- "DNS:www.ansible.com" | ||
- "DNS:docs.ansible.com" | ||
delegate_to: server_1 | ||
run_once: true | ||
register: csr | ||
|
||
- name: Check whether certificate exists | ||
stat: | ||
path: /path/to/certificate.pem | ||
delegate_to: server_1 | ||
run_once: true | ||
register: certificate_exists | ||
|
||
- name: Read existing certificate if exists | ||
slurp: | ||
src: /path/to/certificate.pem | ||
when: certificate_exists.stat.exists | ||
delegate_to: server_1 | ||
run_once: true | ||
register: certificate | ||
|
||
- name: Sign certificate with our CA | ||
community.crypto.x509_certificate_pipe: | ||
content: "{{ (certificate.content | b64decode) if certificate_exists.stat.exists else omit }}" | ||
csr_content: "{{ ca_csr.csr }}" | ||
provider: ownca | ||
ownca_path: /path/to/ca-certificate.pem | ||
ownca_privatekey_path: /path/to/ca-certificate.key | ||
ownca_privatekey_passphrase: "{{ secret_ca_passphrase }}" | ||
ownca_not_after: +365d # valid for one year | ||
ownca_not_before: "-1d" # valid since yesterday | ||
delegate_to: server_2 | ||
run_once: true | ||
register: certificate | ||
|
||
- name: Write certificate file on server_1 | ||
copy: | ||
dest: /path/to/certificate.pem | ||
content: "{{ certificate.certificate }}" | ||
delegate_to: server_1 | ||
run_once: true | ||
when: certificate is changed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
.. _ansible_collections.community.crypto.docsite.guide_selfsigned: | ||
|
||
How to create self-signed certificates | ||
====================================== | ||
|
||
The `community.crypto collection <https://galaxy.ansible.com/community/crypto>`_ offers multiple modules that create private keys, certificate signing requests, and certificates. This guide shows how to create self-signed certificates. | ||
|
||
For creating any kind of certificate, you always have to start with a private key. You can use the :ref:`community.crypto.openssl_privatekey module <ansible_collections.community.crypto.openssl_privatekey_module>` to create a private key. If you only specify ``path``, the default parameters will be used. This will result in a 4096 bit RSA private key: | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create private key (RSA, 4096 bits) | ||
community.crypto.openssl_privatekey: | ||
path: /path/to/certificate.key | ||
|
||
You can specify ``type`` to select another key type, ``size`` to select a different key size (only available for RSA and DSA keys), or ``passphrase`` if you want to store the key password-protected: | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create private key (X25519) with password protection | ||
community.crypto.openssl_privatekey: | ||
path: /path/to/certificate.key | ||
type: X25519 | ||
passphrase: changeme | ||
|
||
To create a very simple self-signed certificate with no specific information, you can proceed directly with the :ref:`community.crypto.x509_certificate module <ansible_collections.community.crypto.x509_certificate_module>`: | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create simple self-signed certificate | ||
community.crypto.x509_certificate: | ||
path: /path/to/certificate.pem | ||
privatekey_path: /path/to/certificate.key | ||
provider: selfsigned | ||
|
||
(If you used ``passphrase`` for the private key, you have to provide ``privatekey_passphrase``.) | ||
|
||
You can use ``selfsigned_not_after`` to define when the certificate expires (default: in roughly 10 years), and ``selfsigned_not_before`` to define from when the certificate is valid (default: now). | ||
|
||
To define further properties of the certificate, like the subject, Subject Alternative Names (SANs), key usages, name constraints, etc., you need to first create a Certificate Signing Request (CSR) and provide it to the :ref:`community.crypto.x509_certificate module <ansible_collections.community.crypto.x509_certificate_module>`. If you do not need the CSR file, you can use the :ref:`community.crypto.openssl_csr_pipe module <ansible_collections.community.crypto.openssl_csr_pipe_module>` as in the example below. (To store it to disk, use the :ref:`community.crypto.openssl_csr module <ansible_collections.community.crypto.openssl_csr_module>` instead.) | ||
|
||
.. code-block:: yaml+jinja | ||
|
||
- name: Create certificate signing request (CSR) for self-signed certificate | ||
community.crypto.openssl_csr_pipe: | ||
privatekey_path: /path/to/certificate.key | ||
common_name: ansible.com | ||
organization_name: Ansible, Inc. | ||
subject_alt_name: | ||
- "DNS:ansible.com" | ||
- "DNS:www.ansible.com" | ||
- "DNS:docs.ansible.com" | ||
register: csr | ||
|
||
- name: Create self-signed certificate from CSR | ||
community.crypto.x509_certificate: | ||
path: /path/to/certificate.pem | ||
csr_content: "{{ csr.csr }}" | ||
privatekey_path: /path/to/certificate.key | ||
provider: selfsigned |