<p>It feels like what you have done here is implement a discount/bastardized CA (Certificate Authority). I fear that in doing so, you might have inadvertently created a security threat for yourself.</p>
<p>In a traditional PKI deployment, your client would generate a private key and a Certificate Signing Request (CSR) that is then submitted to your Certificate Authority for signing. Your CA would then sign your key after validating the applicant by some means and issue a Certificate to be installed on the client.</p>
<p>What you may have just done by concatenating every single certificate of each client into a CA is grant each and every client the ability to sign certificates for other machines. Any machine in your Gluster cluster then may have the ability to issue a certificate for an arbitrary key which then would be trusted by your Gluster cluster which could allow for an attacker to use a compromised system or key to allow an arbitrary endpoint to join your cluster.</p>
<p>Instead, you might want to follow this guide on <a href="https://backbeat.tech/blog/using-saltstack-for-internal-ssl-certificates" rel="nofollow noreferrer">setting up a CA for use by your SaltStack</a>. In fact, it is worth noting that your salt master is itself a CA. You could simply copy the minion's certificate and key for use by gluster, though that has the downside of a compromised cert/key being able to be used to impersonate a minion.</p>
<p>But generally speaking, you probably don't want to grant all of your minions the power to be a CA.</p>

CC BY-SA 4.0
2021-05-12T02:34:33.783Z
2021-05-12T02:34:33.783Z
James Shewey
<ul>
<li><p>You should use <a href="https://docs.saltproject.io/en/latest/ref/states/requisites.html" rel="nofollow noreferrer">requisites</a> to define the order of states, not order. Otherwise it's going to continue execution when necessary prerequisites fail.</p>
</li>
<li><p>To collect files from each minion, use the <a href="https://docs.saltproject.io/en/latest/topics/mine/" rel="nofollow noreferrer">Salt Mine</a>.</p>
</li>
<li><p>To concatenate the files, use <a href="https://docs.saltproject.io/en/latest/ref/states/all/salt.states.file.html#salt.states.file.managed" rel="nofollow noreferrer">file.managed</a> with a jinja template.</p>
</li>
</ul>
<p>So, if you really want to generate a self-signed unlimited CA on every minion and have all of them trust each other, your state could look something like this:</p>
<pre class="lang-yaml prettyprint-override"><code>/etc/ssl/glusterfs.key:
  x509.private_key_managed:
    - bits: 2048
    - prereq:
      - x509: /etc/ssl/glusterfs.pem

/etc/ssl/glusterfs.pem:
  x509.certificate_managed:
    - signing_private_key: /etc/ssl/glusterfs.key
    - CN: {{ grains.id }}
    - C: UA
    - basicConstraints: &quot;critical CA:true&quot;
    - keyUsage: &quot;critical cRLSign, keyCertSign&quot;
    - subjectKeyIdentifier: hash
    - authorityKeyIdentifier: keyid,issuer:always
    - days_valid: 3650
    - days_remaining: 0

push glusterfs cert:
  module.run:
    - mine.send:
      - x509.get_pem_entries
      - /etc/ssl/glusterfs.pem
    - onchanges:
      - x509: /etc/ssl/glusterfs.pem

/etc/ssl/glusterfs.ca:
  file.managed:
    - source: salt://pem_concat.jinja
    - template: jinja
</code></pre>
<pre><code>{% for certs in salt[&quot;mine.get&quot;](&quot;*&quot;, &quot;x509.get_pem_entries&quot;) -%}
{% for cert in certs.values() %}
{{ cert }}
{%- endfor %}
{%- endfor %}
</code></pre>
<p>That will need applying multiple times, as other minion generate their certs and send them to the mine.</p>
<p>The mine can also define in the minion config instead of as part of the state.</p>

