salt: 2016.3 x509 state does not work when using ca_server

Description of Issue/Question

I am trying to setup remote singing according to: https://docs.saltstack.com/en/develop/ref/states/all/salt.states.x509.html#module-salt.states.x509

[root@cronos /salt/states/role/certificate]# salt cronos state.apply role.certificate
cronos:
  Name: /opt/local/etc/openssl/certs - Function: file.directory - Result: Clean
  Name: /opt/local/etc/openssl/certs/internal-ca.crt - Function: x509.pem_managed - Result: Clean
  Name: /opt/local/bin/c_rehash - Function: cmd.wait - Result: Clean
  Name: /opt/local/etc/pki - Function: file.directory - Result: Clean
  Name: /opt/local/etc/pki/test.acheron.be.key - Function: x509.private_key_managed - Result: Clean
----------
          ID: certificate:test.acheron.be::crt
    Function: x509.certificate_managed
      Result: False
     Comment: An exception occurred in this state: Traceback (most recent call last):
                File "/opt/salt/lib/python2.7/site-packages/salt/state.py", line 1703, in call
                  **cdata['kwargs'])
                File "/opt/salt/lib/python2.7/site-packages/salt/loader.py", line 1607, in wrapper
                  return f(*args, **kwargs)
                File "/opt/salt/lib/python2.7/site-packages/salt/states/x509.py", line 429, in certificate_managed
                  new = __salt__['x509.create_certificate'](testrun=True, **kwargs)
                File "/opt/salt/lib/python2.7/site-packages/salt/modules/x509.py", line 1100, in create_certificate
                  pem_type='CERTIFICATE')
                File "/opt/salt/lib/python2.7/site-packages/salt/modules/x509.py", line 628, in write_pem
                  text = get_pem_entry(text, pem_type=pem_type)
                File "/opt/salt/lib/python2.7/site-packages/salt/modules/x509.py", line 350, in get_pem_entry
                  text = _text_or_file(text)
                File "/opt/salt/lib/python2.7/site-packages/salt/modules/x509.py", line 267, in _text_or_file
                  if os.path.isfile(input_):
                File "/opt/local/lib/python2.7/genericpath.py", line 37, in isfile
                  st = os.stat(path)
              TypeError: coercing to Unicode: need string or buffer, dict found
     Started: 12:25:26.512975
    Duration: 539.322 ms
     Changes:   

Summary for cronos
------------
Succeeded: 5
Failed:    1
------------
Total states run:     6

Setup

role.certificate is split into 2 states, authority.sls (the ca) and init.sls for all the clients.

role/certificate/authority.sls

######
## certificate.authority state
## -----------------------------------
## https://docs.saltstack.com/en/develop/ref/states/all/salt.states.x509.html#module-salt.states.x509
######
## import
{% from 'role/salt/config.jinja' import saltcfg with context %}
{% from 'role/certificate/config.jinja' import certcfg with context %}

## manage policies
certificate.authority::policies:
  file.managed:
    - name: {{ saltcfg['prefix'] }}/minion.d/signing_policies.conf
    - template: jinja
    - source: salt://role/certificate/_files/signing_policies.conf
    - context:
        saltcfg: {{ saltcfg }}
        certcfg: {{ certcfg }}

## manage directories
certificate.authority::directories:
  file.directory:
    - names:
        - {{ certcfg['authority_dir'] }}
        - {{ certcfg['authority_dir'] }}/issued/
    - user: root
    - group: nacl
    - dir_mode: 2770

## manage ca key
certificate.authority::key:
  x509.private_key_managed:
    - name: {{ certcfg['authority_dir'] }}/ca.key
    - bits: 4096
    - backup: True
    - require:
      - file: certificate.authority::directories

## manage ca certificate
certificate.authority::crt:
  x509.certificate_managed:
    - name: {{ certcfg['authority_dir'] }}/ca.crt
    - signing_private_key: {{ certcfg['authority_dir'] }}/ca.key
    - CN: ca.acheron.be
    - C: BE
    - ST: Antwerp
    - L: Kapellen
    - Email: certadm@acheron.be
    - basicConstraints: "critical CA:true"
    - keyUsage: "critical cRLSign, keyCertSign"
    - subjectKeyIdentifier: hash
    - authorityKeyIdentifier: keyid,issuer:always
    - days_valid: 3650
    - days_remaining: 0
    - backup: True
    - require:
      - x509: certificate.authority::key

## store ca in grains
mine.send:
  module.run:
    - func: x509.get_pem_entries
    - kwargs:
        glob_path: {{ certcfg['authority_dir'] }}/ca.crt
    - onchanges:
      - x509: certificate.authority::crt

# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2

role/certificate/init.sls

######
## certificate state
## -----------------------------------
######
## import
{% from 'role/certificate/config.jinja' import certcfg with context %}
{% from 'role/certificate/_macros/cert.jinja' import setup_ca, rebuild_cache, managed_cert, show_notice with context %}

## variables
{% set ca_host = certcfg['authority_id'] %}
{% set ca_crt_path = certcfg['authority_dir'] ~ '/ca.crt' %}
{% set ca_crt = salt['mine.get'](ca_host, 'x509.get_pem_entries') %}


## publish authority root cert
{% if ca_host in ca_crt and ca_crt_path in ca_crt[ca_host] and certcfg['castore_dir'] %}
  {{ setup_ca(ca_crt[ca_host][ca_crt_path]|replace('\n', '')) }}

  {% if certcfg['castore_bin'] %}
    {{ rebuild_cache() }}
  {% endif %}

  {% if certcfg['managed'] %}
    {% for fqdn in certcfg['managed'] %}
      {{ managed_cert(fqdn) }}
    {% endfor %}
  {% endif %}
{% else %}
  {{ show_notice() }}
{% endif %}

# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2

role/certificate/config.jinja

######
## certificate configuration
## -----------------------------------
######

## macros
{% from '_macros/common.jinja' import config_merge with context %}

## defaults
{% set certcfg = 
  {
    'authority_id': 'cronos',
    'authority_dir': '/salt/pki/certificates',
    'castore_dir': false,
    'castore_bin': false,
    'pki_dir': '/etc/pki',
    'managed': None
  }
%}

## platform specific + pillar overwrite
{% do config_merge(certcfg, salt['grains.filter_by']({
    'SmartOS': {
      'castore_dir': '/opt/local/etc/openssl/certs',
      'castore_bin': '/opt/local/bin/c_rehash',
      'pki_dir': '/opt/local/etc/pki'
    },
    'CentOS': {
      'castore_dir': '/etc/pki/ca-trust/source/anchors',
      'castore_bin': '/usr/bin/update-ca-trust extract'
    },
    'Ubuntu': {
      'castore_dir': '/usr/local/share/ca-certificates',
      'castore_bin': '/usr/sbin/update-ca-certificates'
    },
  },
  grain="os", merge=salt.pillar.get('certificate', {})))
%}

# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2

role/certificate/_files/signing_policies.conf

x509_signing_policies:
  default:
    - minions: '*'
    - signing_private_key: {{ certcfg['authority_dir'] }}/ca.key
    - signing_cert: {{ certcfg['authority_dir'] }}/ca.crt
    - C: BE
    - ST: Antwerp
    - L: Kapellen
    - Email: certadm@acheron.be
    - basicConstraints: "critical CA:false"
    - keyUsage: "critical cRLSign, keyCertSign"
    - subjectKeyIdentifier: hash
    - authorityKeyIdentifier: keyid,issuer:always
    - days_valid: 90
    - copypath: {{ certcfg['authority_dir'] }}/issued/

role/certificate/_macros/cert.jinja

######
## certificate macros
## -----------------------------------
######
## import
{% from 'role/certificate/config.jinja' import certcfg with context %}

## macros
{% macro setup_ca(ca_crt) %}
certificate::ca:
  file.directory:
    - name: {{ certcfg['castore_dir'] }}
  x509.pem_managed:
    - name: {{ certcfg['castore_dir'] }}/internal-ca.crt
    - text: {{ ca_crt }}
    - require:
        - file: certificate::ca
{% endmacro %}

{% macro rebuild_cache() %}
certificate::rebuild-cache:
  cmd.wait:
    - name: {{ certcfg['castore_bin'] }}
    - watch:
        - x509: certificate::ca
{% endmacro %}

{% macro show_notice() %}
certificate::ca:
  test.show_notification:
    - text: root authority certificate not found, signing requests will fail
{% endmacro %}

{% macro managed_cert(fqdn, dns_alias=[], ip4_alias=[], ip6_alias=[], key_size=2048, days_valid=90) %}
#TODO: dns, ip4, ip6 aliasses
certificate:{{ fqdn }}::directory:
  file.directory:
    - name: {{ certcfg['pki_dir'] }}

certificate:{{ fqdn }}::key:
  x509.private_key_managed:
    - name: {{ certcfg['pki_dir'] ~ '/' ~ fqdn ~ '.key' }}
    - bits: {{ key_size }}
    - require:
        - file: certificate:{{ fqdn }}::directory

certificate:{{ fqdn }}::crt:
  x509.certificate_managed:
    - ca_server: {{ certcfg['authority_id'] }}
    - signing_policy: default
    - public_key: {{ certcfg['pki_dir'] ~ '/' ~ fqdn ~ '.key' }}
    - path: {{ certcfg['pki_dir'] ~ '/' ~ fqdn ~ '.crt' }}
    - CN: {{ fqdn }}
    - days_valid: {{ days_valid }}
    - days_remaining: 30
    - backup: True
    - require:
        - x509: certificate:{{ fqdn }}::key
{% endmacro %}

# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2

cronos is both the CA (that work is working) and to keep it simple the client that will request the test certificate.

salt-call pillar.get certificate

local:
    ----------
    managed:
        ----------
        test.acheron.be:
            None

Trying to get a simple cert to work before I start adding subject altnames and such but I keep hitting a exception as mentioned above.

Steps to Reproduce Issue

Try to apply the state

Versions Report

Salt Version:
           Salt: 2016.3.0rc1-96-gfe86a3d

Dependency Versions:
         Jinja2: 2.8
       M2Crypto: 0.22
           Mako: Not Installed
         PyYAML: 3.11
          PyZMQ: 14.4.1
         Python: 2.7.11 (default, Mar 18 2016, 13:38:08)
           RAET: 0.6.5
        Tornado: 4.3
            ZMQ: 4.1.3
           cffi: Not Installed
       cherrypy: 3.8.0
       dateutil: 2.4.0
          gitdb: 0.6.4
      gitpython: 1.0.2
          ioflo: 1.5.1
        libgit2: Not Installed
        libnacl: 1.4.4
   msgpack-pure: Not Installed
 msgpack-python: 0.4.7
   mysql-python: Not Installed
      pycparser: Not Installed
       pycrypto: 2.6.1
         pygit2: Not Installed
   python-gnupg: 2.0.2
          smmap: 0.9.0
        timelib: 0.2.4

System Versions:
           dist:   
        machine: i86pc
        release: 5.11
         system: SunOS
        version: Not Installed

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 22 (22 by maintainers)

Most upvoted comments

Yeah I double checked all that, posted, tripple checked because I was 100% sure I had this before.

It was a stray ’ at the end of the peer file. The salt-master should really complain on bad/incorrect peer configs.

All good now 😃 thanks for tracking this one down.