sql >> Base de Datos >  >> RDS >> MariaDB

Aprovisionamiento de MySQL/MariaDB Vault Database Secrets Engine con Terraform

El objetivo de esta publicación es proporcionar credenciales de base de datos dinámicas/temporales sin tener que crearlas y administrarlas todas manualmente.

Solo voy a comenzar diciendo que esto es solo una prueba de concepto y que las mejores prácticas no se siguieron en absoluto. (principalmente de seguridad). Todos los procedimientos desde este punto son solo pruebas simples enfocadas en facilitar todas las tareas secundarias solo para ver que todo el proceso funciona.

Contenedores de prueba

Usaremos contenedores MariaDB y Vault, lanzados (rápidamente) como se especifica en las páginas oficiales de DockerHub de ambos proyectos.

  • Bóveda
docker run --rm \
    --name vault \
    --cap-add=IPC_LOCK \
    -e 'VAULT_LOCAL_CONFIG={"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h"}' \
    -p 8200:8200 \
    -d vault

Cuando Vault termina de iniciarse, podemos ver en los registros del contenedor lo siguiente:

Es posible que deba establecer la siguiente variable de entorno:

$ exportar VAULT_ADDR='http://0.0.0.0:8200

La clave de desbloqueo y el token raíz se muestran a continuación en caso de que desee
sellar/quitar el sello de Vault o volver a autenticarse.

Clave de apertura:kSUgoPDPyBrCGWc4s93CIlMUnDLZGcxdu4doYCkWSPs=
Ficha raíz:s.I6TnqhrgYh8uET91FUsNvIwV

¡El modo de desarrollo NO debe usarse en>instalaciones de producción!

Entonces, tenemos la dirección de nuestra bóveda y el token raíz.

  • MariaDB
docker run --rm \
    --name mariadb \
    -p 3306:3306 \
    -e MYSQL_ROOT_PASSWORD=mysecretpw \
    -d mariadb:latest

Y aquí tenemos nuestro usuario root y contraseña para MariaDB.

Debido a que el usuario raíz no debe usarse para nada, vamos a crear un usuario dedicado para las interacciones de la bóveda.

Inicie sesión en la base de datos usando mysql -h 127.0.0.1 -u root -p

y crea el usuario de la bóveda

grant CREATE USER, SELECT, INSERT, UPDATE ON *.* TO 'vault'@'%' identified by 'myvaultsecretpw' WITH GRANT OPTION;

Terraformar

Con todos los servicios ejecutándose y configurados, es hora de ocuparse de la parte de terraformación.

Una vez más, esto es solo un POC. Todas las contraseñas codificadas y débiles están destinadas a fines de prueba.

provider "vault" {
    address = "http://localhost:8200"
        #Token provided from vault container log
    token = "s.I6TnqhrgYh8uET91FUsNvIwV" 
}

resource "vault_auth_backend" "userpass" {
  type = "userpass"
}

# USERS
resource "vault_generic_endpoint" "user_userro" {
  depends_on           = [vault_auth_backend.userpass]
  path                 = "auth/userpass/users/userro"
  ignore_absent_fields = true

  data_json = <<EOT
{
  "policies": ["db-ro"],
  "password": "userro"
}
EOT
}

resource "vault_generic_endpoint" "user_userrw" {
  depends_on           = [vault_auth_backend.userpass]
  path                 = "auth/userpass/users/userrw"
  ignore_absent_fields = true

  data_json = <<EOT
{
  "policies": ["db-all", "db-ro"],
  "password": "userrw"
}
EOT
}

# POLICIES
# Read-Only access policy
resource "vault_policy" "dbro" {
  name   = "db-ro"
  policy = file("policies/dbro.hcl")
}

# All permissions access policy
resource "vault_policy" "dball" {
  name   = "db-all"
  policy = file("policies/dball.hcl")
}


# DB
resource "vault_mount" "mariadb" {
  path = "mariadb"
  type = "database"
}

resource "vault_database_secret_backend_connection" "mariadb_connection" {
  backend       = vault_mount.mariadb.path
  name          = "mariadb"
  allowed_roles = ["db-ro", "db-all"]
  verify_connection = true

  mysql{
    connection_url = "{{username}}:{{password}}@tcp(192.168.11.71:3306)/"
  }

# note that I have my database address hardcoded and I'm using my lan IP, since I'm running the mysql client directly from my host and vault/mariadb are running inside containers with their ports exposed.

  data = {
    username = "vault"
    password = "myvaultsecretpw"
  } 

}