CC BY-SA 4.0
2022-09-14T11:19:59.213Z
2022-09-14T11:19:59.213Z
OrangeDog
<p>I would like to have the following a bit more clean. I'm trying to create concatenated CA file using Salt.
To accomplish this I first have to collect all glusterfs.pem files from all my minions and transfer them to the salt-master's minions cache and then output all glusterfs.pem into a single CA file (glusterfs.ca) on the salt-master to later on enroll them again on all minions.</p>
<p>Actually my solution is working but it is simply out of the salt context and looks crappy to me. I'm new to salt, I never worked with reactors, so and I was hoping to find some help (preferably  with an example if possible) on this site.</p>
<p>This is my current situation only using states:</p>
<p>glusterfs/init.sls (only runs on minions)</p>
<pre><code>/etc/ssl/glusterfs.key:
  x509.private_key_managed:
    - order: 9
    - bits: 2048
    - name: /etc/ssl/glusterfs.key

/etc/ssl/glusterfs.pem:
  x509.certificate_managed:
    - order: 10
    - signing_private_key: /etc/ssl/glusterfs.key
    - CN: {{ grains.id }}
    - C: UA
    - ST: Unavailable
    - L: Unavailable
    - basicConstraints: &quot;critical CA:true&quot;
    - keyUsage: &quot;critical cRLSign, keyCertSign&quot;
    - subjectKeyIdentifier: hash
    - authorityKeyIdentifier: keyid,issuer:always
    - days_valid: 3650
    - days_remaining: 0

/etc/ssl/glusterfs.ca:
  file:
    - order: 11
    - managed
    - source: salt://glusterfs/glusterfs.ca
</code></pre>
<p>ca.sls (only runs on salt-master):</p>
<pre><code>collect_glusterfs_certs:
  cmd.run:
    - order: 1
    - name: salt -C 'not salt' cp.push /etc/ssl/glusterfs.pem

concatenation_glusterfs_certs:
  cmd.run:
    - order: 2
    - onlyif: 'test ! -e /var/cache/salt/master/minions/{master*,worker*}/files/etc/ssl/glusterfs.pem &amp;&amp; test ! -e /srv/salt/glusterfs/glusterfs.ca'
    - name: 'cat /var/cache/salt/master/minions/*/files/etc/ssl/glusterfs.pem &gt; /srv/salt/glusterfs/glusterfs.ca'
</code></pre>
<p>I basically first pull all glusterfs.pem to the local salt-master's minion cache and afterwards create the concatenated glusterfs.ca file which I  later deploy onto all the minions I previously collected the glusterfs.pem file from...</p>
<p>Thanks in advance</p>

<automation><salt>
Saltstack howto create a Concatenation CA?
V O
# Saltstack howto create a Concatenation CA?

(Asked by: username_0 on 2020-09-28)

I would like to have the following a bit more clean. I'm trying to create concatenated CA file using Salt.
To accomplish this I first have to collect all glusterfs.pem files from all my minions and transfer them to the salt-master's minions cache and then output all glusterfs.pem into a single CA file (glusterfs.ca) on the salt-master to later on enroll them again on all minions.
Actually my solution is working but it is simply out of the salt context and looks crappy to me. I'm new to salt, I never worked with reactors, so and I was hoping to find some help (preferably  with an example if possible) on this site.
This is my current situation only using states:
glusterfs/init.sls (only runs on minions)
/etc/ssl/glusterfs.key:
  x509.private_key_managed:
    - order: 9
    - bits: 2048
    - name: /etc/ssl/glusterfs.key

/etc/ssl/glusterfs.pem:
  x509.certificate_managed:
    - order: 10
    - signing_private_key: /etc/ssl/glusterfs.key
    - CN: {{ grains.id }}
    - C: UA
    - ST: Unavailable
    - L: Unavailable
    - basicConstraints: "critical CA:true"
    - keyUsage: "critical cRLSign, keyCertSign"
    - subjectKeyIdentifier: hash
    - authorityKeyIdentifier: keyid,issuer:always
    - days_valid: 3650
    - days_remaining: 0

