Подключение к шифрованию Amazon Web Services (AWS) Key Management Service (KMS) — Расширенное применение
В данном документе предполагается, что у вас уже есть учетная запись Amazon Web Services (AWS), создан мастер-ключ в службе управления ключами (KMS) и выполнена базовая настройка плагина MariaDB AWS KMS. Эти шаги подробно описаны в Руководстве по настройке плагина шифрования ключей Amazon Web Services (AWS) Key Management Service (KMS).
В конечном итоге, хранение всех учетных данных, необходимых для чтения ключа на одном хосте, означает, что пользователь, получивший доступ к хосту, имеет достаточно информации для чтения зашифрованных файлов в каталоге данных, чтения зашифрованных ключей из каталога данных, взаимодействия с AWS KMS для расшифровки зашифрованных ключей и последующего использования расшифрованных ключей для расшифровки зашифрованных данных.
Теоретически, суперпользователь может прочитать память процесса сервера MariaDB для чтения расшифрованных ключей или перезапустить MariaDB с отключенной аутентификацией по паролю для выгрузки данных или добавить новых пользователей в MariaDB, чтобы разрешить пользователю подключиться и выгрузить данные. Решение этих проблем выходит за рамки данного документа. Пользователь, получивший права root доступа к вашей операционной системе или права root доступа к серверу MariaDB, сможет расшифровать ваши данные. Планируйте соответствующим образом.
Управление учетными данными AWS
Размещение учетных данных AWS в файле внутри домашнего каталога MariaDB не является оптимальным решением. По умолчанию любой пользователь с правом FILE может читать любые файлы, к которым у сервера MariaDB есть доступ, что включает и файл учетных данных. Чтобы защитить от этого, следует установить secure_file_priv для ограничения местоположения, из которого сервер позволит пользователю читать при выполнении LOAD DATA INFILE или функции LOAD_FILE().
Но размещение их в других местах требует передачи дополнительных данных серверу, что в случае с CentOS 7 требует настройки процедуры запуска systemd. Это наиболее легко сделать, создав файл «drop-in» в каталоге /etc/systemd/system/mariadb.service.d/. Файл должен оканчиваться на ".conf", но может иметь любое другое имя. После внесения любых изменений в файлы systemd выполните systemctl daemon-reload и затем запустите (или перезапустите) службу как обычно.
Вы можете разместить файл учетных данных в выбранном вами месте и затем обратиться к нему, установив переменную окружения AWS_CREDENTIAL_PROFILES_FILE в файле drop-in:
[Service] Environment=AWS_CREDENTIAL_PROFILES_FILE=/etc/aws-kms-credentials
Файл учетных данных должен быть доступен для чтения пользователю «mysql», но не для других пользователей.
Учетные данные AWS также можно поместить непосредственно в файл systemd «drop-in», который будет читаться при запуске службы MariaDB:
# cat /etc/systemd/system/mariadb.service.d/aws-kms.conf [Service] Environment=AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A Environment=AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV
Однако любой пользователь ОС может прочитать эту информацию из systemd, что может рассматриваться как риск безопасности. Другое решение — поместить учетные данные в отдельный файл, доступный только для чтения пользователем root, а затем обратиться к этому файлу с помощью директивы EnvironmentFile в файле drop-in systemd.
# cat /etc/systemd/system/mariadb.service.d/aws-kms.env AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV # chown root /etc/systemd/system/mariadb.service.d/aws-kms.env # chmod 600 /etc/systemd/system/mariadb.service.d/aws-kms.env # cat /etc/systemd/system/mariadb.service.d/aws-kms.conf [Service] EnvironmentFile=/etc/systemd/system/mariadb.service.d/aws-kms.env
Это имеет преимущество, что учетные данные могут быть прочитаны непосредственно только пользователем root. systemd добавляет эти переменные в среду сервера MariaDB при его запуске, и MariaDB может использовать учетные данные для взаимодействия с AWS. Однако обратите внимание, что любой процесс, выполняемый как пользователь «mysql», по-прежнему может читать учетные данные из файловой системы proc в Linux.
$ whoami mysql $ cat /proc/$(pgrep mysqld)/environ | tr '\0' '\n' | grep AWS AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV
Политика ключа AWS KMS
AWS KMS позволяет гибко настраивать политику ключа, которую можно редактировать. Это обеспечивает точный контроль над тем, какие пользователи могут взаимодействовать с ключами. Возможности варьируются от простого ограничения IP-адресов, разрешенных для выполнения операций с ключом, до требования использования устройства MFA (многофакторной аутентификации) для использования ключа и до обеспечения разделения ответственности путем создания дополнительного пользователя с ограниченными привилегиями для включения и отключения ключа. Все три варианта будут рассмотрены в этом разделе.
Для получения более подробной информации о настройке политики ключа для ваших мастер-ключей, пожалуйста, обратитесь к документации Политики ключа службы управления ключами AWS.
Ограничения по источнику IP
Простым и разумным ограничением является ограничение диапазона IP-адресов, которые разрешено использовать для вашего мастер-ключа. Таким образом, даже если кто-то получит учетные данные API, они не смогут использовать их для расшифровки ваших ключей шифрования с другого хоста.
Для ограничения доступа API только с определенного IP-адреса или диапазона IP-адресов вам необходимо вручную отредактировать политику ключа.
- Загрузите консоль IAM по адресу https://console.aws.amazon.com/iam/.
- На левой боковой панели щелкните «Ключи шифрования».
- Щелкните имя своего ключа шифрования, чтобы просмотреть его детали.
- Щелкните ссылку «Переключиться на просмотр политики», расположенную справа от заголовка раздела «Политика ключа».
- Найдите раздел, содержащий
"Sid": "Allow use of the key". - Добавьте этот текст ниже строки
"Sid":"Condition": { "IpAddress": { "aws:SourceIp": [ "10.1.2.3/32" ] } },... заменив10.1.2.3/32выше на IP-адрес или диапазон IP-адресов в формате CIDR. Например, один адрес будет192.168.12.34/32, а диапазон адресов —192.168.0.0/24. - Нажмите «Сохранить изменения».
- Нажмите «Продолжить», если появится предупреждение об использовании в будущем стандартного вида.
Теперь доступ к API будет ограничен запросами, поступающими с IP-адреса или диапазона IP-адресов, указанных в политике.
Использование устройства многофакторной аутентификации (MFA)
Один из подходов — изменить политику ключа для мастер-ключа таким образом, чтобы для использования ключа требовалось устройство MFA (многофакторной аутентификации). Это достигается с помощью оболочки, которая обрабатывает запросы кода MFA от пользователя, получает временные учетные данные с ограниченными привилегиями от AWS Security Token Service (STS) и помещает эти учетные данные в среду процесса сервера MariaDB. Учетные данные могут истекать уже через 15 минут.
Чтобы потребовать токен MFA для пользователей ключа, вам необходимо вручную отредактировать политику ключа.
- Загрузите консоль IAM по адресу https://console.aws.amazon.com/iam/.
- На левой боковой панели щелкните «Ключи шифрования».
- Щелкните имя своего ключа шифрования, чтобы просмотреть его детали.
- Щелкните ссылку «Переключиться на просмотр политики», расположенную справа от заголовка раздела «Политика ключа».
- Найдите раздел, содержащий
"Sid": "Allow use of the key". - Добавьте этот текст ниже строки
"Sid":"Condition": { "Bool": { "aws:MultiFactorAuthPresent": "True" } }, - Нажмите «Сохранить изменения».
- Нажмите «Продолжить», если появится предупреждение об использовании в будущем стандартного вида.
Теперь добавьте устройство MFA для вашего пользователя. Вам потребуется аппаратное устройство MFA или приложение, такое как Google Authenticator, установленное на вашем смартфоне.
- На левой боковой панели щелкните «Пользователи».
- Щелкните имя своего пользователя.
- Щелкните вкладку «Учетные данные безопасности».
- В разделе «Учетные данные входа» щелкните кнопку «Управлять устройством MFA».
- Выполните шаги по активации устройства MFA.
- Скопируйте ARN для вашего устройства MFA. Вам потребуется использовать его при настройке программы-оболочки.
Теперь настройте программу-оболочку.
- Скопируйте файл iam-kms-wrapper в /usr/local/bin/ и убедитесь, что он имеет разрешение на выполнение.
- Создайте файл конфигурации systemd «drop-in» в
/etc/systemd/system/mariadb.service.d/:[Service] EnvironmentFile=/etc/systemd/system/mariadb.service.d/aws-kms.env ExecStart= ExecStart=/usr/local/bin/iam-kms-wrapper --config=/etc/my.cnf.d/iam-kms-wrapper.config /usr/sbin/mysqld $MYSQLD_OPTS
- Выполните
systemctl daemon-reload. - Создайте файл по адресу
/etc/my.cnf.d/iam-kms-wrapper.configс этим содержимым, используя ARN вашего устройства MFA в качестве значения дляkms_mfa_id:[kms] kms_mfa_id = arn:aws:iam::551888187628:mfa/MDBEnc kms_mfa_socket = /tmp/kms_mfa_socket
При запуске службы MariaDB теперь оболочка временно создаст файл сокета по указанному адресу в параметре kms_mfa_socket. Оболочка прочитает код MFA из сокета и использует его для аутентификации в KMS. Для ввода кода MFA просто запишите цифры в файл сокета с помощью echo: echo 111676 > /tmp/kms_mfa_socket.
Команда systemctl будет блокироваться до запуска MariaDB, поэтому вам потребуется ввести код в файл сокета через отдельный терминал.
Обратите внимание, что временные учетные данные, помещенные в среду процесса MariaDB, истекают через определенный период времени, определенный запросом к AWS Security Token Service (STS). В приведенном ниже примере они истекают через 900 секунд. После этого времени MariaDB может не смочь сгенерировать новые ключи шифрования данных, что означает, что, например, попытка создать таблицу с ранее неиспользуемым идентификатором ключа завершится неудачей.
Пример программы-оболочки
Вот пример программы-оболочки, написанной на языке Go. Скомпилируйте ее в исполняемый файл под названием iam-kms-wrapper и используйте ее в соответствии с инструкциями выше. Конечно, ее можно написать на любом языке, для которого существует соответствующий SDK AWS, но Go имеет преимущество компиляции в статический двоичный файл, что означает, что вам не нужно беспокоиться о версиях интерпретаторов или установке сложных зависимостей на хосте, на котором работает ваш сервер MariaDB.
package main
import (
"syscall"
"os"
"log"
"flag"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/robfig/config"
)
func main() {
config_file_p := flag.String("config", "", "location of the config file")
flag.Parse()
if flag.NArg() < 1 {
log.Fatal("Command to wrap must be given as first command-line argument")
}
cmd := flag.Arg(0)
args := flag.Args()[0:]
conf, err := config.ReadDefault(*config_file_p)
if err != nil {
log.Fatal(err)
}
kms_mfa_id, err := conf.String("kms","kms_mfa_id")
mfa_socket_file, err := conf.String("kms","kms_mfa_socket")
sess := session.New()
svc := sts.New(sess)
syscall.Umask(0044)
log.Printf("Reading MFA token from %s\n",mfa_socket_file)
if err := syscall.Mknod(mfa_socket_file, syscall.S_IFIFO|uint32(os.FileMode(0622)), 0); err != nil {
log.Fatal(err)
}
file, err := os.Open(mfa_socket_file)
if err != nil {
log.Fatal(err)
}
token := make([]byte, 6)
if _, err := file.Read(token); err != nil {
log.Fatal(err)
}
file.Close()
if err := syscall.Unlink(mfa_socket_file); err != nil {
log.Fatal(err)
}
mfa_token := string(token)
token_params := &sts.GetSessionTokenInput{
DurationSeconds: aws.Int64(900),
SerialNumber: aws.String(kms_mfa_id),
TokenCode: aws.String(mfa_token),
}
resp, err := svc.GetSessionToken(token_params)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
// Prints out full error message, including original error if there was one.
log.Fatal("Error:", awsErr.Error())
} else {
log.Fatal("Error:", err.Error())
}
}
creds := resp.Credentials
os.Setenv("AWS_ACCESS_KEY_ID",*creds.AccessKeyId)
os.Setenv("AWS_SECRET_ACCESS_KEY",*creds.SecretAccessKey)
os.Setenv("AWS_SESSION_TOKEN",*creds.SessionToken)
execErr := syscall.Exec(cmd, args, os.Environ())
if execErr != nil {
panic(execErr)
}
}
Отключение ключей при их неиспользовании
Другая возможность — использовать API для отключения доступа к мастер-ключам и включить его только тогда, когда уполномоченный администратор знает, что служба MariaDB должна быть запущена. Специализированный инструмент на отдельном хосте может использоваться для включения ключа на очень короткий период времени во время запуска службы и затем быстро отключить ключ.
Для этого вы можете создать дополнительного пользователя IAM, который может использовать только API-точки kms:EnableKey и kms:DisableKey для вашего ключа. Этот пользователь не сможет шифровать или расшифровывать данные с помощью ключа.
Сначала создайте нового пользователя.
- Загрузите консоль IAM по адресу https://console.aws.amazon.com/iam/.
- На левой боковой панели щелкните «Пользователи».
- Щелкните «Создать новых пользователей».
- Введите новое имя пользователя. (Примеры будут использовать «MDBEncAdmin».)
- Щелкните «Показать учетные данные безопасности пользователя».
- Скопируйте учетные данные и поместите их в файл
credentialsсо следующей структурой:[MDBEncAdmin] aws_access_key_id=AKIAJMPPNO7EBKABCDEF aws_secret_access_key=pVdGwbuK5/jG64aBK1oEJOXRlkdM0aAylgabCDef
- Щелкните «Закрыть».
- Щелкните «Закрыть» еще раз, если появится запрос.
- Щелкните имя вашего нового пользователя, чтобы открыть страницу сведений.
- Скопируйте значение «ARN пользователя» для вашего пользователя (например, «arn:aws:iam::551888181234:user/MDBEncAdmin»). Вам потребуется это для следующего шага.
Теперь предоставьте новому пользователю разрешение на выполнение операций API с вашим ключом.
- На левой боковой панели щелкните «Ключи шифрования».
- Щелкните имя своего ключа, чтобы открыть страницу сведений.
- Щелкните «Переключиться на просмотр политики», если это не открыто. («Просмотр политики» — это большое текстовое поле, содержащее JSON, описывающий политику ключа.)
- Создайте новый элемент в массиве
Statementсо следующей структурой:{ "Sid": "Allow Enable and Disable of the key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::551888181234:user/MDBEncAdmin" }, "Action": [ "kms:EnableKey", "kms:DisableKey" ] },... чтобы ваша политика ключа выглядела так:{ "Version": "2012-10-17", "Id": "key-consolepolicy-2", "Statement": [ { "Sid": "Allow Enable and Disable of the key", "Effect": "Allow", "Principal": { ... - Нажмите «Сохранить изменения».
Вы добавили нового пользователя IAM и предоставили ему права на включение и отключение вашего ключа. Этот пользователь сможет выполнять эти операции с помощью AWS CLI или через скрипт собственной разработки с использованием AWS API. Например, с помощью AWS CLI:
$ cat ~/.aws/credentials [MDBEncAdmin] aws_access_key_id=AKIAJMPPNO7EBKABCDEF aws_secret_access_key=pVdGwbuK5/jG64aBK1oEJOXRlkdM0aAylgabCDef $ AWS_PROFILE=MDBEncAdmin aws --region us-east-1 kms disable-key --key-id arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c
Для запуска MariaDB новому пользователю необходимо включить главный ключ, затем DBA может запустить MariaDB, а этот пользователь может снова отключить главный ключ после запуска службы. Обратите внимание, что в этом процессе MariaDB не сможет создавать новые ключи шифрования, как это происходит при создании пользователем таблицы, которая ссылается на несуществующий идентификатор ключа. Плагин AWS KMS столкнётся с ошибкой, если попытается сгенерировать новый ключ шифрования, пока главный ключ отключён. В этом случае администратор ключа должен включить ключ, прежде чем операция сможет завершиться успешно. Вот что вы должны увидеть в журнале, если MariaDB попытается взаимодействовать с отключённым главным ключом:
[ERROR] AWS KMS plugin : GenerateDataKeyWithoutPlaintext failed : DisabledException - Unable to parse ExceptionName: DisabledException Message: arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c is disabled.
Добавление MFA
Также возможно добавить MFA к этой технике, чтобы пользователю, который включает и отключает главный ключ, пришлось пройти аутентификацию с помощью устройства MFA. Скопируйте инструкции из раздела MFA выше, чтобы добавить MFA в раздел политики для пользователя с правами EnableKey и DisableKeys, добавьте устройство MFA для этого пользователя, используйте Security Token Service (STS) для получения временных учетных данных безопасности, а затем используйте эти учетные данные для выполнения вызовов API. Вот пример Python-скрипта, который следует этому процессу:
#!/usr/bin/env python
import boto3
import sys
# Command-line argument processing should be more robust than this...
action= sys.argv[1]
mfa_token= sys.argv[2]
# These should perhaps go into a config file instead of here
mfa_serial= 'arn:aws:iam::551888181234:mfa/MDBEncAdmin'
key_id= 'arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c'
# Make the connection to the Security Token Service to get temporary credentials
token_client= boto3.client('sts')
token_response= token_client.get_session_token(
DurationSeconds= 900,
SerialNumber= mfa_serial,
TokenCode= mfa_token
)
cred= token_response['Credentials']
# Start new session using temporary, MFA-authenticated credentials
kms_session= boto3.session.Session(
aws_access_key_id= cred['AccessKeyId'],
aws_secret_access_key= cred['SecretAccessKey'],
aws_session_token= cred['SessionToken'],
region_name= key_id.split(':')[3]
)
# Start KMS client and execute operation against key
kms_client= kms_session.client('kms')
if action == 'enable' or action == 'e':
action_f= kms_client.enable_key
elif action == 'disable' or action == 'd':
action_f= kms_client.disable_key
else:
raise Exception('Action must be either "disable" or "enable"')
action_f(KeyId=key_id)
$ AWS_PROFILE=MDBEncAdmin python kms-manage-key disable 575290 $ AWS_PROFILE=MDBEncAdmin python kms-manage-key enable 799870
Ведение журнала и аудит
CloudTrail
Услуга Amazon CloudTrail создаёт текстовые файлы журналов в формате JSON для каждого взаимодействия с API. Включение CloudTrail требует S3, что влечёт дополнительные расходы.
Сначала включите CloudTrail и добавьте след.
- Загрузите консоль CloudTrail по адресу https://console.aws.amazon.com/cloudtrail/.
- Если вы никогда не использовали CloudTrail ранее, нажмите «Начать сейчас».
- Введите значение для «имени следа». В этом примере используется «mariadb-encryption-key».
- Создайте новый ведро S3, используя уникальное имя по всему миру, или используйте существующее ведро S3 в зависимости от ваших потребностей.
- Нажмите «Включить».
Если вы перейдёте в созданное вами ведро S3, вы должны найти файлы журналов, которые содержат описания ваших взаимодействий с API в формате JSON.
CloudWatch
Услуга Amazon CloudWatch позволяет создавать оповещения и правила событий, которые отслеживают информацию из журналов.
Сначала отправьте свои журналы CloudTrail в CloudWatch.
- Загрузите консоль CloudTrail по адресу https://console.aws.amazon.com/cloudtrail/.
- Нажмите «Следы» в боковой панели навигации слева.
- Нажмите имя вашего следа, чтобы открыть представление «Настройка».
- В разделе «Журналы CloudWatch» нажмите «Настроить».
- Нажмите «Продолжить».
- Нажмите «Разрешить».
Теперь настройте тему SNS для облегчения уведомлений по электронной почте.
- Откройте https://console.aws.amazon.com/sns/.
- Убедитесь, что регион в консоли (смотрите в правом верхнем углу) совпадает с регионом, где вы создали свой ключ!
- Нажмите «Начать», если появится запрос.
- Нажмите «События» в боковой панели слева.
- Нажмите «Создать новую тему».
- Введите Имя темы по своему выбору.
- Введите Отображаемое имя по своему выбору.
- Нажмите «Создать тему».
- Нажмите ARN вашей новой темы SNS.
- Нажмите «Создать подписку».
- Выберите «Электронная почта» из раскрывающегося списка «Протокол».
- Введите желаемый адрес электронной почты для уведомлений в поле «Конечная точка».
- Дождитесь появления подтверждающего письма и следуйте инструкциям.
Теперь настройте CloudWatch и создайте правило событий.
- Откройте https://console.aws.amazon.com/cloudwatch/.
- Убедитесь, что регион в консоли (смотрите в правом верхнем углу) совпадает с регионом, где вы создали свой ключ и вашу тему SNS!
- Нажмите «События» в боковой панели слева.
- Нажмите «Создать правило».
- Выберите «Вызов AWS API» из раскрывающегося списка «Выберите источник событий».
- Выберите «KMS» из раскрывающегося списка «Имя службы».
- Определите, какие операции должны запускать событие. (Для простоты можно оставить «Любая операция».)
- Нажмите «Добавить целевой объект».
- Выберите «Целевой объект SNS» из раскрывающегося списка.
- Выберите тему SNS, созданную на предыдущих шагах.
- Нажмите «Настроить детали».
- Введите Имя и Описание по своему выбору.
- Нажмите «Создать правило».
Теперь вы будете получать электронные письма всякий раз, когда кто-то выполняет вызовы API для службы KMS в регионе, где вы создали правило CloudWatch Event. Это означает, что вы будете получать электронные письма всякий раз, когда ключ включается или отключается, а также всякий раз, когда плагин AWS KMS генерирует новые ключи или расшифровывает ключи, хранящиеся на диске на сервере MariaDB.
Вы также можете создать правило событий (или дополнительное событие), которое соответствует только случаям, когда неавторизованный пользователь пытается получить доступ к ключу. Вы можете достичь этого, вручную отредактировав селектор событий правила, чтобы он выглядел примерно так:
{
"detail-type": [
"AWS API Call via CloudTrail"
],
"detail": {
"eventSource": [
"kms.amazonaws.com"
],
"errorCode": [
"AccessDenied",
"UnauthorizedOperation"
]
}
}
Письма отформатированы в формате JSON. Дальнейшая настройка потока электронных писем CloudWatch выходит за рамки этого документа.
Существует множество других рабочих процессов, доступных с помощью CloudWatch, включая рабочие процессы с оповещениями и панелями мониторинга. Они также выходят за рамки этого документа.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/aws-key-management-encryption-plugin-advanced-usage/