Статьи

Управление секретами с хранилищем

Как вы храните секреты?

Пароли, ключи API, безопасные токены и конфиденциальные данные попадают в категорию секретов. Это данные, которые не должны лежать вокруг. Он не должен быть доступен в виде открытого текста в легко угадываемых местах. На самом деле, он не должен храниться в открытом виде в любом месте.

Конфиденциальные данные могут быть зашифрованы с помощью сервера Spring Cloud Config или TomEE . Зашифрованные данные на один шаг лучше, чем незашифрованные. Шифрование налагает на другую сторону необходимость дешифрования на стороне пользователя, которая требует распространения ключа дешифрования. Теперь, где вы положили ключ? Защищен ли ключ парольной фразой? Где вы положили пароль? На скольких системах вы распространяете свой ключ и фразу-пароль?

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

Один из подходов — поместить ключ в трудно угадываемое место перед запуском приложения и стереть ключ после его чтения в память. Время, в течение которого ключ доступен, сокращается. Время атаки сокращено, но ключ все еще был там. Стирание ключа работает только для одного запуска приложения. Известно, что контейнеры и микросервисы в облаке перезапускаются после сбоя. Перезапуск приложения больше невозможен, так как ключ исчез.

Подожди, есть надежда!

Правильно выполнить шифрование трудно, управление секретами еще сложнее, если вы делаете это самостоятельно. Vault решает именно эти проблемы. Это помогает решить проблему куриного яйца и поставляется с шифрованием. Vault — это служба для управления секретами. Он предоставляет API, который дает доступ к секретам на основе политик. Любой пользователь API должен пройти аутентификацию и видит только те секреты, на которые он авторизован. Vault шифрует данные, используя 256-битный AES с GCM . Он может хранить данные в различных бэкэндах (файлы, Amazon DynamoDB, Consul и т. Д. И многое другое). Другим ключевым аспектом является то, что Vault никогда не хранит ключ в постоянном месте. Запуск / перезапуск Vault всегда требует, чтобы один или несколько операторов открыли Vault. Однако давайте начнем с основ.

Хранилище — не решение всех проблем безопасности. Стоит проверить документацию модели безопасности хранилища, чтобы получить представление о модели угрозы.

Чтобы загрузить Vault, вам необходимо скачать двоичный файл с https://www.vaultproject.io/downloads.html . Vault написан на Go и бинарные файлы доступны для различных платформ. Разархивируйте загруженный файл, и вы готовы использовать Vault.

Запустите Vault Server дальше. Вам нужен файл конфигурации, чтобы указать некоторые параметры.

vault.conf

1
2
3
4
5
6
7
8
9
backend "inmem" {
}
 
listener "tcp" {
  address = "0.0.0.0:8200"
  tls_disable = 1
}
 
disable_mlock = true

Этот конфиг подходит для большинства платформ и позволяет попробовать первые шаги в Vault. Не используйте его в производстве.

Запустите Vault с

1
$ vault server -config vault.conf

Vault запустится как процесс переднего плана.

Поздравляю, вы запустили Vault.

Сейчас хороший момент, чтобы открыть вторую консоль для выполнения административных задач с помощью Vault. Vault теперь работает в режиме открытого текста, потому что TLS / SSL отключен. Вам нужно установить VAULT_ADDR среды VAULT_ADDR чтобы указать клиенту Vault использовать открытый текст:

1
$ export VAULT_ADDR=http://127.0.0.1:8200

Хранилище запущено. Требуется два дополнительных шага, прежде чем вы действительно сможете начать использовать Vault. Хранилище должно быть инициализировано и распечатано. Инициализация — это процесс генерации начального ключа. Unsealing предоставляет ключи для Vault, так что Vault может расшифровать зашифрованные данные и начать обслуживание клиентов.

Vault создает при инициализации две вещи:

  1. Главный ключ и разделение ключей
  2. Корневой токен

Vault позволяет использовать общие ключи, используя алгоритм Shamir Secret Sharing . Данные обычно шифруются одним ключом. Тот, кто имеет доступ к ключу, имеет полный контроль над всеми данными как один человек. Иногда ты этого не хочешь. Обычно вы хотите распределить главный ключ среди нескольких людей, чтобы никто не контролировал все ваши зашифрованные данные. Vault позволяет указать общее количество общих ключей и количество общих ключей, необходимых для распечатывания Vault во время инициализации. Эту настройку нельзя изменить после инициализации Vault. При инициализации Vault из консоли отобразится полный ключ. Инициализация с использованием API — это, возможно, то, что вы хотите использовать в своем инструменте DevOps, например, отправляя защищенные сообщения своим операторам, которые должны получить ключевую долю.

Инициализируйте Vault с помощью:

1
$ vault init -key-shares=5 -key-threshold=2

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
Key 1: 99eb89735688ad7a29bb1ff27383bd1005a22a62c97f14357ea4f5f98c1d2c8c01
Key 2: 0c5605b16905794a302603bbeb8f6c8ad5ecf7e877f0e29084f838eba931b86902
Key 3: 7f3d88067c7e355acea4fe756a8b23fc6cd6bc671d7cb0f3d2cc8ae543dc3dc303
Key 4: 3d37062e1704ca2a02073b29c097d5a56e7056e710f515c16b40b9cfe3698bb804
Key 5: 4e5c8b99027f863afc85c6e741939ad3d74a1d687a7947a23d740bc109840e1205
Initial Root Token: 9a63de21-8af7-311a-9a5a-151b6a0d4795
 
Vault initialized with 5 keys and a key threshold of 2. Please
securely distribute the above keys. When the Vault is re-sealed,
restarted, or stopped, you must provide at least 2 of these keys
to unseal it again.
 
Vault does not store the master key. Without at least 2 keys,
your Vault will remain permanently sealed.

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

01
02
03
04
05
06
07
08
09
10
11
$ vault unseal 99eb89735688ad7a29bb1ff27383bd1005a22a62c97f14357ea4f5f98c1d2c8c01
Sealed: true
Key Shares: 5
Key Threshold: 2
Unseal Progress: 1
 
$ vault unseal 7f3d88067c7e355acea4fe756a8b23fc6cd6bc671d7cb0f3d2cc8ae543dc3dc303
Sealed: false
Key Shares: 5
Key Threshold: 2
Unseal Progress: 0

Как только хранилище будет открыто, вы можете начать хранить секретные данные внутри хранилища.

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

Помните вывод из инициализации? Последний элемент после обмена ключами является корневым токеном. На данный момент самый простой способ — использовать корневой токен. Самый простой способ использовать токен на консоли — сохранить его в переменной среды:

1
2
$ export VAULT_TOKEN=9a63de21-8af7-311a-9a5a-151b6a0d4795
$ vault write secret/my-application password=H@rdT0Gu3ss

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

Помимо общего секретного бэкэнда Vault предоставляет другие бэкэнды, которые позволяют генерировать учетные данные для MySQL, SQL Server, PostgreSQL, Consul и многих других .

Аутентификация

Vault работает в основном с токенами. Каждый токен назначается политике, которая может ограничивать действия и пути. Политики используют сопоставление на основе пути для применения правил. Токены могут получать метаданные (значения ключа) и отображаемые имена, что делает администрирование более удобным для пользователей.

Вы можете создавать токены вручную и назначать их приложениям и пользователям. Кроме того, есть несколько механизмов аутентификации (LDAP, Username / Password, GitHub Token,…), которые позволяют пользователям входить в систему и получать токен. Токены и механизмы аутентификации могут быть отозваны, что позволяет легко заблокировать конкретного пользователя.

Spring Cloud Vault

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

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

1
2
3
4
/secret/{application}/{profile}
/secret/{application}
/secret/{defaultContext}/{profile}
/secret/{defaultContext}

Начало работы с Spring Cloud Vault

Сначала вам нужен проект Spring Boot. start.spring.io — хорошая отправная точка. Достаточно любого пустого проекта.

Включите стартер Spring Cloud Vault в свой проект

Добавьте следующий код в файл конфигурации сборки. Эти строки включают стартер для Spring Cloud Vault со всеми необходимыми зависимостями.

специалист

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-vault-starter-config</artifactId>
    <version>1.0.0.BUILD-SNAPSHOT</version>
</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

1
2
3
4
5
6
7
8
9
repositories {
    maven {
    }
}
 
dependencies {
    compile("org.springframework.cloud:spring-cloud-vault-starter-config:1.0.0.BUILD-SNAPSHOT")
}

Обязательно включите репозиторий Snapshots при использовании зависимостей SNAPSHOT .

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

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

1
2
3
4
5
spring:
    application.name: my-application
    cloud.vault:
        token: 9a63de21-8af7-311a-9a5a-151b6a0d4795
        scheme: http

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

Обратите внимание, что токен здесь взят из корневого токена. Вы можете создавать новые токены с:

1
2
3
4
5
6
7
8
$ vault token-create
Key             Value
---             -----
token           728d26ae-53a6-d8b6-d7a0-c5f62238ea55
token_accessor  2fd7dcba-39d0-04d3-8d6b-096c3529cf14
token_duration  0
token_renewable true
token_policies  [root]

Записать данные в хранилище

Запишите некоторые данные в Vault:

1
$ vault write secret/my-application password=H@rdT0Gu3ss

Обновите приложение Spring Boot

Теперь перейдите к классу запуска приложений и улучшите его, чтобы ввести секрет. Используйте то же имя свойства, которое вы использовали для записи его в Vault:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package example;
 
import javax.annotation.PostConstruct;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class SpringBootVaultHelloWorldApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringBootVaultHelloWorldApplication.class, args);
    }
 
    @Value("${password}")
    String password;
 
    @PostConstruct
    private void postConstruct() {
        System.out.println("My password is: " + password);
    }
}

Все остальные вещи обрабатываются самим Spring Cloud Vault. Теперь запустите ваше приложение.

Поздравляю, вы сделали это!

прогноз

Spring Cloud Vault живет в Cloud Incubator прямо сейчас. Он поддерживает токен и аутентификацию AppId . Spring Cloud Vault поставляется с стартером и зависимостями для интеграции различных баз данных и поддержки RabbitMQ / Consul. Вы можете ознакомиться с проектом и документацией по адресу ttps: //github.com/spring-cloud-incubator/spring-cloud-vault-config .

Мы подготовили несколько примеров, чтобы дать вам представление о том, как вы можете интегрировать Spring Cloud Vault со своим приложением. Вы можете найти образцы по адресу https://github.com/mp911de/spring-cloud-vault-config-samples .

Ссылка: Управление секретами с Vault от нашего партнера JCG Марка Палуха в блоге paluch.biz .