Secure second days operations with Boundary and Vault.pdf

attachmentgenie 30 views 39 slides Jun 11, 2024
Slide 1
Slide 1 of 39
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39

About This Presentation

We now live in the age of cloud native which also means that we now have an incredibly dynamic fleet of nodes to maintain. Instead of injecting a well known SSH key into our entire infrastructure this talk will show how we can utilise Boundary and Vault to build a zero trust system. This than allows...


Slide Content

Secure second day
operations with
Boundary and
Vault

Bram Vogelaar
@attachmentgenie

“I bet I know the most
powerful user in your
platform”

“I am 99.9% sure it is not
root”

“It probably is your own ssh key”

“I am also pretty sure it’s
as old as your platform”

~ ❯ whoami
Previously a Molecular Biologist
Then became a Dev, now an Ops

Amsterdam HUG organizer
HashiCorp Ambassador 2024
HashiCorp Core Contributor 2024

On today’s agenda

“Let's rotate the secrets …right now”

Connect GHA to Vault




CODE EDITOR
steps:
- name: Import Vault Secrets
id: vault_secrets
uses: hashicorp/vault-action@v3
with:
url: "https://nonofyourbusiness.hashicorp.cloud:8200"
namespace: "admin/engineering"
githubToken: ${{ secrets.CI_RUNNER_ACCESS_TOKEN }}
method: approle
roleId: ${{ secrets.CI_VAULT_ROLE_ID }}
secretId: ${{ secrets.CI_VAULT_SECRET_ID }}
secrets: |
shared/secrets/data/not_a_secret foo ;
- name: Print foo secret length
run: echo -n $FOO | wc -l

Create a Github application

Create a Github application

Connect your github application

Connect your github application




CODE EDITOR
data "github_repository" "atc" {
full_name = "attachmentgenie/atc"
}
resource "github_app_installation_repository" "atc" {
installation_id = "1234567"
repository = data,github_repository.atc.name
}

Link the Github application



CODE EDITOR
vault write sys/sync/github-apps/hashidays_gha_secrets \
app_id=<APP_ID> \
private_key=<PATH_TO_PRIVATE_KEY>

Create the sync location


CODE EDITOR
vault write sys/sync/destinations/gh/hashidays-gha-secrets \
installation_id=<INSTALLATION_ID> \
repository_owner=<GITHUB_USER> \
repository_name=<MY_REPO_NAME> \
app_name=<APP_NAME>

Create the secret and sync instructions



CODE EDITOR
vault secrets enable -path=hashidays-gha-secrets kv-v2
vault kv put -mount='hashidays-gha-secrets' my-secret foo='bar'
vault write sys/sync/destinations/gh/hashidays-gha-secrets/associations/set \
mount=hashidays-gha-secrets \
secret_name=my-secret

“O11y exposes a wealth of
information”

Securing Node Exporter



CODE EDITOR
tls_server_config:
cert_file: /etc/node_exporter/ssl/node.pki.vagrant.cert
key_file: /etc/node_exporter/ssl/node.pki.vagrant.key
client_auth_type: RequireAndVerifyClientCert
client_ca_file: /etc/node_exporter/ssl/ca.cert

Securing Node Exporter



CODE EDITOR
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "tls"
static_configs: - targets: [”node.pki.vagrant:9100"]
scheme: https
tls_config:
cert_file: /etc/prometheus/ssl/prometheus.pki.vagrant.cert
key_file: /etc/prometheus/ssl/prometheus.pki.vagrant.key
ca_file: /etc/prometheus/ssl/ca.cert

Vault Agent Config





CODE EDITOR
vault {
address = "http://prometheus.pki.vagrant:8200"
}
auto_auth {
method "approle" {
config = {
role_id_file_path = "/vagrant_data/tmp/role_id"
secret_id_file_path = "/vagrant_data/tmp/secret_id"
remove_secret_id_file_after_reading = false
}
}
}


* Wildly insecure config, for demo purpose only

Vault Agent Config Cont.






CODE EDITOR
template {
contents="{{ with secret \"pki_int/issue/pki-dot-vagrant\" \"ttl=3m\"
\"common_name=prometheus.pki.vagrant\" }}{{ .Data.certificate }}{{ end }}"
destination="/etc/prometheus/ssl/prometheus.pki.vagrant.cert"
command = "killall -HUP prometheus"
}

{{ .Data.issuing_ca }} => "/etc/prometheus/ssl/ca.cert”
{{.Data.private_key }} => "/etc/prometheus/ssl/prometheus.pki.vagrant.key"

Build In certificate expiration

“Ben the BI guy, needs
database access for a bit”

Single Use Database Credentials






CODE EDITOR
vault secrets enable database

vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@$POSTGRES_URL/postgres" \
allowed_roles=readonly \
username="root" \
password="nolongercommonknowledge"

Create “create user” instructions






CODE EDITOR
tee readonly.sql <<EOF
CREATE ROLE "{{name}}" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'
INHERIT;
GRANT ro TO "{{name}}";
EOF

vault write database/roles/readonly \
db_name=postgresql \
[email protected] \
default_ttl=1h \
max_ttl=24h

Create “create user” instructions






CODE EDITOR
vault read database/creds/readonly

Key Value
--- -----
lease_id database/creds/readonly/fyF5xDomnKeCHNZNQgStwBKD
lease_duration 1h
lease_renewable true
password A1a-ckirtymYaXACpIHn
username v-token-readonly-6iRIcGv8tLpu816oblPY-1556567086

“Can you just put on the
sftp server anyway?”

Conway’s Law OU group

Boundary as Source of truth

Model your organization
CODE EDITOR
resource "boundary_scope" "org" {
name = "hashdays inc"
description = "top level"
scope_id = "global"
auto_create_admin_role = true
auto_create_default_role = true
}

resource "boundary_scope" "bi_team" {
name = "platform team"
description = "project for the BI team"
scope_id = boundary_scope.org.id
auto_create_admin_role = true
}

Infrastructure Mesh as Code


CODE EDITOR
resource "boundary_target" "bi_pgsql" {
name = "bi_pgsql"
description = "BI Postgresql"
address = aws_instance.hashidays.public_ip:5432
type = "tcp"
default_port = "5432"
scope_id = boundary_scope.bi_team.id
}


boundary connect postgres -target-id ttcp_eTcZMueUYv -username admin -dbname postgres

“Can you update that
webserver, you know the
one i am talking about”

CODE EDITOR
resource "boundary_host_catalog_static" "webservers" {
name = "webservers"
scope_id = boundary_scope.project.id
}

resource "boundary_host_static" "webserver" {
name = "webserver"
address = aws_instance.hashidays.public_ip
host_catalog_id = boundary_host_catalog_static.webservers.id
}
Model your fleet

CODE EDITOR
resource "boundary_credential_store_vault" "platform" {
name = "platform”
address = var.vault_url
token = vault_token.hashidays.client_token
scope_id = boundary_scope.project_team.id
}

resource "boundary_credential_library_vault" "platform" {
name = "platform"
credential_store_id = boundary_credential_store_vault.platform.id
path = "ssh/connect/hashidays"
http_method = "GET"
credential_type = "username_password"
}
Define what credentials to use

CODE EDITOR
resource "boundary_target" "webserver" {
name = "webserver"
description = "public website"
type = "ssh"
default_port = "22"
scope_id = boundary_scope.platform_team.id
host_source_ids = [
boundary_host_set.webserver.id
]
injected_application_credential_source_ids = [
boundary_credential_library_vault.platform.id
]
}
Credential Injection from vault

Boundary as ansible transport

CODE EDITOR
hashidays_inventory:
hosts:
webserver:
ansible_host: 18.196.188.109
ansible_ssh_user: ubuntu
ansible_ssh_private_key_file: /home/attachmentgenie/.ssh/id_rsa_aws

hashidays_inventory:
hosts:
webserver:
ansible_host: 127.0.0.1
ansible_port: 42921

Inventory + Acls + API =
Break glass as Code
https://www.hashicorp.com/blog/event-driven-access-controls-with-hashicorp-boundary-and-vault

Thank you!




[email protected]
@attachmentgenie
https://www.slideshare.net/attachmentgenie