Динамическая генерация секретов в OpenBao

Движок секретов database в OpenBao позволяет динамически генерировать пары логин/пароль для различных типов баз данных. В данном примере показана генерация учетных данных для БД PostgreSQL (ADB или ADPG) и подключение к БД с этими данными через Spark.

Подготовка

Настройка

ADB

  1. Создайте пользователя для OpenBao с правами на передачу привилегий:

    CREATE ROLE openbao
    WITH  CREATEEXTTABLE(protocol='gpfdist',type='readable')
          CREATEEXTTABLE(protocol='gpfdist',type='writable')
          LOGIN
          PASSWORD '123'
    WITH GRANT OPTION;
  2. Дайте этому пользователю права на создание ролей:

    ALTER ROLE openbao WITH CREATEROLE;
  3. Измените файл-параметр pg_hba.conf в настройках сервиса ADB в ADCM:

    host    all  openbao       0.0.0.0/0     md5
    host    all  tmp_user      0.0.0.0/0     md5

    где tmp_user — имя пользователя, для которого OpenBao будет генерировать пароль.

OpenBao

В данном примере настройка происходит с использованием интерфейса командной строки. Команды следует запускать на хосте, где установлен OpenBao.

  1. Пройдите аутентификацию в OpenBao:

    $ bao login

    Если не указывать метод аутентификации, то потребуется ввести токен доступа. После ввода корректного токена вы увидите следующее сообщение:

    Success! You are now authenticated. The token information displayed below is
    already stored in the token helper. You do NOT need to run "bao login" again.
    Future OpenBao requests will automatically use this token.
    
    Key                    Value
    ---                    -----
    token                  <your_token>
    token_accessor         o5mN3ud1fz1Zmb4EIamcVhve
    token_duration         1h
    token_renewable        true
    token_policies         ["default"]
    identity_policies      []
    policies               ["default"]
    token_meta_username    test_user
  2. Активируйте движок секретов database:

    $ bao secrets enable database
  3. Настройте плагин PostgreSQL с данными подключения (username и password должны совпадать с данными пользователя, созданного в ADB):

    $ bao write database/config/adb \
        plugin_name="postgresql-database-plugin" \
        allowed_roles="cred-manager" \
        connection_url="postgresql://{{username}}:{{password}}@<adb-master-host>:5432/adb?sslmode=disable" \
        username="openbao" \
        password="123" \
        usename_template="tmp_user" \
        password_authentication="scram-sha-256"

    Параметр usename_template не является обязательным, но он позволяет контролировать вид генерируемых учетных данных. В данном примере генерируемое имя статично. Чтобы узнать обо всех возможностях шаблонизации генерируемого имени пользователя, см. Username templating.

  4. Настройте роль для сопоставления имени в OpenBao с SQL-выражением, которое будет исполняться при генерации учетных данных для БД. Название роли должно совпадать со значением параметра allowed-roles в команде выше:

    $ bao write database/roles/cred-manager \
        db_name="adb" \
        creation_statements="CREATE ROLE "{{name}}" WITH CREATEEXTTABLE(protocol='gpfdist',type='readable') CREATEEXTTABLE(protocol='gpfdist',type='writable') LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';,GRANT USAGE ON SCHEMA public TO "{{name}}";,GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA public TO "{{name}}";" \
        default_ttl="1h" \
        max_ttl="24h"
  5. Сгенерируйте временные учетные данные, отправив запрос на эндпойнт /creds:

    $ bao read database/creds/cred-manager

    При успешном выполнении вы получите следующий результат:

    Key                Value
    ---                -----
    Key                Value
    ---                -----
    lease_id           database/creds/cred-manager/93reYpVubYhVjd6xpek7edTS
    lease_duration     1h
    lease_renewable    true
    password           cBOb-ugyiUzuPbmySax4
    username           tmp_user

Проверка

Подход похож на описанный в статье Примеры использования ADB Spark 3 Connector.

  1. Откройте spark3-shell на хосте, где установлен Spark 3:

    $ sudo -u hdfs spark3-shell
  2. Определите функцию для получения учетных данных от OpenBao (код ниже приведен для демонстрации работы, при необходимости функцию можно изменить):

    def getOpenBaoCredentials(openbaoUrl: String, token: String, path: String): (String, String) = {
      val connection = new java.net.URL(s"$openbaoUrl/v1/$path").openConnection
      connection.setRequestProperty("X-Vault-Token", token)
    
      val response = scala.io.Source.fromInputStream(connection.getInputStream).mkString
      connection.getInputStream.close()
    
      // Simple manual parsing - assumes response format: {"data":{"username":"xxx","password":"yyy"}}
      val dataPart = response.substring(response.indexOf("\"data\":{") + 7)
      val username = dataPart.split("\"username\":\"")(1).split("\"")(0)
      val password = dataPart.split("\"password\":\"")(1).split("\"")(0)
    
      (username, password)
    }
  3. Получите учетные данные от OpenBao:

    val (username, password) = getOpenBaoCredentials(
      "http://<openbao-host>:8200",
      "<token>",
      "database/creds/cred-manager"
    )
  4. Укажите настройки коннектора для чтения данных из предварительно созданной и заполненной таблицы ADB author:

    val options = Map(
       "spark.adb.url" -> "jdbc:postgresql://<adb-master-host>:5432/adb",
       "spark.adb.user" -> username,
       "spark.adb.password" -> password,
       "spark.adb.dbschema" -> "public",
       "spark.adb.dbtable" -> "author"
       )
  5. Создайте DataFrame:

    val adb_author  = spark.read.format("adb").options(options).load()
  6. Проверьте содержимое DataFrame:

    adb_author.show()

    Результат:

    +---+-----------------+
    | id|             name|
    +---+-----------------+
    |  4|    J.D. Salinger|
    |  8|       Alan Moore|
    |  5|    George Orwell|
    | 10| Ernest Hemingway|
    |  2|   J.R.R. Tolkien|
    |  1|   Virginia Woolf|
    |  7|Margaret Mitchell|
    |  6|   John Steinbeck|
    |  3|       Harper Lee|
    |  9|     Jack Kerouac|
    +---+-----------------+
Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней