Статьи

Управление секретами вашей базы данных с хранилищем

В моем предыдущем посте об управлении секретами с помощью Vault я познакомил вас с Vault и с тем, как хранить произвольные секреты, используя общий секретный бэкэнд. Vault может управлять не только секретными данными, такими как ключи API, пароли и другие конфиденциальные строковые данные. Сегодня мы рассмотрим интеграцию Vault с базами данных, сервисами и сертификатами.

Учетные данные базы данных имеют тенденцию быть статичными

Когда дело доходит до баз данных, регулярный рабочий процесс получения учетных данных, подающих заявку на базу данных, требует от какого-либо оператора или инструмента самообслуживания предоставить вам учетные данные, чтобы ваше приложение могло войти в базу данных. На этом этапе учетные данные считаются статическими. Учетные данные обычно меняются в случае переноса базы данных или в случае нарушения безопасности.

В Spring Cloud Vault вы можете хранить имя пользователя и пароль в Vault вместо конфигурации вашего приложения. Spring Config Server также является хорошим выбором; это позволяет хранить зашифрованные секреты в вашем хранилище конфигураций. Ваши учетные данные защищены.

Есть одно предупреждение: долгоживущие учетные данные являются хорошей целью для утечки. Утечка учетных данных может дать доступ к непреднамеренной стороне. Несколько баз данных реализуют ограничения на исходные хосты. В некоторых случаях пользователь базы данных может быть ограничен группой хостов. Это ограничение препятствует доступу с других хостов. Тем не менее, каждый пользователь и процесс, имеющий доступ к разрешенному компьютеру, может использовать утечку учетных данных. Но как вы обнаружили эту утечку? Вы можете обнаружить утечку, если ваши данные были переданы общественности или Интернету, но это не всегда так. В других случаях непреднамеренная сторона может прочитать или изменить ваши данные, и она вполне уверена, что утечка остается незамеченной в течение достаточно долгого времени.

Давайте сделаем учетные данные недолгим.

Хранилище и базы данных

Vault поставляется с различными интеграциями для разных систем. Некоторые из них интегрируются с PostgreSQL и MySQL в качестве секретного бэкэнда. Секретный бэкэнд может предоставить секреты. В этом случае секретный бэкэнд не означает, что секретные данные хранятся в PosgreSQL / MySQL. Это означает, что Vault может создавать (и отзывать) пользователей для баз данных по требованию.

Чтобы сгенерировать учетные данные базы данных, вам нужно сначала установить роль. Роли управляют контекстом разрешений для генерации учетных данных базы данных. Роль определяет разрешения, связанные с учетными данными. Эта концепция хорошо отображается, если вы запускаете разные приложения, и для каждого приложения требуются разные разрешения базы данных.
Роль также определяет максимальное время аренды для полученных учетных данных. Срок аренды — в Vault-говорить, срок действия учетных данных действительны. Vault отзывает учетные данные из системы базы данных после истечения срока их действия. Некоторые базы данных, такие как PostgreSQL, имеют встроенную поддержку истечения срока действия пароля с помощью этого CREATE ROLE … VALID UNTIL …предложения.

Первые шаги с Vault и MySQL

Теперь, как начать работу с Vault и MySQL?

Вам нужен инициализированный и открытый сервер Vault и работающий сервер MySQL. Смотрите предыдущий пост, как настроить Vault.

Затем вы можете настроить серверную часть MySQL, указав детали подключения и объявление роли:

Сначала установите mysqlсекретный бэкэнд с

$ vault mount mysql
Successfully mounted 'mysql' at 'mysql'!

Каждое монтирование соответствует одному серверу MySQL. Если вы хотите сгенерировать учетные данные для нескольких серверов, вам нужно монтировать бэкэнд несколько раз, используя разные пути.

После того, как серверная часть смонтирована, вам необходимо предоставить данные управляющего соединения, которые состоят из комбинации имени пользователя и пароля, а также хоста и порта. Управляющее соединение используется для создания и отзыва пользователей.

$ vault write mysql/config/connection \
connection_url="root:[email protected](127.0.0.1:3306)/"
Success! Data written to: mysql/config/connection

Роль содержит сценарии для создания пользователя и авторизации. Вы можете включить несколько команд, если вы хотите это сделать. Vault будет выполнять эти команды для каждого поколения учетных данных:

$ vault write mysql/roles/readonly \
sql="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';"
Success! Data written to: mysql/roles/readonly

Vault теперь готов генерировать учетные данные для readonlyроли. Вы можете получить учетные данные с …

$ vault read mysql/creds/readonly
Key            Value
---            -----
lease_id       mysql/creds/readonly/2e7cd1d0-e313-158e-c9a4-1dd3c3277642
lease_duration 2592000
lease_renewabletrue
password       04cf512a-57f8-d146-9cf5-ec2bd829ca8c
username       token-10a8b69f-a

… и убедитесь, что они работают, используя mysqlконсольное приложение:

$ mysql -h 127.0.0.1 -utoken-10a8b69f-a -p04cf512a-57f8-d146-9cf5-ec2bd829ca8c
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
...

Теперь, когда мы знаем, что наша интеграция Vault / MySQL работает, мы можем использовать ее в приложении Spring Boot с Spring Cloud Vault.

Возьмите проект Spring Boot. start.spring.io — хорошая отправная точка.

Включите spring-jdbcв свой проект Spring Cloud Vault Starter, зависимость от базы данных и драйвер MySQL. Добавьте следующий код в файл конфигурации сборки. Эти строки включают все необходимые зависимости.

специалист

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-vault-starter-config</artifactId>
    <version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-vault-config-databases</artifactId>
    <version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<repositories>
    <repository>
    <id>spring-snapshots</id>
    <name>Spring Snapshots</name>
    <url>https://repo.spring.io/libs-snapshot</url>
    <snapshots>
    <enabled>true</enabled>
</snapshots>
</repository>
</repositories>

Gradle

repositories {
    maven {
        url 'https://repo.spring.io/libs-snapshot'
    }
}

dependencies {
    compile("org.springframework.cloud:spring-cloud-vault-starter-config:1.0.0.BUILD-SNAPSHOT")
    compile("org.springframework.cloud:spring-cloud-vault-config-databases:1.0.0.BUILD-SNAPSHOT")
    compile("org.springframework:spring-jdbc:4.3.1.RELEASE")
    compile("mysql:mysql-connector-java:5.1.39")
}

Настройте конфигурацию

Spring Cloud Vault по умолчанию использует общий секретный бэкэнд. В нашем случае нам не нужен универсальный бэкэнд. Поэтому нам нужно отключить genericбэкэнд и включить бэкэнд MySQL. Вся конфигурация должна быть указана в конфигурации начальной загрузки. Для этого примера мы используем bootstrap.ymlв src/main/resources:

spring.cloud.vault:
token: 9a63de21-8af7-311a-9a5a-151b6a0d4795
scheme: http
generic:
enabled: false
mysql:
enabled: true
role: readonly

spring.datasource.url: jdbc:mysql://127.0.0.1:3306

Мы не добавляем учетные данные базы данных в файл конфигурации. Обычно это будет spring.datasource.usernameи spring.datasource.password.

Значение spring.cloud.vault.schemeустановлено на, httpпотому что мы запустили Vault в текстовом режиме HTTP (по spring.cloud.vault.schemeумолчанию https). Не делай этого в производстве. Открытый текст делает всю секретную историю бесполезной, поскольку все слушатели в сети могут видеть ваши секреты.
Обратите внимание, что токен, используемый в примере, является корневым токеном.

Вы можете создавать новые токены с:

$ vault token-create
Key            Value
---            -----
token          728d26ae-53a6-d8b6-d7a0-c5f62238ea55
token_accessor 2fd7dcba-39d0-04d3-8d6b-096c3529cf14
token_duration 0
token_renewabletrue
token_policies [root]

Это, очевидно, все, что вам нужно сделать для интеграции Vault MySQL с приложением Spring Boot.

Давайте быстро добавим код в ваше приложение, чтобы вы могли проверить интеграцию с реальным кодом.

@SpringBootApplication
public class MySqlApplication {
    public static void main(String[] args) {
        SpringApplication.run(MySqlApplication.class, args);
    }

    @Autowired
    DataSource dataSource;

    @PostConstruct
    private void postConstruct() throws Exception {

        try (Connection connection = dataSource.getConnection();
        Statement statement = connection.createStatement()) {

            ResultSet resultSet = statement.executeQuery("SELECT CURRENT_USER();");
            resultSet.next();

            System.out.println("Connection works with User: " + resultSet.getString(1));

            resultSet.close();
        }
    }

Затем запустите ваше приложение. Код производит вывод как:

Connection works with User: token-...

Spring Cloud Vault получает учетные данные базы данных при запуске и сохраняет их, используя имена свойств по умолчанию, чтобы Spring Boot мог выбрать их.

Другие услуги

Vault поддерживает несколько других интеграций. Мы создали поддержку для интеграций, которые мы также поддерживаем в Spring Boot.

Вы можете использовать следующие сервисы и базы данных:

  • PostgreSQL и MySQL: генерирует учетные данные для использования с JDBC и Spring Data JPA
  • Apache Cassandra: создает учетные данные для использования с клиентом Datastax и Spring Data Cassandra
  • Hashicorp Consul: генерирует токен ACL, который можно использовать вместе с Spring Cloud Consul
  • RabbitMQ: генерирует учетные данные для использования с Spring AMQP
  • Amazon AWS: генерирует ключ доступа и секретный ключ для использования с Spring Cloud AWS

Вы можете просмотреть полный пример в нашем репозитории примеров здесь .