Skip to content

Instantly share code, notes, and snippets.

@vincentramirez
Last active May 8, 2021 18:16
Show Gist options
  • Save vincentramirez/ac4314c516891ff03554c51cafd69205 to your computer and use it in GitHub Desktop.
Save vincentramirez/ac4314c516891ff03554c51cafd69205 to your computer and use it in GitHub Desktop.
HashiCorp Vault database engine demo

This is a setp-by-step guide to help demonstrate the use of the HashiCorp Vault database secrets engine with LDAP authentication, as well as a demonstration of Control Groups. The guide is written for Mac users to perform this demo locally.

Pre-reqs:

A fairly current version of Mac OS (v10.13.6 at time of this guide)
Docker (v18.09.2 at time of this guide)
Git
Vault binary (v1.1.1 at the time of this guide)
Optional Vault enterprise binary to demonstrate Control Groups
download the open source binary https://www.vaultproject.io/downloads.html
or contact HashiCorp to get access to an enterprise trial https://www.hashicorp.com/go/vault-enterprise

Run a local instance of Vault

open a terminal window and cd into the directory that has your unzipped Vault binary

./vault server -log-level=trace -dev -dev-root-token-id=root -dev-listen-address=127.0.0.1:8200 -dev-ha -dev-transactional

Open a new terminal window

export VAULT_ADDR=http://127.0.0.1:8200
vault login root

Verify the UI, open a browser and go to 127.0.0.1:8200
Method: Token
Token: root

Configure MySQL container https://hub.docker.com/_/mysql

open a new terminal window and Launch MySQL docker container

docker run -p 3306:3306 --name mysqlsrv01 -e MYSQL_ROOT_PASSWORD=root -d mysql:latest 

Connect to the docker container

docker exec -it mysqlsrv01 /bin/bash

Log into MySQL while in the container

mysql -u root -p
Enter Password: root

Test out MySQL

mysql> show databases;
mysql> SELECT user, host FROM mysql.user;

Now create a privileged user for Vault to use for dynamic secrets engine

mysql> CREATE USER 'vaultsvc'@'%' IDENTIFIED BY 'password1';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'vaultsvc'@'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
mysql> SHOW GRANTS FOR vaultsvc;

keep this terminal open

Configure an LDAP Container based on this -> https://github.com/grove-mountain/docker-ldap-server

Run the container and test it steps only *don't need to customize it or use the apache directory studio
create a dir on your system

mkdir ldap_demo
cd ldap_demo
git clone https://github.com/grove-mountain/docker-ldap-server.git
cd docker-ldap-server
./launch_ldap.sh
export IP_ADDRESS=$(ipconfig getifaddr en0)
export LDAP_READONLY_USER_PASSWORD=devsecopsFTW

Test the ldap container with these commands

ldapsearch -LLL -x -H ldap://${IP_ADDRESS} -b dc=ourcorp,dc=com \
-D "cn=read-only,dc=ourcorp,dc=com" -w ${LDAP_READONLY_USER_PASSWORD} \
'(memberOf=cn=database,ou=um_group,dc=ourcorp,dc=com)' dn

expected output

dn: cn=chun,ou=people,dc=ourcorp,dc=com
ldapsearch -LLL -x -H ldap://${IP_ADDRESS} -b dc=ourcorp,dc=com \
-D "cn=read-only,dc=ourcorp,dc=com" -w ${LDAP_READONLY_USER_PASSWORD} \
'(memberOf=cn=hr,ou=um_group,dc=ourcorp,dc=com)' dn

expected output

dn: cn=frank,ou=people,dc=ourcorp,dc=com

Continue configuring Vault

Open a new terminal window

vault login root
vault secrets enable database
vault write database/config/mysqlsrv01 \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(<yourMacIp>:3306)/" \
allowed_roles="mysqlsrv01-admin-role,mysqlsrv01-readonly-role" \
username="vaultsvc" \
password="password1"
vault write database/roles/mysqlsrv01-admin-role \
db_name=mysqlsrv01 \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT ALL PRIVILEGES ON *.* TO '{{name}}'@'%';" \
default_ttl="5m" \
max_ttl="10m"
vault write database/roles/mysqlsrv01-readonly-role \
db_name=mysqlsrv01 \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" \
default_ttl="1m" \
max_ttl="5m"

Test dynamic DB creds

vault read database/creds/mysqlsrv01-admin-role
vault read database/creds/mysqlsrv01-readonly-role

return to the terminal session connected to the MySQL container

mysql> SELECT user, host FROM mysql.user;

You can now see the dynamically created users, the admin-role user will last for 5mins, the readonly-role will last for 1min

Rotate the db svc account creds (only Vault knows the password now)

in your terminal window connect to the MySQL container log out of the MySQL root account

mysql> exit
Bye

log into MySQL with the vaultsvc account and known password

mysql -u vaultsvc -p
Enter password: password1

go to your terminal that is connected to Vault
use this command to have Vault rotate the known passowrd for the MySQL vaultsvc account

vault write -force database/rotate-root/mysqlsrv01

verify that the secrets engine still works

