-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ssh): add signed ssh certificates lab
- Loading branch information
Showing
8 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# SSH secrets engine | ||
|
||
![img](assets/shh_sign.png) | ||
> https://www.hashicorp.com/blog/managing-ssh-access-at-scale-with-hashicorp-vault | ||
|
||
The idea of the ssh secret engine is to supplement the classic ssh public key authentication with a signing workflow. | ||
|
||
This means that public keys are no longer entered in the authorized keys files on individual hosts. Instead, all hosts trust the vault ssh ca and therefore keys signed by it. The contexts in which the signed key are valid is specified in the signature. | ||
|
||
To log on to a server, not only the private key but also the corresponding public key signed by the vault ca must be provided. | ||
|
||
The numbers in the diagram represent the following steps: | ||
|
||
- User creates a personal SSH key pair. | ||
- User authenticates to Vault with their Identity Provider (IDP) credentials. | ||
- Once authenticated, the user sends their SSH public key to Vault for signing. | ||
- Vault signs the SSH key and return the SSH certificate to the user. | ||
- User initiates SSH connection using the SSH certificate. | ||
- Host verifies the client SSH certificate is signed by the trusted SSH CA and allows connection. | ||
|
||
[HashiCorp Blog](https://www.hashicorp.com/blog/managing-ssh-access-at-scale-with-hashicorp-vault) | ||
|
||
|
||
## Requirements | ||
You can enable this lab by setting: | ||
|
||
```yaml | ||
# terraform.tfvars | ||
ssh = { | ||
enabled = true | ||
} | ||
``` | ||
|
||
You then can bootstrap the cluster using `make bootstrap` | ||
|
||
## Overview | ||
The following resources will be created: | ||
|
||
1. A Ubuntu Container will be deployed | ||
2. The ssh secret engine will be enabled | ||
3. A ssh signing ca will be created | ||
4. A ssh secret backend role that will allow you to login as the ubuntu user | ||
|
||
## Walkthrough | ||
|
||
The SSH signing ca has been configured under the `ssh-client-signer` path. | ||
|
||
```bash | ||
$ vault secrets list | ||
Path Type Accessor Description | ||
---- ---- -------- ----------- | ||
ssh-client-signer/ ssh ssh_002866eb n/a | ||
|
||
$ vault read ssh-client-signer/config/ca | ||
Key Value | ||
--- ----- | ||
public_key ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDjcpfjEV7fqCj6I14a6oGrfy6M9Fgi5ZQj7brbocNXG4w4GkZkrO5g93fec+5vcn6eoJYG4n== | ||
``` | ||
|
||
A ssh signer role has been created. | ||
|
||
```bash | ||
$vault read ssh-client-signer/roles/ubuntu | ||
Key Value | ||
--- ----- | ||
algorithm_signer default | ||
allow_bare_domains false | ||
allow_host_certificates false | ||
allow_subdomains false | ||
allow_user_certificates true | ||
allow_user_key_ids false | ||
allowed_critical_options n/a | ||
allowed_domains n/a | ||
allowed_domains_template false | ||
allowed_extensions n/a | ||
allowed_user_key_lengths map[] | ||
allowed_users ubuntu | ||
allowed_users_template false | ||
default_critical_options map[] | ||
default_extensions map[permit-pty:] | ||
default_extensions_template false | ||
default_user ubuntu | ||
default_user_template false | ||
key_id_format n/a | ||
key_type ca | ||
max_ttl 0s | ||
not_before_duration 30s | ||
ttl | ||
``` | ||
|
||
To log in to the ubuntu container you need to sign you public key. | ||
|
||
```bash | ||
$ vault write -field=signed_key ssh-client-signer/sign/ubuntu public_key=@$HOME/.ssh/id_rsa.pub >| signed-cert.pub | ||
``` | ||
|
||
Query the ip of the ubuntu container and use the signed public key and your private key to connect. | ||
|
||
```bash | ||
export UBUNTU_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ubuntu | ||
ssh -i signed-cert.pub -i ~/.ssh/id_rsa ubuntu@$UBUNTU_IP | ||
``` | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,3 +43,8 @@ kubernetes = { | |
# enable vault agent injector | ||
vault_agent_injector = true | ||
} | ||
|
||
|
||
ssh = { | ||
enabled = false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#/usr/bin/sh | ||
|
||
apt-get update | ||
apt install -y openssh-server curl | ||
|
||
mkdir /var/run/sshd | ||
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config | ||
curl -k -o /etc/ssh/trusted-user-ca-keys.pem https://haproxy/v1/ssh-client-signer/public_key | ||
echo "TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem" >> /etc/ssh/sshd_config | ||
|
||
useradd -m ubuntu -s /bin/bash | ||
|
||
|
||
/usr/sbin/sshd -D |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
|
||
data "docker_network" "vault" { | ||
name = "vault" | ||
} | ||
|
||
resource "docker_container" "ubuntu" { | ||
name = "ubuntu" | ||
image = "ubuntu:latest" | ||
|
||
command = ["/usr/bin/sh", "/files/init.sh"] | ||
|
||
volumes { | ||
host_path = abspath("${path.root}/vault-tls/output") | ||
container_path = "/opt/tls/" | ||
read_only = true | ||
} | ||
|
||
volumes { | ||
host_path = abspath("${path.root}/vault-ssh/files") | ||
container_path = "/files" | ||
read_only = true | ||
} | ||
|
||
networks_advanced { | ||
name = data.docker_network.vault.name | ||
} | ||
|
||
lifecycle { | ||
ignore_changes = all | ||
} | ||
|
||
depends_on = [vault_ssh_secret_backend_ca.this] | ||
} | ||
|
||
resource "vault_mount" "ssh" { | ||
type = "ssh" | ||
path = "ssh-client-signer" | ||
} | ||
|
||
resource "vault_ssh_secret_backend_ca" "this" { | ||
backend = vault_mount.ssh.path | ||
generate_signing_key = true | ||
} | ||
|
||
resource "vault_ssh_secret_backend_role" "ubuntu" { | ||
name = "ubuntu" | ||
backend = vault_mount.ssh.path | ||
key_type = "ca" | ||
allow_user_certificates = true | ||
allowed_users = "ubuntu" | ||
default_user = "ubuntu" | ||
default_extensions = { | ||
"permit-pty" : "" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
terraform { | ||
required_version = ">= 1.6.0" | ||
|
||
required_providers { | ||
vault = { | ||
source = "hashicorp/vault" | ||
version = "3.20.1" | ||
} | ||
docker = { | ||
source = "kreuzwerker/docker" | ||
version = "3.0.2" | ||
} | ||
} | ||
} | ||
|