/etc/ssl/glusterfs.ca:
  file:
    - order: 11
    - managed
    - source: salt://glusterfs/glusterfs.ca

ca.sls (only runs on salt-master):
collect_glusterfs_certs:
  cmd.run:
    - order: 1
    - name: salt -C 'not salt' cp.push /etc/ssl/glusterfs.pem

concatenation_glusterfs_certs:
  cmd.run:
    - order: 2
    - onlyif: 'test ! -e /var/cache/salt/master/minions/{master*,worker*}/files/etc/ssl/glusterfs.pem && test ! -e /srv/salt/glusterfs/glusterfs.ca'
    - name: 'cat /var/cache/salt/master/minions/*/files/etc/ssl/glusterfs.pem > /srv/salt/glusterfs/glusterfs.ca'

I basically first pull all glusterfs.pem to the local salt-master's minion cache and afterwards create the concatenated glusterfs.ca file which I  later deploy onto all the minions I previously collected the glusterfs.pem file from...
Thanks in advance

**Tags:** automation, salt


---

## 2 answers

### Answer by username_1 on 2021-05-12. Score: 1

It feels like what you have done here is implement a discount/bastardized CA (Certificate Authority). I fear that in doing so, you might have inadvertently created a security threat for yourself.

In a traditional PKI deployment, your client would generate a private key and a Certificate Signing Request (CSR) that is then submitted to your Certificate Authority for signing. Your CA would then sign your key after validating the applicant by some means and issue a Certificate to be installed on the client.

What you may have just done by concatenating every single certificate of each client into a CA is grant each and every client the ability to sign certificates for other machines. Any machine in your Gluster cluster then may have the ability to issue a certificate for an arbitrary key which then would be trusted by your Gluster cluster which could allow for an attacker to use a compromised system or key to allow an arbitrary endpoint to join your cluster.

Instead, you might want to follow this guide on [setting up a CA for use by your SaltStack](https://backbeat.tech/blog/using-saltstack-for-internal-ssl-certificates). In fact, it is worth noting that your salt master is itself a CA. You could simply copy the minion's certificate and key for use by gluster, though that has the downside of a compromised cert/key being able to be used to impersonate a minion.

But generally speaking, you probably don't want to grant all of your minions the power to be a CA.


---

### Answer by username_2 on 2022-09-14. Score: 0

You should use requisites to define the order of states, not order. Otherwise it's going to continue execution when necessary prerequisites fail.

To collect files from each minion, use the Salt Mine.

To concatenate the files, use file.managed with a jinja template.


So, if you really want to generate a self-signed unlimited CA on every minion and have all of them trust each other, your state could look something like this:
/etc/ssl/glusterfs.key:
  x509.private_key_managed:
    - bits: 2048
    - prereq:
      - x509: /etc/ssl/glusterfs.pem

/etc/ssl/glusterfs.pem:
  x509.certificate_managed:
    - signing_private_key: /etc/ssl/glusterfs.key
    - CN: {{ grains.id }}
    - C: UA
    - basicConstraints: "critical CA:true"
    - keyUsage: "critical cRLSign, keyCertSign"
    - subjectKeyIdentifier: hash
    - authorityKeyIdentifier: keyid,issuer:always
    - days_valid: 3650
    - days_remaining: 0

push glusterfs cert:
  module.run:
    - mine.send:
      - x509.get_pem_entries
      - /etc/ssl/glusterfs.pem
    - onchanges:
      - x509: /etc/ssl/glusterfs.pem

/etc/ssl/glusterfs.ca:
  file.managed:
    - source: salt://pem_concat.jinja
    - template: jinja

{% for certs in salt["mine.get"]("*", "x509.get_pem_entries") -%}
{% for cert in certs.values() %}
{{ cert }}
{%- endfor %}
{%- endfor %}

That will need applying multiple times, as other minion generate their certs and send them to the mine.
The mine can also define in the minion config instead of as part of the state.


---

