salt.modules.tls

A salt module for SSL/TLS. Can create a Certificate Authority (CA) or use Self-Signed certificates.

depends

PyOpenSSL Python module (0.10 or later, 0.14 or later for X509 extension support)

configuration

Add the following values in /etc/salt/minion for the CA module to function properly:

ca.cert_base_path: '/etc/pki'

CLI Example #1: Creating a CA, a server request and its signed certificate:

# salt-call tls.create_ca my_little \
days=5 \
CN='My Little CA' \
C=US \
ST=Utah \
L=Salt Lake City \
O=Saltstack \
emailAddress=pleasedontemail@example.com

Created Private Key: "/etc/pki/my_little/my_little_ca_cert.key"
Created CA "my_little_ca": "/etc/pki/my_little_ca/my_little_ca_cert.crt"

# salt-call tls.create_csr my_little CN=www.example.com
Created Private Key: "/etc/pki/my_little/certs/www.example.com.key
Created CSR for "www.example.com": "/etc/pki/my_little/certs/www.example.com.csr"

# salt-call tls.create_ca_signed_cert my_little CN=www.example.com
Created Certificate for "www.example.com": /etc/pki/my_little/certs/www.example.com.crt"

CLI Example #2: Creating a client request and its signed certificate

# salt-call tls.create_csr my_little CN=DBReplica_No.1 cert_type=client
Created Private Key: "/etc/pki/my_little/certs//DBReplica_No.1.key."
Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1.csr."

# salt-call tls.create_ca_signed_cert my_little CN=DBReplica_No.1
Created Certificate for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1.crt"

CLI Example #3: Creating both a server and client req + cert for the same CN

# salt-call tls.create_csr my_little CN=MasterDBReplica_No.2  \
    cert_type=client
Created Private Key: "/etc/pki/my_little/certs/MasterDBReplica_No.2.key."
Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/MasterDBReplica_No.2.csr."

# salt-call tls.create_ca_signed_cert my_little CN=MasterDBReplica_No.2
Created Certificate for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1.crt"

# salt-call tls.create_csr my_little CN=MasterDBReplica_No.2 \
    cert_type=server
Certificate "MasterDBReplica_No.2" already exists

(doh!)

# salt-call tls.create_csr my_little CN=MasterDBReplica_No.2 \
    cert_type=server type_ext=True
Created Private Key: "/etc/pki/my_little/certs/DBReplica_No.1_client.key."
Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/DBReplica_No.1_client.csr."

# salt-call tls.create_ca_signed_cert my_little CN=MasterDBReplica_No.2
Certificate "MasterDBReplica_No.2" already exists

(DOH!)

# salt-call tls.create_ca_signed_cert my_little CN=MasterDBReplica_No.2 \
    cert_type=server type_ext=True
Created Certificate for "MasterDBReplica_No.2": "/etc/pki/my_little/certs/MasterDBReplica_No.2_server.crt"

CLI Example #4: Create a server req + cert with non-CN filename for the cert

# salt-call tls.create_csr my_little CN=www.anothersometh.ing \
    cert_type=server type_ext=True
Created Private Key: "/etc/pki/my_little/certs/www.anothersometh.ing_server.key."
Created CSR for "DBReplica_No.1": "/etc/pki/my_little/certs/www.anothersometh.ing_server.csr."

# salt-call tls_create_ca_signed_cert my_little CN=www.anothersometh.ing \
    cert_type=server cert_filename="something_completely_different"
Created Certificate for "www.anothersometh.ing": /etc/pki/my_little/certs/something_completely_different.crt
salt.modules.tls.ca_exists(ca_name, cacert_path=None, ca_filename=None)

Verify whether a Certificate Authority (CA) already exists

ca_name

name of the CA

cacert_path

absolute path to ca certificates root directory

ca_filename

alternative filename for the CA

New in version 2015.5.3.

CLI Example:

salt '*' tls.ca_exists test_ca /etc/certs
salt.modules.tls.cert_base_path(cacert_path=None)

Return the base path for certs from CLI or from options

cacert_path

absolute path to ca certificates root directory

CLI Example:

salt '*' tls.cert_base_path
salt.modules.tls.cert_info(cert, digest='sha256')

Return information for a particular certificate

cert

path to the certifiate PEM file or string

Changed in version 2018.3.4.

digest

what digest to use for fingerprinting

CLI Example:

salt '*' tls.cert_info /dir/for/certs/cert.pem
salt.modules.tls.create_ca(ca_name, bits=2048, days=365, CN='localhost', C='US', ST='Utah', L='Salt Lake City', O='SaltStack', OU=None, emailAddress=None, fixmode=False, cacert_path=None, ca_filename=None, digest='sha256', onlyif=None, unless=None, replace=False)

Create a Certificate Authority (CA)

ca_name

name of the CA

bits

number of RSA key bits, default is 2048

days

number of days the CA will be valid, default is 365

CN

common name in the request, default is "localhost"

C

country, default is "US"

ST

state, default is "Utah"

L

locality, default is "Centerville", the city where SaltStack originated

O

organization, default is "SaltStack"

OU

organizational unit, default is None

emailAddress

email address for the CA owner, default is None

cacert_path

absolute path to ca certificates root directory

ca_filename

alternative filename for the CA

New in version 2015.5.3.

digest

The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: 'sha256'

replace

Replace this certificate even if it exists

New in version 2015.5.1.

Writes out a CA certificate based upon defined config values. If the file already exists, the function just returns assuming the CA certificate already exists.

If the following values were set:

ca.cert_base_path='/etc/pki'
ca_name='koji'

the resulting CA, and corresponding key, would be written in the following location with appropriate permissions:

/etc/pki/koji/koji_ca_cert.crt
/etc/pki/koji/koji_ca_cert.key

CLI Example:

salt '*' tls.create_ca test_ca
salt.modules.tls.create_ca_signed_cert(ca_name, CN, days=365, cacert_path=None, ca_filename=None, cert_path=None, cert_filename=None, digest='sha256', cert_type=None, type_ext=False, replace=False)

Create a Certificate (CERT) signed by a named Certificate Authority (CA)

If the certificate file already exists, the function just returns assuming the CERT already exists.

The CN must match an existing CSR generated by create_csr. If it does not, this method does nothing.

ca_name

name of the CA

CN

common name matching the certificate signing request

days

number of days certificate is valid, default is 365 (1 year)

cacert_path

absolute path to ca certificates root directory

ca_filename

alternative filename for the CA

New in version 2015.5.3.

cert_path

full path to the certificates directory

cert_filename

alternative filename for the certificate, useful when using special characters in the CN. If this option is set it will override the certificate filename output effects of cert_type. type_ext will be completely overridden.

New in version 2015.5.3.

digest

The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: 'sha256'

replace

Replace this certificate even if it exists

New in version 2015.5.1.

cert_type

string. Either 'server' or 'client' (see create_csr() for details).

If create_csr(type_ext=True) this function must be called with the same cert_type so it can find the CSR file.

Note

create_csr() defaults to cert_type='server'; therefore, if it was also called with type_ext, cert_type becomes a required argument for create_ca_signed_cert()

type_ext

bool. If set True, use cert_type as an extension to the CN when formatting the filename.

e.g.: some_subject_CN_server.crt or some_subject_CN_client.crt

This facilitates the context where both types are required for the same subject

If cert_filename is not None, setting type_ext has no effect

If the following values were set:

ca.cert_base_path='/etc/pki'
ca_name='koji'
CN='test.egavas.org'

the resulting signed certificate would be written in the following location:

/etc/pki/koji/certs/test.egavas.org.crt

CLI Example:

salt '*' tls.create_ca_signed_cert test localhost
salt.modules.tls.create_csr(ca_name, bits=2048, CN='localhost', C='US', ST='Utah', L='Salt Lake City', O='SaltStack', OU=None, emailAddress=None, subjectAltName=None, cacert_path=None, ca_filename=None, csr_path=None, csr_filename=None, digest='sha256', type_ext=False, cert_type='server', replace=False)

Create a Certificate Signing Request (CSR) for a particular Certificate Authority (CA)

ca_name

name of the CA

bits

number of RSA key bits, default is 2048

CN

common name in the request, default is "localhost"

C

country, default is "US"

ST

state, default is "Utah"

L

locality, default is "Centerville", the city where SaltStack originated

O

organization, default is "SaltStack" NOTE: Must the same as CA certificate or an error will be raised

OU

organizational unit, default is None

emailAddress

email address for the request, default is None

subjectAltName

valid subjectAltNames in full form, e.g. to add DNS entry you would call this function with this value:

examples: ['DNS:somednsname.com',

'DNS:1.2.3.4', 'IP:1.2.3.4', 'IP:2001:4801:7821:77:be76:4eff:fe11:e51', 'email:me@i.like.pie.com']

Note

some libraries do not properly query IP: prefixes, instead looking for the given req. source with a DNS: prefix. To be thorough, you may want to include both DNS: and IP: entries if you are using subjectAltNames for destinations for your TLS connections. e.g.: requests to https://1.2.3.4 will fail from python's requests library w/out the second entry in the above list

New in version 2015.8.0.

cert_type

Specify the general certificate type. Can be either server or client. Indicates the set of common extensions added to the CSR.

server: {
   'basicConstraints': 'CA:FALSE',
   'extendedKeyUsage': 'serverAuth',
   'keyUsage': 'digitalSignature, keyEncipherment'
}

client: {
   'basicConstraints': 'CA:FALSE',
   'extendedKeyUsage': 'clientAuth',
   'keyUsage': 'nonRepudiation, digitalSignature, keyEncipherment'
}
type_ext

boolean. Whether or not to extend the filename with CN_[cert_type] This can be useful if a server and client certificate are needed for the same CN. Defaults to False to avoid introducing an unexpected file naming pattern

The files normally named some_subject_CN.csr and some_subject_CN.key will then be saved

replace

Replace this signing request even if it exists

New in version 2015.5.1.

Writes out a Certificate Signing Request (CSR) If the file already exists, the function just returns assuming the CSR already exists.

If the following values were set:

ca.cert_base_path='/etc/pki'
ca_name='koji'
CN='test.egavas.org'

the resulting CSR, and corresponding key, would be written in the following location with appropriate permissions:

/etc/pki/koji/certs/test.egavas.org.csr
/etc/pki/koji/certs/test.egavas.org.key

CLI Example:

salt '*' tls.create_csr test
salt.modules.tls.create_empty_crl(ca_name, cacert_path=None, ca_filename=None, crl_file=None, digest='sha256')

Create an empty Certificate Revocation List.

New in version 2015.8.0.

ca_name

name of the CA

cacert_path

absolute path to ca certificates root directory

ca_filename

alternative filename for the CA

New in version 2015.5.3.

crl_file

full path to the CRL file

digest

The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: 'sha256'

CLI Example:

salt '*' tls.create_empty_crl ca_name='koji'                 ca_filename='ca'                 crl_file='/etc/openvpn/team1/crl.pem'
salt.modules.tls.create_pkcs12(ca_name, CN, passphrase='', cacert_path=None, replace=False)

Create a PKCS#12 browser certificate for a particular Certificate (CN)

ca_name

name of the CA

CN

common name matching the certificate signing request

passphrase

used to unlock the PKCS#12 certificate when loaded into the browser

cacert_path

absolute path to ca certificates root directory

replace

Replace this certificate even if it exists

New in version 2015.5.1.

If the following values were set:

ca.cert_base_path='/etc/pki'
ca_name='koji'
CN='test.egavas.org'

the resulting signed certificate would be written in the following location:

/etc/pki/koji/certs/test.egavas.org.p12

CLI Example:

salt '*' tls.create_pkcs12 test localhost
salt.modules.tls.create_self_signed_cert(tls_dir='tls', bits=2048, days=365, CN='localhost', C='US', ST='Utah', L='Salt Lake City', O='SaltStack', OU=None, emailAddress=None, cacert_path=None, cert_filename=None, digest='sha256', replace=False)

Create a Self-Signed Certificate (CERT)

tls_dir

location appended to the ca.cert_base_path, default is 'tls'

bits

number of RSA key bits, default is 2048

CN

common name in the request, default is "localhost"

C

country, default is "US"

ST

state, default is "Utah"

L

locality, default is "Centerville", the city where SaltStack originated

O

organization, default is "SaltStack" NOTE: Must the same as CA certificate or an error will be raised

OU

organizational unit, default is None

emailAddress

email address for the request, default is None

cacert_path

absolute path to ca certificates root directory

digest

The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: 'sha256'

replace

Replace this certificate even if it exists

New in version 2015.5.1.

Writes out a Self-Signed Certificate (CERT). If the file already exists, the function just returns.

If the following values were set:

ca.cert_base_path='/etc/pki'
tls_dir='koji'
CN='test.egavas.org'

the resulting CERT, and corresponding key, would be written in the following location with appropriate permissions:

/etc/pki/koji/certs/test.egavas.org.crt
/etc/pki/koji/certs/test.egavas.org.key

CLI Example:

salt '*' tls.create_self_signed_cert

Passing options from the command line:

salt 'minion' tls.create_self_signed_cert CN='test.mysite.org'
salt.modules.tls.get_ca(ca_name, as_text=False, cacert_path=None)

Get the certificate path or content

ca_name

name of the CA

as_text

if true, return the certificate content instead of the path

cacert_path

absolute path to ca certificates root directory

CLI Example:

salt '*' tls.get_ca test_ca as_text=False cacert_path=/etc/certs
salt.modules.tls.get_ca_signed_cert(ca_name, CN='localhost', as_text=False, cacert_path=None, cert_filename=None)

Get the certificate path or content

ca_name

name of the CA

CN

common name of the certificate

as_text

if true, return the certificate content instead of the path

cacert_path

absolute path to certificates root directory

cert_filename

alternative filename for the certificate, useful when using special characters in the CN

New in version 2015.5.3.

CLI Example:

salt '*' tls.get_ca_signed_cert test_ca CN=localhost as_text=False cacert_path=/etc/certs
salt.modules.tls.get_ca_signed_key(ca_name, CN='localhost', as_text=False, cacert_path=None, key_filename=None)

Get the certificate path or content

ca_name

name of the CA

CN

common name of the certificate

as_text

if true, return the certificate content instead of the path

cacert_path

absolute path to certificates root directory

key_filename

alternative filename for the key, useful when using special characters

New in version 2015.5.3.

in the CN

CLI Example:

salt '*' tls.get_ca_signed_key                 test_ca CN=localhost                 as_text=False                 cacert_path=/etc/certs
salt.modules.tls.get_expiration_date(cert, date_format='%Y-%m-%d')

New in version 2019.2.0.

Get a certificate's expiration date

cert

Full path to the certificate

date_format

By default this will return the expiration date in YYYY-MM-DD format, use this to specify a different strftime format string. Note that the expiration time will be in UTC.

CLI Examples:

salt '*' tls.get_expiration_date /path/to/foo.crt
salt '*' tls.get_expiration_date /path/to/foo.crt date_format='%d/%m/%Y'
salt.modules.tls.get_extensions(cert_type)

Fetch X509 and CSR extension definitions from tls:extensions: (common|server|client) or set them to standard defaults.

New in version 2015.8.0.

cert_type:

The type of certificate such as server or client.

CLI Example:

salt '*' tls.get_extensions client
salt.modules.tls.maybe_fix_ssl_version(ca_name, cacert_path=None, ca_filename=None)

Check that the X509 version is correct (was incorrectly set in previous salt versions). This will fix the version if needed.

ca_name

ca authority name

cacert_path

absolute path to ca certificates root directory

ca_filename

alternative filename for the CA

New in version 2015.5.3.

CLI Example:

salt '*' tls.maybe_fix_ssl_version test_ca /etc/certs
salt.modules.tls.revoke_cert(ca_name, CN, cacert_path=None, ca_filename=None, cert_path=None, cert_filename=None, crl_file=None, digest='sha256')

Revoke a certificate.

New in version 2015.8.0.

ca_name

Name of the CA.

CN

Common name matching the certificate signing request.

cacert_path

Absolute path to ca certificates root directory.

ca_filename

Alternative filename for the CA.

cert_path

Path to the cert file.

cert_filename

Alternative filename for the certificate, useful when using special characters in the CN.

crl_file

Full path to the CRL file.

digest

The message digest algorithm. Must be a string describing a digest algorithm supported by OpenSSL (by EVP_get_digestbyname, specifically). For example, "md5" or "sha1". Default: 'sha256'

CLI Example:

salt '*' tls.revoke_cert ca_name='koji'                 ca_filename='ca'                 crl_file='/etc/openvpn/team1/crl.pem'
salt.modules.tls.set_ca_path(cacert_path)

If wanted, store the aforementioned cacert_path in context to be used as the basepath for further operations

CLI Example:

salt '*' tls.set_ca_path /etc/certs
salt.modules.tls.validate(cert, ca_name, crl_file)

New in version 3000.

Validate a certificate against a given CA/CRL.

cert

path to the certifiate PEM file or string

ca_name

name of the CA

crl_file

full path to the CRL file