ansible-collections / community.crypto

The community.crypto collection for Ansible.
https://galaxy.ansible.com/ui/repo/published/community/crypto/
Other
98 stars 89 forks source link

x509_certificate: Unable to load certificate #226

Closed PrymalInstynct closed 3 years ago

PrymalInstynct commented 3 years ago
SUMMARY

Attempting to use community.crypto to create a self-signed CA, then sign a number of x509 certifcates

ISSUE TYPE
COMPONENT NAME

x509_certificate

ANSIBLE VERSION
ansible 2.9.18
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/zimmermanc/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Aug 18 2020, 08:33:21) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
CONFIGURATION
DEFAULT_CALLBACK_WHITELIST(/etc/ansible/ansible.cfg) = ['profile_tasks']
HOST_KEY_CHECKING(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT

Red Hat Enterprise Linux 8.3

STEPS TO REPRODUCE

This is a part of role, so the yaml below is from the task associated with these steps

- name: Create OpenSSL CA.key
  run_once: yes
  become: yes
  become_user: "{{ local_user }}"
  delegate_to: localhost
  openssl_privatekey:
    path: "{{ role_path }}/files/ca.key"
    type: RSA
    size: 4096
    owner: "{{ local_user }}"
    group: "{{ local_user }}"

- name: "Create OpenSSL CA.crt"
  run_once: yes
  become: yes
  become_user: "{{ local_user }}"
  delegate_to: localhost
  openssl_publickey:
    path: "{{ role_path }}/files/ca.crt"
    privatekey_path: "{{ role_path }}/files/ca.key"

- name: "Create OpenSSL {{ vault_url }}.key"
  run_once: yes
  become: yes
  become_user: "{{ local_user }}"
  delegate_to: localhost
  openssl_privatekey:
    path: "{{ role_path }}/files/{{ vault_url }}.key"
    type: RSA
    size: 4096
    owner: "{{ local_user }}"
    group: "{{ local_user }}"

- name: "Create OpenSSL {{ vault_url }}.csr"
  run_once: yes
  become: yes
  become_user: "{{ local_user }}"
  delegate_to: localhost
  openssl_csr:
    path: "{{ role_path }}/files/{{ vault_url }}.csr"
    privatekey_path: "{{ role_path }}/files/{{ vault_url }}.key"
    country_name: US
    state_or_province_name: Colorado
    common_name: "{{ vault_url }}"
    basic_constraints:
      - CA:FALSE
    key_usage:
      - digitalSignature
      - nonRepudiation
      - keyEncipherment
      - dataEncipherment
    extended_key_usage:
      - serverAuth
    subject_alt_name: 'DNS:{{ vault_url }},DNS:{{ vault_short_url }}'
    owner: "{{ local_user }}"
    group: "{{ local_user }}"

- name: "Create OpenSSL {{ vault_url }}.crt"
  run_once: yes
  become: yes
  become_user: "{{ local_user }}"
  delegate_to: localhost
  x509_certificate:
    path: "{{ role_path }}/files/{{ vault_url }}.crt"
    csr_path: "{{ role_path }}/files/{{ vault_url }}.csr"
    ownca_path: "{{ role_path }}/files/ca.crt"
    ownca_privatekey_path: "{{ role_path }}/files/ca.key"
    provider: ownca
EXPECTED RESULTS

I expect the x509_certificate module to successfully create and output a certificate

ACTUAL RESULTS

I get the following output fatal: [vault01.dev.env]: FAILED! => {"changed": false, "msg": "Unable to load certificate"}

<localhost> ESTABLISH LOCAL CONNECTION FOR USER: zimmermanc
<localhost> EXEC /bin/sh -c 'echo ~zimmermanc && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/zimmermanc/.ansible/tmp `"&& mkdir "` echo /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629 `" && echo ansible-tmp-1620392623.492317-1658179-74491262349629="` echo /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629 `" ) && sleep 0'
Using module file /home/zimmermanc/.ansible/collections/ansible_collections/community/crypto/plugins/modules/x509_certificate.py
<localhost> PUT /home/zimmermanc/.ansible/tmp/ansible-local-165787482qd_06h/tmpeg9gdh3_ TO /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629/AnsiballZ_x509_certificate.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629/ /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629/AnsiballZ_x509_certificate.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python3.6 /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629/AnsiballZ_x509_certificate.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/zimmermanc/.ansible/tmp/ansible-tmp-1620392623.492317-1658179-74491262349629/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
  File "/tmp/ansible_x509_certificate_payload_cjqckiab/ansible_x509_certificate_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate.py", line 544, in main
  File "/tmp/ansible_x509_certificate_payload_cjqckiab/ansible_x509_certificate_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate.py", line 371, in select_backend
    return provider.create_backend(module, backend)
  File "/tmp/ansible_x509_certificate_payload_cjqckiab/ansible_x509_certificate_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py", line 336, in create_backend
    return OwnCACertificateBackendCryptography(module)
  File "/tmp/ansible_x509_certificate_payload_cjqckiab/ansible_x509_certificate_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_ownca.py", line 97, in __init__
    backend=self.backend
  File "/tmp/ansible_x509_certificate_payload_cjqckiab/ansible_x509_certificate_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/support.py", line 203, in load_certificate
    raise OpenSSLObjectError(exc)
fatal: [gitlab.dev.env]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "acme_accountkey_path": null,
            "acme_chain": false,
            "acme_challenge_path": null,
            "acme_directory": "https://acme-v02.api.letsencrypt.org/directory",
            "attributes": null,
            "backup": false,
            "content": null,
            "csr_content": null,
            "csr_path": "/home/zimmermanc/Projects/homelab/ansible/roles/dev-setup/files/vault01.dev.env.csr",
            "delimiter": null,
            "directory_mode": null,
            "entrust_api_client_cert_key_path": null,
            "entrust_api_client_cert_path": null,
            "entrust_api_key": null,
            "entrust_api_specification_path": "https://cloud.entrust.net/EntrustCloud/documentation/cms-api-2.1.0.yaml",
            "entrust_api_user": null,
            "entrust_cert_type": "STANDARD_SSL",
            "entrust_not_after": "+365d",
            "entrust_requester_email": null,
            "entrust_requester_name": null,
            "entrust_requester_phone": null,
            "extended_key_usage": null,
            "extended_key_usage_strict": false,
            "follow": false,
            "force": false,
            "group": null,
            "has_expired": false,
            "invalid_at": null,
            "issuer": null,
            "issuer_strict": false,
            "key_usage": null,
            "key_usage_strict": false,
            "mode": null,
            "not_after": null,
            "not_before": null,
            "ownca_content": null,
            "ownca_create_authority_key_identifier": true,
            "ownca_create_subject_key_identifier": "create_if_not_provided",
            "ownca_digest": "sha256",
            "ownca_not_after": "+3650d",
            "ownca_not_before": "+0s",
            "ownca_path": "/home/zimmermanc/Projects/homelab/ansible/roles/dev-setup/files/ca.crt",
            "ownca_privatekey_content": null,
            "ownca_privatekey_passphrase": null,
            "ownca_privatekey_path": "/home/zimmermanc/Projects/homelab/ansible/roles/dev-setup/files/ca.key",
            "ownca_version": 3,
            "owner": null,
            "path": "/home/zimmermanc/Projects/homelab/ansible/roles/dev-setup/files/vault01.dev.env.crt",
            "privatekey_content": null,
            "privatekey_passphrase": null,
            "privatekey_path": null,
            "provider": "ownca",
            "regexp": null,
            "remote_src": null,
            "return_content": false,
            "select_crypto_backend": "auto",
            "selevel": null,
            "selfsigned_create_subject_key_identifier": "create_if_not_provided",
            "selfsigned_digest": "sha256",
            "selfsigned_not_after": "+3650d",
            "selfsigned_not_before": "+0s",
            "selfsigned_version": 3,
            "serole": null,
            "setype": null,
            "seuser": null,
            "signature_algorithms": null,
            "src": null,
            "state": "present",
            "subject": null,
            "subject_alt_name": null,
            "subject_alt_name_strict": false,
            "subject_strict": false,
            "unsafe_writes": null,
            "valid_at": null,
            "valid_in": null,
            "version": null
        }
    },
    "msg": "Unable to load certificate"
}

I have validated it is not a permissions issue as the become user owns the files that the x509_certificate module is trying to read.

felixfontein commented 3 years ago

Well, this is not a surprise since ca.crt in your example is not a certificate, but a public key:

- name: "Create OpenSSL CA.crt"
  run_once: yes
  become: yes
  become_user: "{{ local_user }}"
  delegate_to: localhost
  openssl_publickey:
    path: "{{ role_path }}/files/ca.crt"
    privatekey_path: "{{ role_path }}/files/ca.key"

You need a certificate, not a public key.

PrymalInstynct commented 3 years ago

ok, gotcha, I should have realized that. If I can make a recommendation it would be to update the documentation that goes along with this module to address creating a self-signed CA as that has got to be a pretty common usecase.

Ajpantuso commented 3 years ago

ok, gotcha, I should have realized that. If I can make a recommendation it would be to update the documentation that goes along with this module to address creating a self-signed CA as that has got to be a pretty common usecase.

Were you able to create your self-signed root certificate?

The first example in the x509_certificate documentation covers this:

- name: Generate a Self Signed OpenSSL certificate 
  community.crypto.x509_certificate:
    path: /etc/ssl/crt/ansible.com.crt
    privatekey_path: /etc/ssl/private/ansible.com.pem
    csr_path: /etc/ssl/csr/ansible.com.csr
    provider: selfsigned

To your point however these modules don't really cover creating a CA which typically involves setting up the directory structure, configurations, and initial state of the CA database/serial number sequence.

So if you really need to create a CA I would look at other options however for creating a self-signed cert the docs cover what is needed.

felixfontein commented 3 years ago

This is something we should add as a scenario guide I guess, similar to some other common use-cases. (We hopefully will be able to publish guides soon, using https://github.com/ansible-community/antsibull/pull/255...)

felixfontein commented 3 years ago

I started writing some guides in #237.