vault read database/creds/mysqlsrv01-admin-role
vault read database/creds/mysqlsrv01-readonly-role

now go back to the terminal session connected to the MySQL container

mysql> exit
Bye

attempt to login into MySQL with the vaultsvc account again

mysql -u vaultsvc -p
Enter password: password1

This should fail since Vault has rotated the vaultsvc account password in MySQL

Create policies in Vault to use with LDAP mapping

go back to the Vault UI, or start a new UI session at 127.0.0.1:8200 method token, token: root
navigate to > Policies > Create ACL Policy
Name: mysqlsrv01-admin
Policy:

path "database/creds/mysqlsrv01-admin-role" {
  capabilities = ["read"]
}

Create Policy
ACL Policies > Create ACL Policy
Name: mysqlsrv01-readonly
Policy:

path "database/creds/mysqlsrv01-readonly-role" {
  capabilities = ["read"]
}

Create Policy

Configure LDAP Auth method

in your terminal window connected to Vault

vault auth enable ldap

vault write auth/ldap/config url="ldap://localhost" binddn="cn=read-only,dc=ourcorp,dc=com" bindpass="devsecopsFTW" userdn="ou=people,dc=ourcorp,dc=com" userattr="cn" groupdn="dc=ourcorp,dc=com" groupattr="cn"

vault write auth/ldap/groups/database policies=mysqlsrv01-admin

vault write auth/ldap/groups/hr policies=mysqlsrv01-readonly

Test Ldap auth and DB access based on policies

log into Vault as LDAP user chun and generate dynamic db creds for admin access

vault login -method=ldap username=chun
password: thispasswordsucks
vault read database/creds/mysqlsrv01-admin-role

go back to the terminal session connected to the MySQLcontainer
log into MySQL with the dynamic admin creds generated from Vault

mysql> exit
Bye
mysql -u <dynamicUserNameFromVault> -p
Enter password: <dynamicPasswordFromVault>

verify this user has admin privliges in MySQL
create a database and some data

mysql> SHOW DATABASES;
mysql> CREATE DATABASE demodb;
mysql> USE demodb;
mysql> CREATE TABLE customer_info (customer_id VARCHAR(10),first_name VARCHAR(100),last_name VARCHAR(40),address_street VARCHAR(200));
mysql> INSERT INTO customer_info (customer_id,first_name,last_name,address_street)VALUES("123-44-555","John","Doe","1 Maple ave. Chicago IL");
mysql> SHOW TABLES;
mysql> SELECT * FROM customer_info;

This demonstrates that the user Chun is able to auth into Vault using LDAP
and is able to generate MySQL admin creds
now log into Vault as LDAP user Frank

vault login -method=ldap username=frank
password: thispasswordsucks

try to generate dynamic admin creds while logged in as Frank

vault read database/creds/mysqlsrv01-admin-role

this will should fail with permission denied
Frank is part of an LDAP group that is only allowed to generate read only dynamic db creds

vault read database/creds/mysqlsrv01-readonly-role

go back to the terminal session connected to the MySQLcontainer
log into MySQL with the dynamic read only creds generated from Vault

mysql> exit
Bye
mysql -u <dynamicUserNameFromVault> -p
Enter password: <dynamicPasswordFromVault>
mysql> SHOW DATABASES;
mysql> USE demodb;
mysql> SHOW TABLES;
mysql> SELECT * FROM customer_info;
mysql> DROP DATABASE demodb;

the DROP DATABASE command should fail since Frank only has read only privileges in MySQL

This next section requires the use of the Vault enterprise binary and assumes you have been using it the entire time

Control Groups is a Vault Enterprise feature

Complete this entire guide -> https://learn.hashicorp.com/vault/identity-access-management/iam-control-groups

Now that you are familiar with Control Groups lets test it on the database secrets engine

In the Vault UI, 127.0.0.1:8200 method token, token: root
navigate to > Policies > mysqlsrv01-admin > edit

path "database/creds/mysqlsrv01-admin-role" {
  capabilities = ["read"]
 
  control_group = {
    factor "authorizer" {
        identity {
            group_names = [ "acct_manager" ]
            approvals = 1
        }
    }
  }
}

save

log back into Vault as LDAP user Chun, and try to generate dynamic admin db creds

vault login -method=ldap username=chun
password: thispasswordsucks
vault read database/creds/mysqlsrv01-admin-role

you should now see that Control Groups have been enabled on the database secrets engine for mysqlsrv01-admin-role
open another terminal and log in as userpass user Ellen to approve Chun's request for admin db creds

vault login -method=userpass username="ellen" password="training"
vault write sys/control-group/authorize accessor=<theWrappingAccessorFromChun>

go back to the terminal with the Chun Vault login

vault unwrap <wrappingToken>

you should now have access to the dynamic admin db creds

Clean up

To stop Vault, ctrl + c in the terminal window running Vault in dev mode
or

sudo pkill -9 vault 

To stop the docker containers

docker kill openldap mysqlsrv01 

If you wish to delete the docker containers permenately use

docker system prune 
y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment