New in version 3008.0.
cryptography
Configuration instructions and general remarks are documented in the execution module docs.
This module can enable managing a complete SSH PKI infrastructure, including creating private keys, CAs and certificates. It includes the ability to generate a private key on a server, and have the corresponding public key sent to a remote CA to create a CA-signed certificate. This can be done in a secure manner, where private keys are always generated locally and never moved across the network.
Note
In addition to the native Salt backend (the ssh_pki execution module),
you can have the state module call a different (compatible) execution module
using the backend parameter.
Example
Here is a simple example scenario. In this example, ca is the CA server
and www is a web server that needs a certificate signed by ca.
Note
Remote signing using the native Salt backend requires the setup of Peer Communication and signing policies. Please see the execution module docs.
/srv/salt/top.sls
base:
'*':
- cert
'ca':
- ca
'www':
- www
This state creates the CA key and signing policy. It also publishes the public key to the mine, where it can be easily retrieved by other minions.
# /srv/salt/ca.sls
Ensure SSH PKI directories exist:
file.directory:
- name: /etc/pki/ssh/issued_certs
- makedirs: true
Create CA private key:
ssh_pki.private_key_managed:
- name: /etc/pki/ssh/ca.key
- algo: ed25519
- backup: true
- require:
- file: /etc/pki/ssh/issued_certs
Write CA public key:
ssh_pki.public_key_managed:
- name: /etc/pki/ssh/ca.pub
- public_key_source: /etc/pki/ssh/ca.key
- require:
- ssh_pki: /etc/pki/ssh/ca.key
# /srv/salt/ssh_pki.conf
# publish the CA certificate to the mine
mine_functions:
ssh_ca:
- mine_function: ssh_pki.get_public_key
- /etc/pki/ssh/ca.key
# define at least one signing policy for remote signing
ssh_signing_policies:
www_host:
- minions: 'www'
- signing_private_key: /etc/pki/ssh/ca.key
- cert_type: host
- ttl: 7d
- copypath: /etc/pki/ssh/issued_certs/
This example state will instruct minion SSH servers to trust certificates signed by our new CA. Mind that the specifics depend on the OS.
# /srv/salt/cert.sls
Write the trusted CA file:
file.managed:
- name: /etc/ssh/trusted-user-ca-keys.pem
- contents: {{ salt["mine.get"]("ca", "ssh_ca")["ca"] | json }}
- user: root
- group: root
Ensure SSH is configured to trust the CA:
file.managed:
- name: /etc/ssh/sshd_config.d/salt_ca_trust.conf
- contents: |
TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
- require:
- file: /etc/ssh/trusted-user-ca-keys.pem
This state creates a private key to use as the host key, then requests
a certificate signed by our CA according to the www_host policy and configures
the SSH server to use it.
# /srv/salt/www.sls
Create host private key:
ssh_pki.private_key_managed:
- name: /etc/ssh/ssh_host_rsa_key
- algo: ed25519
- backup: true
Request certificate:
ssh_pki.certificate_managed:
- name: /etc/ssh/ssh_host_rsa_key.pub
- ca_server: ca
- signing_policy: www_host
- private_key: /etc/ssh/ssh_host_rsa_key
- backup: true
- require:
- ssh_pki: /etc/ssh/ssh_host_rsa_key
Ensure SSH is configured to use the certificate:
file.managed:
- name: /etc/ssh/sshd_config.d/host_cert.conf
- contents: |
HostKey /etc/ssh/ssh_host_rsa_key
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
- require:
- ssh_pki: /etc/ssh/ssh_host_rsa_key
- ssh_pki: /etc/ssh/ssh_host_rsa_key.pub
Ensure an OpenSSH certificate is present as specified.
This function accepts the same arguments as
ssh_pki.create_certificate,
as well as most ones for :py:func:`file.managed <salt.states.file.managed>.
Note
Since file.managed also has an encoding param, it can be passed
as file_encoding instead.
The path the certificate should be present at.
The certificate will be recreated once the remaining certificate validity
period is less than this number of seconds. Can also be specified as a
time string like 12d or 1.5h.
Defaults to 30d for host keys and 1h for user keys.
Request a remotely signed certificate from another minion acting as
a CA server via the ssh_pki execution module. For this to
work, a signing_policy must be specified, and that same policy
must be configured on the ca_server. Also, the Salt master must
permit peers to call the ssh_pki.sign_remote_certificate function.
See the execution module docs for details.
Instead of using the ssh_pki execution module for certificate
creation, use this backend. It must provide a compatible API for
create_certificate and get_signing_policy.
If backend is specified, pass these additional keyword arguments
to it. Must be a mapping (dict).
The name of a configured signing policy. Parameters specified in there are hardcoded and cannot be overridden. This is required for remote signing, otherwise optional.
Create a copy of the issued certificate in this directory.
The file will be named <serial_number>.crt.
The certificate type to generate. Either user or host.
Required if not specified in the signing policy.
The private key corresponding to the public key the certificate should
be issued for. Either this or public_key is required.
If private_key is specified and encrypted, the passphrase to decrypt it.
The public key the certificate should be issued for. Either this or
private_key is required.
The private key of the CA that should be used to sign the certificate. Required.
If signing_private_key is encrypted, the passphrase to decrypt it.
A serial number to be embedded in the certificate. If unspecified, will autogenerate one. This should be an integer, either in decimal or hexadecimal notation.
Set a specific date the certificate should not be valid before.
The format should follow %Y-%m-%d %H:%M:%S and will be interpreted as GMT/UTC.
Defaults to the time of issuance.
Set a specific date the certificate should not be valid after.
The format should follow %Y-%m-%d %H:%M:%S and will be interpreted as GMT/UTC.
If unspecified, defaults to the current time plus ttl.
If not_after is unspecified, a time string (like 30d or 12h)
or the number of seconds from the time of issuance the certificate
should be valid for. Defaults to 30d for host certificates
and 24h for client certificates.
A mapping of critical option name to option value to set on the certificate.
If an option does not take a value, specify it as true.
A mapping of extension name to extension value to set on the certificate.
If an extension does not take a value, specify it as true.
A list of valid principals.
Allow any principals. Defaults to false.
Specify a string-valued key ID for the signed public key. When the certificate is used for authentication, this value will be logged in plaintext.
Helper for the SSH wrapper module.
This receives a certificate and dumps the data to the target.
A file.managed sub-state run will be performed.
Ensure a private key is present as specified.
This function accepts the same arguments as
ssh_pki.create_private_key,
as well as most ones for file.managed.
Note
If mode is unspecified, it will default to 0400.
The path the private key should be present at.
The digital signature scheme the private key should be based on.
Available: rsa, ec, ed25519. Defaults to rsa.
For rsa, specifies the bitlength of the private key (2048, 3072, 4096).
For ec, specifies the NIST curve to use (256, 384, 521).
Irrelevant for ed25519.
Defaults to 2048 for RSA and 256 for EC.
If this is specified, the private key will be encrypted using this passphrase. The encryption algorithm cannot be selected, it will be determined automatically as the best available one.
Always create a new key. Defaults to false.
Combining new with prereq
can allow key rotation whenever a new certificate is generated.
Overwrite an existing private key if the provided passphrase cannot decrypt it. Defaults to false.
Example:
The Jinja templating in this example ensures a new private key is generated if the file does not exist and whenever the associated certificate is to be renewed.
Manage www private key:
ssh_pki.private_key_managed:
- name: /root/.ssh/www
- keysize: 4096
- new: true
{%- if salt["file.file_exists"]("/root/.ssh/www") %}
- prereq:
- ssh_pki: /root/.ssh/www.crt
{%- endif %}
Helper for the SSH wrapper module to report the correct return and
perform a file.managed sub-state run.
Ensure a public key is present as specified.
This function accepts most arguments for file.managed.
Note
If mode is unspecified, it will default to 0400.
The path the public key should be present at.
The certificate (or any reference that can be passed
to get_public_key) to retrieve the public key from.
If public_key_source is an encrypted private key,
specify its passphrase here.