salt.modules.ssh_pki

Manage OpenSSH keys and certificates

New in version 3008.0.

depends:

cryptography

Note

  • Certificate operations require at least cryptography release 40

  • Certificate operations with force-command and source-address (or any critical option/extension with a value) should only be relied upon in releases >= 41.0.2 (https://github.com/pyca/cryptography/issues/9207)

  • Operations with encrypted private keys require the bcrypt module, which is installable as cryptography[ssh] as well.

Configuration

Peer communication

To be able to remotely sign certificates, it is required to configure the Salt master to allow Peer Communication:

# /etc/salt/master.d/peer.conf

peer:
  .*:
    - ssh_pki.sign_remote_certificate

In order for the Compound Matcher to work with restricting signing policies to a subset of minions, in addition calls to match.compound by the minion acting as the CA must be permitted:

# /etc/salt/master.d/peer.conf

peer:
  .*:
    - ssh_pki.sign_remote_certificate

  ca_server:
    - match.compound

Signing policies

In addition, the minion representing the CA needs to have at least one signing policy configured, remote calls not referencing one are always rejected.

The parameters specified in this signing policy override any parameters passed from the minion requesting the certificate. It can be configured in the CA minion's pillar, which takes precedence, or any location config.get looks up in. Signing policies are defined under ssh_signing_policies.

Special handling

In addition to forcing some arguments to a specific value, signing policies can also specify default and allowed values.

allowed_critical_options

A list of critical option names that can be requested to be set under this policy. Defaults to all (["*"]).

allowed_extensions

A list of extension names that can be requested to be set under this policy. Defaults to all (["*"]).

allowed_valid_principals

A list of principals that can be requested to be set under this policy. This is an alias for valid_principals since requesting less permissions is always possible.

default_critical_options

Defines default critical options that can be overridden by the requester.

default_extensions

Defines default extensions that can be overridden by the requester.

default_valid_principals

Defines default principals that can be overridden by the requester. Defaults to allowed_valid_principals

critical_options

Values set here are forced as usual, but per critical option.

extensions

Values set here are forced as usual, but per extension.

max_ttl

The maximum TTL that can be requested under this policy.

ttl

The default TTL that can be overridden by the requester. Defaults to max_ttl.

Restricting requesters

You can restrict which minions can request a certificate under a configured signing policy by specifying a matcher in minions. This can be a glob or compound matcher (for the latter, see the notes above).

ssh_signing_policies:
  www_host:
    - minions: 'www*'
    - signing_private_key: /etc/pki/ssh/ca.key
    - ttl: 30d
    - copypath: /etc/pki/ssh/issued_certs/
salt.modules.ssh_pki.create_certificate(ca_server=None, signing_policy=None, path=None, overwrite=False, raw=False, **kwargs)

Create an OpenSSH certificate and return an encoded version of it.

Note

All parameters that take a public key or private key can be specified either as a string or a path to a local file encoded for OpenSSH.

CLI Example:

salt '*' ssh_pki.create_certificate private_key=/root/.ssh/id_rsa signing_private_key='/etc/pki/ssh/myca.key'
ca_server

Request a remotely signed certificate from another minion acting as a CA server. For this to work, a signing_policy must be specified, and that same policy must be configured on the ca_server. See Signing policies for details. Also, the Salt master must permit peers to call the sign_remote_certificate function, see Peer communication.

signing_policy

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. See Signing policies for details.

copypath

Create a copy of the issued certificate in this directory. The file will be named <serial_number>.crt.

path

Instead of returning the certificate, write it to this file path.

overwrite

If path is specified and the file exists, do not overwrite it. Defaults to false.

raw

Return the encoded raw bytes instead of a string. Defaults to false.

cert_type

The certificate type to generate. Either user or host. Required if not specified in the signing policy.

private_key

The private key corresponding to the public key the certificate should be issued for. Either this or public_key is required.

private_key_passphrase

If private_key is specified and encrypted, the passphrase to decrypt it.

public_key

The public key the certificate should be issued for. Either this or private_key is required.

signing_private_key

The private key of the CA that should be used to sign the certificate. Required.

signing_private_key_passphrase

If signing_private_key is encrypted, the passphrase to decrypt it.

serial_number

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.

not_before

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.

not_after

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.

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.

critical_options

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.

Example:

salt-call ssh_pki.create_certificate [...]               critical_options='{"force-command": "/usr/bin/id", "verify-required": true}'
extensions

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.

Example:

salt-call ssh_pki.create_certificate [...]               extensions='{"custom-option@my.org": "foobar", "permit-pty": true}'
valid_principals

A list of valid principals.

all_principals

Allow any principals. Defaults to false.

key_id

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.

salt.modules.ssh_pki.create_certificate_ssh(ca_server=None, signing_policy=None, path=None, overwrite=False, raw=False, **kwargs)

This function is an alias of create_certificate.

Create an OpenSSH certificate and return an encoded version of it.

Note

All parameters that take a public key or private key can be specified either as a string or a path to a local file encoded for OpenSSH.

CLI Example:

salt '*' ssh_pki.create_certificate private_key=/root/.ssh/id_rsa signing_private_key='/etc/pki/ssh/myca.key'
ca_server

Request a remotely signed certificate from another minion acting as a CA server. For this to work, a signing_policy must be specified, and that same policy must be configured on the ca_server. See Signing policies for details. Also, the Salt master must permit peers to call the sign_remote_certificate function, see Peer communication.

signing_policy

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. See Signing policies for details.

copypath

Create a copy of the issued certificate in this directory. The file will be named <serial_number>.crt.

path

Instead of returning the certificate, write it to this file path.

overwrite

If path is specified and the file exists, do not overwrite it. Defaults to false.

raw

Return the encoded raw bytes instead of a string. Defaults to false.

cert_type

The certificate type to generate. Either user or host. Required if not specified in the signing policy.

private_key

The private key corresponding to the public key the certificate should be issued for. Either this or public_key is required.

private_key_passphrase

If private_key is specified and encrypted, the passphrase to decrypt it.

public_key

The public key the certificate should be issued for. Either this or private_key is required.

signing_private_key

The private key of the CA that should be used to sign the certificate. Required.

signing_private_key_passphrase

If signing_private_key is encrypted, the passphrase to decrypt it.

serial_number

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.

not_before

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.

not_after

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.

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.

critical_options

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.

Example:

salt-call ssh_pki.create_certificate [...]               critical_options='{"force-command": "/usr/bin/id", "verify-required": true}'
extensions

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.

Example:

salt-call ssh_pki.create_certificate [...]               extensions='{"custom-option@my.org": "foobar", "permit-pty": true}'
valid_principals

A list of valid principals.

all_principals

Allow any principals. Defaults to false.

key_id

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.

salt.modules.ssh_pki.create_private_key(algo='rsa', keysize=None, passphrase=None, path=None, pubkey_suffix='.pub', overwrite=False, raw=False, **kwargs)

Create a private key.

CLI Example:

salt '*' ssh_pki.create_private_key algo=ec keysize=384
algo

The digital signature scheme the private key should be based on. Available: rsa, ec, ed25519. Defaults to rsa.

keysize

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 3072 for RSA and 256 for EC.

passphrase

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.

path

Instead of returning the private key, write it to this file path. The file will be written with 0600 permissions if it does not exist.

pubkey_suffix

If path is specified, write the corresponding pubkey to the same path as the private key with this suffix. Set this to false to skip writing the public key. Defaults to .pub.

overwrite

If path is specified and the file exists, overwrite it. Defaults to false.

raw

Return the encoded raw bytes instead of a string. Defaults to false.

salt.modules.ssh_pki.encode_private_key(private_key, private_key_passphrase=None, passphrase=None, raw=False)

Create an encoded representation of a private key.

CLI Example:

salt '*' ssh_ppki.encode_private_key /root/.ssh/id_rsa passphrase=hunter1
private_key

The private key to encode.

private_key_passphrase

The passphrase that protects the private key. Leave unspecified if there is none currently.

passphrase

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.

raw

Return the encoded raw bytes instead of a string. Defaults to false.

salt.modules.ssh_pki.expires(certificate, ttl=0)

Determine whether a certificate will expire or has expired already. Returns a boolean only.

CLI Example:

salt '*' ssh_pki.expires /root/.ssh/id_rsa.crt days=7
certificate

The certificate to check.

ttl

If specified, determine expiration x seconds in the future. Can also be specified as a time string like 30d or 1.5h. Defaults to 0, which checks for the current time.

salt.modules.ssh_pki.get_private_key_size(private_key, passphrase=None)

Return information about the key size of a private key (RSA/EC).

CLI Example:

salt '*' ssh_pki.get_private_key_size /root/.ssh/id_rsa
private_key

The private key to check.

passphrase

If private_key is encrypted, the passphrase to decrypt it.

salt.modules.ssh_pki.get_public_key(key, passphrase=None)

Returns a public key derived from some reference. The reference should be a public key, certificate or private key.

CLI Example:

salt '*' ssh_pki.get_public_key /root/.ssh/id_rsa
key

A reference to the structure to look the public key up for.

passphrase

If key is encrypted, the passphrase to decrypt it.

salt.modules.ssh_pki.get_signing_policy(signing_policy, ca_server=None)

Returns the specified named signing policy.

CLI Example:

salt '*' ssh_pki.get_signing_policy www
signing_policy

The name of the signing policy to return.

ca_server

If this is set, the CA server will be queried for the signing policy instead of looking it up locally.

salt.modules.ssh_pki.read_certificate(certificate)

Returns a dict containing details of a certificate.

CLI Example:

salt '*' ssh_pki.read_certificate /root/.ssh/id_rsa.crt
certificate

The certificate to read.

salt.modules.ssh_pki.sign_remote_certificate(signing_policy, kwargs, get_signing_policy_only=False, **more_kwargs)

Request a certificate to be remotely signed according to a signing policy. This is mostly for internal use and does not make much sense on the CLI.

CLI Example:

salt '*' ssh_pki.sign_remote_certificate www kwargs="{'public_key': '/etc/pki/ssh/www.key'}"
signing_policy

The name of the signing policy to use. Required.

kwargs

A dict containing all the arguments to be passed into the ssh_pki.create_certificate function.

get_signing_policy_only

Only return the named signing policy. Defaults to false.

salt.modules.ssh_pki.verify_private_key(private_key, public_key, passphrase=None)

Verify that a private key belongs to the specified public key.

CLI Example:

salt '*' ssh_pki.verify_private_key /root/.ssh/id_rsa /root/.ssh/id_rsa.crt
private_key

The private key to check.

public_key

The certificate (or any reference that can be passed to get_public_key) to retrieve the public key from.

passphrase

If private_key is encrypted, the passphrase to decrypt it.

salt.modules.ssh_pki.verify_signature(certificate, signing_pub_key, signing_pub_key_passphrase=None)

Verify that a signature on a certificate was made by the private key corresponding to the public key associated with the specified certificate.

CLI Example:

salt '*' ssh_pki.verify_signature /root/.ssh/id_rsa.crt /etc/pki/ssh/myca.pub
certificate

The certificate to check the signature on.

signing_pub_key

Any reference that can be passed to get_public_key to retrieve the public key of the signing entity from.

signing_pub_key_passphrase

If signing_pub_key is encrypted, the passphrase to decrypt it.