Global trust for SaltCA, distribute ca.crt
diff --git a/.kitchen.yml b/.kitchen.yml
index 6e852bd..39df9e8 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -9,6 +9,7 @@
salt_install: bootstrap
salt_bootstrap_url: https://bootstrap.saltstack.com
salt_version: latest
+ salt_minion_id: salt.ci.local
require_chef: false
log_level: error
formula: salt
@@ -96,13 +97,17 @@
base:
"*":
- common
+ - minion_pki
- master_api
- master_acl
- master_ssh_key
- master_ssh_password
- master_ssh_root
- master_handler
+ - minion_pki_cert
pillars-from-files:
+ minion_pki.sls: tests/pillar/minion_pki_ca.sls
+ minion_pki_cert.sls: tests/pillar/minion_pki_cert.sls
master_api.sls: tests/pillar/master_api.sls
master_acl.sls: tests/pillar/master_acl.sls
master_ssh_key.sls: tests/pillar/master_ssh_minion_key.sls
diff --git a/salt/minion/cert.sls b/salt/minion/cert.sls
index 34255c4..e25534e 100644
--- a/salt/minion/cert.sls
+++ b/salt/minion/cert.sls
@@ -1,5 +1,7 @@
{%- from "salt/map.jinja" import minion with context %}
+
{%- if minion.enabled %}
+{%- if minion.cert is defined %}
{%- for cert_name,cert in minion.get('cert', {}).iteritems() %}
{%- set rowloop = loop %}
@@ -10,6 +12,11 @@
{%- set key_dir = key_file|replace(key_file.split('/')[-1], "") %}
{%- set cert_dir = cert_file|replace(cert_file.split('/')[-1], "") %}
{%- set ca_dir = ca_file|replace(ca_file.split('/')[-1], "") %}
+{%- if grains.os_family == 'RedHat' %}
+{%- set cacerts_dir='/etc/pki/ca-trust/source/anchors' %}
+{%- else %}
+{%- set cacerts_dir='/usr/local/share/ca-certificates' %}
+{%- endif %}
{# Only ensure directories exists, don't touch permissions, etc. #}
salt_minion_cert_{{ cert_name }}_dirs:
@@ -43,11 +50,21 @@
{{ cert_file }}:
x509.certificate_managed:
- - ca_server: {{ cert.host }}
+ {% if cert.host is defined %}- ca_server: {{ cert.host }}{%- endif %}
+ {% if cert.authority is defined and cert.signing_policy is defined %}
- signing_policy: {{ cert.authority }}_{{ cert.signing_policy }}
+ {%- endif %}
- public_key: {{ key_file }}
- CN: "{{ cert.common_name }}"
- {%- if cert.alternative_names is defined %}
+ {% if cert.state is defined %}- ST: {{ cert.state }}{%- endif %}
+ {% if cert.country is defined %}- C: {{ cert.country }}{%- endif %}
+ {% if cert.locality is defined %}- L: {{ cert.locality }}{%- endif %}
+ {% if cert.organization is defined %}- O: {{ cert.organization }}{%- endif %}
+ {% if cert.signing_private_key is defined and cert.signing_cert is defined %}
+ - signing_private_key: "{{ cert.signing_private_key }}"
+ - signing_cert: "{{ cert.signing_cert }}"
+ {%- endif %}
+ {% if cert.alternative_names is defined %}
- subjectAltName: "{{ cert.alternative_names }}"
{%- endif %}
{%- if cert.extended_key_usage is defined %}
@@ -75,6 +92,7 @@
- watch:
- x509: {{ cert_file }}
+{%- if cert.host is defined %}
{%- for ca_path,ca_cert in salt['mine.get'](cert.host, 'x509.get_pem_entries').get(cert.host, {}).iteritems() %}
{%- if '/etc/pki/ca/'+cert.authority in ca_path %}
@@ -97,30 +115,17 @@
- watch:
- x509: {{ ca_file }}
-{%- if grains.os_family == 'Debian' %}
-
-salt_ca_certificates_packages_{{ rowloop.index }}:
- pkg.installed:
- - name: ca-certificates
-
-{{ ca_file }}_{{ rowloop.index }}_debian_symlink:
+{{ ca_file }}_{{ rowloop.index }}_local_trusted_symlink:
file.symlink:
- - name: "/usr/local/share/ca-certificates/ca-{{ cert.authority }}.crt"
+ - name: "{{ cacerts_dir }}/ca-{{ cert.authority }}.crt"
- target: {{ ca_file }}
- watch_in:
- - cmd: salt_update_certificates_{{ rowloop.index }}
- - require:
- - pkg: salt_ca_certificates_packages_{{ rowloop.index }}
-
-salt_update_certificates_{{ rowloop.index }}:
- cmd.wait:
- - name: update-ca-certificates
-
-{%- endif %}
+ - cmd: salt_update_certificates
{%- endif %}
{%- endfor %}
+{%- endif %}
{%- if cert.all_file is defined %}
salt_minion_cert_{{ cert_name }}_all:
@@ -148,3 +153,48 @@
{%- endfor %}
{%- endif %}
+
+salt_ca_certificates_packages:
+ pkg.installed:
+{%- if grains.os_family == 'Debian' %}
+ - name: ca-certificates
+{%- elif grains.os_family == 'RedHat' %}
+ - name: ca-certificates
+{%- else %}
+ - name: []
+{%- endif %}
+
+salt_update_certificates:
+ cmd.wait:
+{%- if grains.os_family == 'Debian' %}
+ - name: "update-ca-certificates{% if minion.get('ca_certificates_cleanup') %} --fresh {% endif %}"
+{%- elif grains.os_family == 'RedHat' %}
+ - name: "update-ca-trust extract"
+{%- else %}
+ - name: true
+{%- endif %}
+ - require:
+ - pkg: salt_ca_certificates_packages
+
+{%- if minion.get('cert', {}).get('trust_salt_ca', 'True') %}
+{%- for ca_host, certs in salt['mine.get']('*/ca*', 'x510.get_pem_entries').iteritems() %}
+{%- for ca_path, ca_cert in certs.iteritems() %}
+{%- set cacert_file="ca-"+ca_path.split("/")[4]+".crt" %}
+
+salt_cert_{{ cacerts_dir }}/{{ cacert_file }}:
+ file.managed:
+ - name: {{ cacerts_dir }}/{{ cacert_file }}
+ - contents: |
+ {{ ca_cert | indent(8) }}
+ - makedirs: True
+ - show_changes: True
+ - follow_symlinks: True
+ - watch_in:
+ - cmd: salt_update_certificates
+
+{%- endfor %}
+{%- endfor %}
+{%- endif %}
+
+{%- endif %}
+
diff --git a/salt/minion/init.sls b/salt/minion/init.sls
index f81ca43..477b0b9 100644
--- a/salt/minion/init.sls
+++ b/salt/minion/init.sls
@@ -7,6 +7,4 @@
{%- if pillar.salt.minion.ca is defined %}
- salt.minion.ca
{%- endif %}
-{%- if pillar.salt.minion.cert is defined %}
- salt.minion.cert
-{%- endif %}
\ No newline at end of file
diff --git a/tests/pillar/minion_pki_ca.sls b/tests/pillar/minion_pki_ca.sls
index 453d1f7..935014b 100644
--- a/tests/pillar/minion_pki_ca.sls
+++ b/tests/pillar/minion_pki_ca.sls
@@ -2,8 +2,8 @@
minion:
enabled: true
ca:
- vagrant:
- common_name: Test CA
+ salt-ca-default:
+ common_name: Test CA Default
country: Czech
state: Prague
locality: Zizkov
@@ -23,3 +23,24 @@
ca_intermediate:
type: v3_intermediate_ca
minions: '*'
+ salt-ca-test:
+ common_name: Test CA Testing
+ country: Czech
+ state: Prague
+ locality: Karlin
+ days_valid:
+ authority: 3650
+ certificate: 90
+ signing_policy:
+ cert_server:
+ type: v3_edge_cert_server
+ minions: '*'
+ cert_client:
+ type: v3_edge_cert_client
+ minions: '*'
+ ca_edge:
+ type: v3_edge_ca
+ minions: '*'
+ ca_intermediate:
+ type: v3_intermediate_ca
+ minions: '*'
diff --git a/tests/pillar/minion_pki_cert.sls b/tests/pillar/minion_pki_cert.sls
new file mode 100644
index 0000000..14b0194
--- /dev/null
+++ b/tests/pillar/minion_pki_cert.sls
@@ -0,0 +1,59 @@
+salt:
+ #master:
+ # enabled: true
+ # accept_policy:
+ # open_mode
+ # peer:
+ # '.*':
+ # - x509.sign_remote_certificate
+ minion:
+ enabled: true
+ cert:
+ ceph_cert:
+ alternative_names:
+ IP:127.0.0.1,DNS:salt.ci.local,DNS:ceph.ci.local,DNS:radosgw.ci.local,DNS:swift.ci.local
+ cert_file:
+ /srv/salt/pki/ci/ceph.ci.local.crt
+ common_name:
+ ceph_mon.ci.local
+ key_file:
+ /srv/salt/pki/ci/ceph.ci.local.key
+ country: CZ
+ state: Prague
+ locality: Karlin
+ signing_cert:
+ /etc/pki/ca/salt-ca-test/ca.crt
+ signing_private_key:
+ /etc/pki/ca/salt-ca-test/ca.key
+ # Kitchen-Salt CI trigger `salt-call --local`, below attributes
+ # can't be used as there is no required SaltMaster connectivity
+ authority:
+ salt-ca-test
+ #host:
+ # salt.ci.local
+ #signing_policy:
+ # cert_server
+ proxy_cert:
+ alternative_names:
+ IP:127.0.0.1,DNS:salt.ci.local,DNS:proxy.ci.local
+ cert_file:
+ /srv/salt/pki/ci/prx.ci.local.crt
+ common_name:
+ prx.ci.local
+ key_file:
+ /srv/salt/pki/ci/prx.ci.local.key
+ country: CZ
+ state: Prague
+ locality: Zizkov
+ signing_cert:
+ /etc/pki/ca/salt-ca-default/ca.crt
+ signing_private_key:
+ /etc/pki/ca/salt-ca-default/ca.key
+ # Kitchen-Salt CI trigger `salt-call --local`, below attributes
+ # can't be used as there is no required SaltMaster connectivity
+ authority:
+ salt-ca-default
+ #host:
+ # salt.ci.local
+ #signing_policy:
+ # cert_server
diff --git a/tests/pillar/minion_pki_cert_extended.sls b/tests/pillar/minion_pki_cert_extended.sls
new file mode 100644
index 0000000..f395bf7
--- /dev/null
+++ b/tests/pillar/minion_pki_cert_extended.sls
@@ -0,0 +1,45 @@
+salt:
+ #master:
+ # enabled: true
+ # accept_policy:
+ # open_mode
+ # peer:
+ # .*:
+ # - x509.sign_remote_certificate
+ minion:
+ enabled: true
+ cert:
+ ceph_cert:
+ all_file:
+ /srv/salt/pki/ci/ceph-with-key.ci.local.pem
+ alternative_names:
+ IP:127.0.0.1,DNS:salt.ci.local,DNS:ceph.ci.local,DNS:radosgw.ci.local,DNS:swift.ci.local
+ cert_file:
+ /srv/salt/pki/ci/ceph.ci.local.crt
+ common_name:
+ ceph_mon.ci.local
+ key_file:
+ /srv/salt/pki/ci/ceph.ci.local.key
+ authority:
+ salt-ca-test
+ host:
+ salt.ci.local
+ signing_policy:
+ cert_server
+ proxy_cert:
+ all_file:
+ /srv/salt/pki/ci/prx-with-key.ci.local.pem
+ alternative_names:
+ IP:127.0.0.1,DNS:salt.ci.local,DNS:proxy.ci.local
+ cert_file:
+ /srv/salt/pki/ci/prx.ci.local.crt
+ common_name:
+ prx.ci.local
+ key_file:
+ /srv/salt/pki/ci/prx.ci.local.key
+ authority:
+ salt-ca-default
+ host:
+ salt.ci.local
+ signing_policy:
+ cert_server