Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openssl_csr does not support non-hostname CN values #105

Closed
ben-turner opened this issue Sep 4, 2020 · 8 comments · Fixed by #106
Closed

openssl_csr does not support non-hostname CN values #105

ben-turner opened this issue Sep 4, 2020 · 8 comments · Fixed by #106

Comments

@ben-turner
Copy link

SUMMARY

PKI certs can be used for a variety of things beyond HTTPS servers. I need to be able to generate a certificate with system:kube-controller-manager as the common name. This is permitted by openssl, but blocked by this module. Since this is an inconsistency between openssl and this module, I'm calling it a bug.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

openssl_csr

ANSIBLE VERSION
ansible 2.9.11
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/myusername/.ansible/plugins/modules', '/usr
/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.5 (default, Jul 27 2020, 08:42:51) [GCC 10.1.0
CONFIGURATION
(blank output)
OS / ENVIRONMENT

Amazon Linux 2
OpenSSL 1.0.2k-fips 26 Jan 2017

STEPS TO REPRODUCE

Try to generate a certificate that contains a non-hostname value as the common name.

- name: Generate CSRs
  become: true
  register: gen_csr
  openssl_csr:
    path: /etc/kubernetes/pki/kube-controller-manager.csr
    privatekey_path: /etc/kubernetes/pki/kube-controller-manager-key.pem
    CN: "system:kube-controller-manager"
    O: "system:kube-controller-manager"
    C: CA
    ST: My Province
    L: My City
    OU: My Business Unit
EXPECTED RESULTS

A new cert is generated with system:kube-controller-manager as the common name.

ACTUAL RESULTS

The task fails

An exception occurred during task execution. To see the full traceback, use -vvv.
 The error was: idna.core.IDNAError: The label system:kube-controller-manager is
not a valid A-label
fatal: [myhost.example.com]: FAILED! => {"changed": false, "module_stderr
": "Shared connection to myhost.example.com closed.\r\n", "module_stdout"
: "Traceback (most recent call last):\r\n  File \"/home/ec2-user/.ansible/tmp/ans
ible-tmp-1599257775.4836168-3939543-279353330847410/AnsiballZ_openssl_csr.py\", l
ine 102, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/ec2-user/.ansible
/tmp/ansible-tmp-1599257775.4836168-3939543-279353330847410/AnsiballZ_openssl_csr
.py\", line 94, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, AN
SIBALLZ_PARAMS)\r\n  File \"/home/ec2-user/.ansible/tmp/ansible-tmp-1599257775.48
36168-3939543-279353330847410/AnsiballZ_openssl_csr.py\", line 40, in invoke_modu
le\r\n    runpy.run_module(mod_name='ansible.modules.crypto.openssl_csr', init_gl
obals=None, run_name='__main__', alter_sys=True)\r\n  File \"/usr/lib64/python2.7
/runpy.py\", line 188, in run_module\r\n    fname, loader, pkg_name)\r\n  File \"
/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code\r\n    mod_name, mo
d_fname, mod_loader, pkg_name)\r\n  File \"/usr/lib64/python2.7/runpy.py\", line
72, in _run_code\r\n    exec code in run_globals\r\n  File \"/tmp/ansible_openssl
_csr_payload_C13PE_/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openss
l_csr.py\", line 1105, in <module>\r\n  File \"/tmp/ansible_openssl_csr_payload_C
13PE_/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py\", li
ne 1088, in main\r\n  File \"/tmp/ansible_openssl_csr_payload_C13PE_/ansible_open
ssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py\", line 541, in generat
e\r\n  File \"/tmp/ansible_openssl_csr_payload_C13PE_/ansible_openssl_csr_payload
.zip/ansible/modules/crypto/openssl_csr.py\", line 834, in _generate_csr\r\n  Fil
e \"/usr/lib64/python2.7/site-packages/cryptography/x509/base.py\", line 393, in
sign\r\n    return backend.create_x509_csr(self, private_key, algorithm)\r\n  Fil
e \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/multibackend.
py\", line 395, in create_x509_csr\r\n    return b.create_x509_csr(builder, priva
te_key, algorithm)\r\n  File \"/usr/lib64/python2.7/site-packages/cryptography/ha
zmat/backends/openssl/backend.py\", line 793, in create_x509_csr\r\n    gc=False\
r\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/opens
sl/backend.py\", line 1009, in _create_x509_extensions\r\n    handlers, extension
\r\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/open
ssl/backend.py\", line 1040, in _create_x509_extension\r\n    ext_struct = encode
(self, extension.value)\r\n  File \"/usr/lib64/python2.7/site-packages/cryptograp
hy/hazmat/backends/openssl/encode_asn1.py\", line 359, in _encode_alt_name\r\n
 general_names = _encode_general_names(backend, san)\r\n  File \"/usr/lib64/pytho
