* conversion stage 1 * correct image paths * add sidebar title to frontmatter * docs/concepts and docs/internals * configuration docs and multi-level nav corrections * commands docs, index file corrections, small item nav correction * secrets converted * auth * add enterprise and agent docs * add extra dividers * secret section, wip * correct sidebar nav title in front matter for apu section, start working on api items * auth and backend, a couple directory structure fixes * remove old docs * intro side nav converted * reset sidebar styles, add hashi-global-styles * basic styling for nav sidebar * folder collapse functionality * patch up border length on last list item * wip restructure for content component * taking middleman hacking to the extreme, but its working * small css fix * add new mega nav * fix a small mistake from the rebase * fix a content resolution issue with middleman * title a couple missing docs pages * update deps, remove temporary markup * community page * footer to layout, community page css adjustments * wip downloads page * deps updated, downloads page ready * fix community page * homepage progress * add components, adjust spacing * docs and api landing pages * a bunch of fixes, add docs and api landing pages * update deps, add deploy scripts * add readme note * update deploy command * overview page, index title * Update doc fields Note this still requires the link fields to be populated -- this is solely related to copy on the description fields * Update api_basic_categories.yml Updated API category descriptions. Like the document descriptions you'll still need to update the link headers to the proper target pages. * Add bottom hero, adjust CSS, responsive friendly * Add mega nav title * homepage adjustments, asset boosts * small fixes * docs page styling fixes * meganav title * some category link corrections * Update API categories page updated to reflect the second level headings for api categories * Update docs_detailed_categories.yml Updated to represent the existing docs structure * Update docs_detailed_categories.yml * docs page data fix, extra operator page remove * api data fix * fix makefile * update deps, add product subnav to docs and api landing pages * Rearrange non-hands-on guides to _docs_ Since there is no place for these on learn.hashicorp, we'll put them under _docs_. * WIP Redirects for guides to docs * content and component updates * font weight hotfix, redirects * fix guides and intro sidenavs * fix some redirects * small style tweaks * Redirects to learn and internally to docs * Remove redirect to `/vault` * Remove `.html` from destination on redirects * fix incorrect index redirect * final touchups * address feedback from michell for makefile and product downloads
14 KiB
layout | page_title | sidebar_title | sidebar_current | description |
---|---|---|---|---|
docs | Signed SSH Certificates - SSH - Secrets Engines | Signed Certificates | docs-secrets-ssh-signed-ssh-certificates | The signed SSH certificates is the simplest and most powerful in terms of setup complexity and in terms of being platform agnostic. When using this type, an SSH CA signing key is generated or configured at the secrets engine's mount. This key will be used to sign other SSH keys. |
Signed SSH Certificates
The signed SSH certificates is the simplest and most powerful in terms of setup complexity and in terms of being platform agnostic. By leveraging Vault's powerful CA capabilities and functionality built into OpenSSH, clients can SSH into target hosts using their own local SSH keys.
In this section, the term "client" refers to the person or machine performing the SSH operation. The "host" refers to the target machine. If this is confusing, substitute "client" with "user".
This page will show a quick start for this secrets engine. For detailed documentation
on every path, use vault path-help
after mounting the secrets engine.
Client Key Signing
Before a client can request their SSH key be signed, the Vault SSH secrets engine must be configured. Usually a Vault administrator or security team performs these steps. It is also possible to automate these actions using a configuration management tool like Chef, Puppet, Ansible, or Salt.
Signing Key & Role Configuration
The following steps are performed in advance by a Vault administrator, security team, or configuration management tooling.
-
Mount the secrets engine. Like all secrets engines in Vault, the SSH secrets engine must be mounted before use.
$ vault secrets enable -path=ssh-client-signer ssh Successfully mounted 'ssh' at 'ssh-client-signer'!
This enables the SSH secrets engine at the path "ssh-client-signer". It is possible to mount the same secrets engine multiple times using different
-path
arguments. The name "ssh-client-signer" is not special - it can be any name, but this documentation will assume "ssh-client-signer". -
Configure Vault with a CA for signing client keys using the
/config/ca
endpoint. If you do not have an internal CA, Vault can generate a keypair for you.$ vault write ssh-client-signer/config/ca generate_signing_key=true Key Value --- ----- public_key ssh-rsa AAAAB3NzaC1yc2EA...
If you already have a keypair, specify the public and private key parts as part of the payload:
$ vault write ssh-client-signer/config/ca \ private_key="..." \ public_key="..."
Regardless of whether it is generated or uploaded, the client signer public key is accessible via the API at the
/public_key
endpoint. -
Add the public key to all target host's SSH configuration. This process can be manual or automated using a configuration management tool. The public key is accessible via the API and does not require authentication.
$ curl -o /etc/ssh/trusted-user-ca-keys.pem http://127.0.0.1:8200/v1/ssh-client-signer/public_key
$ vault read -field=public_key ssh-client-signer/config/ca > /etc/ssh/trusted-user-ca-keys.pem
Add the path where the public key contents are stored to the SSH configuration file as the
TrustedUserCAKeys
option.# /etc/ssh/sshd_config # ... TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
Restart the SSH service to pick up the changes.
-
Create a named Vault role for signing client keys.
Because of the way some SSH certificate features are implemented, options are passed as a map. The following example adds the
permit-pty
extension to the certificate.$ vault write ssh-client-signer/roles/my-role -<<"EOH" { "allow_user_certificates": true, "allowed_users": "*", "default_extensions": [ { "permit-pty": "" } ], "key_type": "ca", "default_user": "ubuntu", "ttl": "30m0s" } EOH
Client SSH Authentication
The following steps are performed by the client (user) that wants to authenticate to machines managed by Vault. These commands are usually run from the client's local workstation.
-
Locate or generate the SSH public key. Usually this is
~/.ssh/id_rsa.pub
. If you do not have an SSH keypair, generate one:$ ssh-keygen -t rsa -C "user@example.com"
-
Ask Vault to sign your public key. This file usually ends in
.pub
and the contents begin withssh-rsa ...
.$ vault write ssh-client-signer/sign/my-role \ public_key=@$HOME/.ssh/id_rsa.pub Key Value --- ----- serial_number c73f26d2340276aa signed_key ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1...
The result will include the serial and the signed key. This signed key is another public key.
To customize the signing options, use a JSON payload:
$ vault write ssh-client-signer/sign/my-role -<<"EOH" { "public_key": "ssh-rsa AAA...", "valid_principals": "my-user", "key_id": "custom-prefix", "extension": { "permit-pty": "" } } EOH
-
Save the resulting signed, public key to disk. Limit permissions as needed.
$ vault write -field=signed_key ssh-client-signer/sign/my-role \ public_key=@$HOME/.ssh/id_rsa.pub > signed-cert.pub
If you are saving the certificate directly beside your SSH keypair, suffix the name with
-cert.pub
(~/.ssh/id_rsa-cert.pub
). With this naming scheme, OpenSSH will automatically use it during authentication. -
(Optional) View enabled extensions, principals, and metadata of the signed key.
$ ssh-keygen -Lf ~/.ssh/signed-cert.pub
-
SSH into the host machine using the signed key. You must supply both the signed public key from Vault and the corresponding private key as authentication to the SSH call.
$ ssh -i signed-cert.pub -i ~/.ssh/id_rsa username@10.0.23.5
Host Key Signing
For an added layers of security, we recommend enabling host key signing. This is used in conjunction with client key signing to provide an additional integrity layer. When enabled, the SSH agent will verify the target host is valid and trusted before attempting to SSH. This will reduce the probability of a user accidentally SSHing into an unmanaged or malicious machine.
Signing Key Configuration
-
Mount the secrets engine. For the most security, mount at a different path from the client signer.
$ vault secrets enable -path=ssh-host-signer ssh Successfully mounted 'ssh' at 'ssh-host-signer'!
-
Configure Vault with a CA for signing host keys using the
/config/ca
endpoint. If you do not have an internal CA, Vault can generate a keypair for you.$ vault write ssh-host-signer/config/ca generate_signing_key=true Key Value --- ----- public_key ssh-rsa AAAAB3NzaC1yc2EA...
If you already have a keypair, specify the public and private key parts as part of the payload:
$ vault write ssh-host-signer/config/ca \ private_key="..." \ public_key="..."
Regardless of whether it is generated or uploaded, the host signer public key is accessible via the API at the
/public_key
endpoint. -
Extend host key certificate TTLs.
$ vault secrets tune -max-lease-ttl=87600h ssh-host-signer
-
Create a role for signing host keys. Be sure to fill in the list of allowed domains, set
allow_bare_domains
, or both.$ vault write ssh-host-signer/roles/hostrole \ key_type=ca \ ttl=87600h \ allow_host_certificates=true \ allowed_domains="localdomain,example.com" \ allow_subdomains=true
-
Sign the host's SSH public key.
$ vault write ssh-host-signer/sign/hostrole \ cert_type=host \ public_key=@/etc/ssh/ssh_host_rsa_key.pub Key Value --- ----- serial_number 3746eb17371540d9 signed_key ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1y...
-
Set the resulting signed certificate as
HostCertificate
in the SSH configuration on the host machine.$ vault write -field=signed_key ssh-host-signer/sign/hostrole \ cert_type=host \ public_key=@/etc/ssh/ssh_host_rsa_key.pub > /etc/ssh/ssh_host_rsa_key-cert.pub
Set permissions on the certificate to be
0640
:$ chmod 0640 /etc/ssh/ssh_host_rsa_key-cert.pub
Add host key and host certificate to the SSH configuration file.
# /etc/ssh/sshd_config # ... # For client keys TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem # For host keys HostKey /etc/ssh/ssh_host_rsa_key HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
Restart the SSH service to pick up the changes.
Client-Side Host Verification
-
Retrieve the host signing CA public key to validate the host signature of target machines.
$ curl http://127.0.0.1:8200/v1/ssh-host-signer/public_key
$ vault read -field=public_key ssh-host-signer/config/ca
-
Add the resulting public key to the
known_hosts
file with authority.# ~/.ssh/known_hosts @cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAA...
-
SSH into target machines as usual.
Troubleshooting
When initially configuring this type of key signing, enable VERBOSE
SSH
logging to help annotate any errors in the log.
# /etc/ssh/sshd_config
# ...
LogLevel VERBOSE
Restart SSH after making these changes.
By default, SSH logs to /var/log/auth.log
, but so do many other things. To
extract just the SSH logs, use the following:
$ tail -f /var/log/auth.log | grep --line-buffered "sshd"
If you are unable to make a connection to the host, the SSH server logs may provide guidance and insights.
Name is not a listed principal
If the auth.log
displays the following messages:
# /var/log/auth.log
key_cert_check_authority: invalid certificate
Certificate invalid: name is not a listed principal
The certificate does not permit the username as a listed principal for
authenticating to the system. This is most likely due to an OpenSSH bug (see
known issues for more information). This bug does not respect
the allowed_users
option value of "*". Here are ways to work around this
issue:
-
Set
default_user
in the role. If you are always authenticating as the same user, set thedefault_user
in the role to the username you are SSHing into the target machine:$ vault write ssh/roles/my-role -<<"EOH" { "default_user": "YOUR_USER", // ... } EOH
-
Set
valid_principals
during signing. In situations where multiple users may be authenticating to SSH via Vault, set the list of valid principles during key signing to include the current username:$ vault write ssh-client-signer/sign/my-role -<<"EOH" { "valid_principals": "my-user" // ... } EOH
No Prompt After Login
If you do not see a prompt after authenticating to the host machine, the signed
certificate may not have the permit-pty
extension. There are two ways to add
this extension to the signed certificate.
-
As part of the role creation
$ vault write ssh-client-signer/roles/my-role -<<"EOH" { "default_extensions": [ { "permit-pty": "" } ] // ... } EOH
-
As part of the signing operation itself:
$ vault write ssh-client-signer/sign/my-role -<<"EOH" { "extension": { "permit-pty": "" } // ... } EOH
No Port Forwarding
If port forwarding from the guest to the host is not working, the signed
certificate may not have the permit-port-forwarding
extension. Add the
extension as part of the role creation or signing process to enable port
forwarding. See no prompt after login for examples.
{
"default_extensions": [
{
"permit-port-forwarding": ""
}
]
}
No X11 Forwarding
If X11 forwarding from the guest to the host is not working, the signed
certificate may not have the permit-X11-forwarding
extension. Add the
extension as part of the role creation or signing process to enable X11
forwarding. See no prompt after login for examples.
{
"default_extensions": [
{
"permit-X11-forwarding": ""
}
]
}
No Agent Forwarding
If agent forwarding from the guest to the host is not working, the signed
certificate may not have the permit-agent-forwarding
extension. Add the
extension as part of the role creation or signing process to enable agent
forwarding. See no prompt after login for examples.
{
"default_extensions": [
{
"permit-agent-forwarding": ""
}
]
}
Known Issues
-
On SELinux-enforcing systems, you may need to adjust related types so that the SSH daemon is able to read it. For example, adjust the signed host certificate to be an
sshd_key_t
type. -
On some versions of SSH, you may get the following error:
no separate private key for certificate
This is a bug introduced in OpenSSH version 7.2 and fixed in 7.5. See OpenSSH bug 2617 for details.
API
The SSH secrets engine has a full HTTP API. Please see the SSH secrets engine API for more details.