resource "vault_database_secret_backend_role" "role" {
  backend             = vault_mount.mariadb.path
  name                = "db-ro"
  db_name             = vault_database_secret_backend_connection.mariadb_connection.name
  creation_statements = ["GRANT SELECT ON *.* TO '{{name}}'@'%' IDENTIFIED BY '{{password}}';"]
}

resource "vault_database_secret_backend_role" "role-all" {
  backend             = vault_mount.mariadb.path
  name                = "db-all"
  db_name             = vault_database_secret_backend_connection.mariadb_connection.name
  creation_statements = ["GRANT ALL ON *.* TO '{{name}}'@'%' IDENTIFIED BY '{{password}}';"]
}

Archivos de políticas utilizados en la lista de códigos anterior:

  • políticas/dball.hcl
path "mariadb/creds/db-all" {
  policy = "read"
  capabilities = ["list"]
}

  • políticas/dbro.hcl
path "mariadb/creds/db-ro" {
  policy = "read"
  capabilities = ["list"]
}

Después de esto, el proceso habitual:
terraform init
terraform apply

Y tenemos todo listo para algunas pruebas.

Prueba

Prueba del usuario de RO

Iniciar sesión en la bóveda

$ vault login -method userpass username=userro
Password (will be hidden): 
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
(...)

solicitar credenciales de base de datos

$ vault read mariadb/creds/db-ro
Key                Value
---                -----
lease_id           mariadb/creds/db-ro/uGldyp0BAa2GhUlFyrEwuIbs
lease_duration     168h
lease_renewable    true
password           8vykdcZNHp-I0pajVtoN
username           v_userpass-d_db-ro_75wxnJaL69FW4

Iniciar sesión en la base de datos
(RECUERDA:¡¡¡El siguiente cmd es realmente una MALA PRÁCTICA !!! )

$ mysql -h 127.0.0.1 -u v_userpass-d_db-ro_75wxnJaL69FW4 -p'8vykdcZNHp-I0pajVtoN'

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 101
Server version: 10.3.13-MariaDB-1:10.3.13+maria~bionic mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

... tratar de hacer cosas

MariaDB [(none)]> create database my_database;
ERROR 1044 (42000): Access denied for user 'v_userpass-d_db-ro_75wxnJaL69FW4'@'%' to database 'my_database'

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_db              |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.00 sec)

MariaDB [(none)]> use my_db;

Database changed
MariaDB [my_db]> show tables;
+-----------------+
| Tables_in_my_db |
+-----------------+
| my_table        |
+-----------------+
1 row in set (0.00 sec)

MariaDB [my_db]> select * from my_table;
Empty set (0.00 sec)

MariaDB [my_db]> 

Prueba del usuario RW

Iniciar sesión en la bóveda

$ vault login -method userpass username=userrw
Password (will be hidden): 
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
(...)

solicitar credenciales de base de datos

$ vault read mariadb/creds/db-all
Key                Value
---                -----
lease_id           mariadb/creds/db-all/GHRHvpuqa2ITP9tX54YHEePl
lease_duration     168h
lease_renewable    true
password           L--8mPBoprFZcaItINKI
username           v_userpass-j_db-all_DMwlhs9nGxA8

Iniciar sesión en la base de datos
(RECUERDA OTRA VEZ:¡¡¡El siguiente cmd es una MALA PRÁCTICA !!! )

$ mysql -h 127.0.0.1 -u v_userpass-j_db-all_DMwlhs9nGxA8 -p'L--8mPBoprFZcaItINKI'
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 109
Server version: 10.3.13-MariaDB-1:10.3.13+maria~bionic mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>  

... tratar de hacer cosas

MariaDB [(none)]> create database my_database;
Query OK, 1 row affected (0.01 sec)

MariaDB [(none)]> use my_db;
Database changed

MariaDB [my_db]> create table the_table (i integer);
Query OK, 0 rows affected (0.03 sec)

MariaDB [my_db]> show tables;
+-----------------+
| Tables_in_my_db |
+-----------------+
| my_table        |
| the_table       |
+-----------------+
2 rows in set (0.00 sec)

Y eso es. Ahora tenemos la base para nuestros usuarios dinámicos/temporales de MariaDB.