n2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py\", line 35
1, in _encode_general_names\r\n    gn = _encode_general_name(backend, name)\r\n
File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/en
code_asn1.py\", line 387, in _encode_general_name\r\n    value = _idna_encode(nam
e.value)\r\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backe
nds/openssl/encode_asn1.py\", line 376, in _idna_encode\r\n    return idna.encode
(value)\r\n  File \"/usr/lib/python2.7/site-packages/idna/core.py\", line 355, in
 encode\r\n    result.append(alabel(label))\r\n  File \"/usr/lib/python2.7/site-p
ackages/idna/core.py\", line 265, in alabel\r\n    raise IDNAError('The label {0}
 is not a valid A-label'.format(label))\r\nidna.core.IDNAError: The label system:
kube-controller-manager is not a valid A-label\r\n", "msg": "MODULE FAILURE\nSee
stdout/stderr for the exact error", "rc": 1}
@felixfontein
Copy link
Contributor

According to the documentation, the common name is always added as a Subject Alternative Name if no Subject Alternative Names are specified (which is true in your case). This causes this error. Simply specify the module option use_common_name_for_san: true to prevent this.

(It definitely should not crash in this case. That's definitely a bug. I'll look at that probably tomorrow.)

@MarkusTeufelberger
Copy link
Contributor

MarkusTeufelberger commented Sep 4, 2020

On that specific use case by the way: Kubernetes is now being built using golang 1.15, so you'll run into issues similar to golang/go#39568 if you use such a certificate in the future, just as a heads-up in general (see also https://golang.org/doc/go1.15#commonname).

The general case of course should be still investigated and probably made possible.

@ben-turner
Copy link
Author

@felixfontein Aha! That did it. Thanks for such a quick reply. (Although I set the value to false rather than true)

@MarkusTeufelberger That's really good to know; that's definitely going to cause issues for me with some other components. I don't think it should matter in this specific case though since the cert isn't being used to validate a hostname.

@felixfontein
Copy link
Contributor

@ben-turner haha, yes, sorry, it definitely should be false :) Was a bit too late for me...

@felixfontein
Copy link
Contributor

I've created a PR which improves this error message (#106). Interestingly, it turns out that only some cryptography versions return this error (probably versions < 2.0, and some later ones only when idna is installed explicitly). Later versions simply accept DNS:system:kube-controller-manager as a SAN, and pyOpenSSL also does that.

@ben-turner could you check which version of cryptography you have installed on the remote machine (where the module is executed), and whether idna is installed as well or not (and if yes, which version, because my fix does not work for idna 2.3, only for earlier and later versions)?

@ben-turner
Copy link
Author

@felixfontein I'm not totally familiar with the ansible and python ecosystems yet so I don't know if this is the output you're looking for. I'm not using pip but I was able to get the following out of yum:

python-jwcrypto.noarch                0.4.2-1.amzn2                  installed  
python2-cryptography.x86_64           1.7.2-2.amzn2                  installed
python-idna.noarch                    2.4-1.amzn2                    installed

These are the default versions that were pre-installed on an EC2 instance running the latest Amazon Linux 2.

@felixfontein
Copy link
Contributor

@ben-turner assuming you are using Python 2 on the host, the module is probably using cryptography 1.7.2, which happens to be one of the versions we're also having in CI. So my fix should work for your system, i.e. produce a nicer error message hinting at use_common_name_for_san :)

@ben-turner
Copy link
Author

Excellent! Thanks so much

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants