Какой лучший способ передачи учетных данных AWS в качестве пользовательских данных в экземпляр EC2? - PullRequest
22 голосов
/ 13 марта 2009

У меня есть архитектура обработки заданий, основанная на AWS, которая требует запросов экземпляров EC2 S3 и SQS. Чтобы запускать экземпляры для доступа к API, учетные данные отправляются в виде пользовательских данных (-f) в виде сценария оболочки в кодировке base64. Например:

$ cat ec2.sh
...
export AWS_ACCOUNT_NUMBER='1111-1111-1111'
export AWS_ACCESS_KEY_ID='0x0x0x0x0x0x0x0x0x0'
...
$ zip -P 'secret-password' ec2.sh
$ openssl enc -base64 -in ec2.zip

Запущено много экземпляров ...

$ ec2run ami-a83fabc0 -n 20 -f ec2.zip

Каждый экземпляр декодирует и расшифровывает ec2.zip, используя «секретный пароль», который жестко запрограммирован в сценарии инициализации. Хотя это работает, у меня есть две проблемы с моим подходом.

  1. 'zip -P' не очень безопасен
  2. Пароль жестко закодирован в экземпляре (это всегда «секретный пароль»)

Метод очень похож на описанный здесь

Есть ли более элегантный или принятый подход? Использование gpg для шифрования учетных данных и сохранение закрытого ключа в экземпляре для расшифровки - это подход, который я сейчас рассматриваю, но я не знаю ни о каких предостережениях. Могу ли я использовать пары ключей AWS напрямую? Я скучаю по какой-то супер очевидной части API?

Ответы [ 5 ]

12 голосов
/ 13 марта 2009

Вы можете сохранить учетные данные на машине (или передать, использовать, а затем удалить их).

Вы можете передавать учетные данные по безопасному каналу (например, используя scp с неинтерактивной аутентификацией, например, с парой ключей), так что вам не нужно будет выполнять какое-либо пользовательское шифрование (только убедитесь, что разрешения правильно установлены на 0400 в файле ключа всегда, например, установите разрешения для мастер-файлов и используйте scp -p)

Если вышеупомянутое не отвечает на ваш вопрос, пожалуйста, предоставьте более подробную информацию повторно. каковы ваши настройки и чего вы пытаетесь достичь. Должны ли действия EC2 быть инициированы на нескольких узлах из центрального местоположения? Доступен ли SSH между несколькими узлами и центральным местоположением? И т.д.


EDIT

Рассматривали ли вы параметризацию вашего AMI , требуя, чтобы те, кто создает экземпляр вашего AMI, сначала заполнили пользовательские данные (ec2-run-instances -f user-data-file) своими ключами AWS? Затем ваш AMI может динамически извлекать эти параметры для каждого экземпляра из http://169.254.169.254/1.0/user-data.


UPDATE

ОК, здесь идет сравнение различных подходов, обсужденных до сих пор с точки зрения безопасности:

  1. Безопасность данных при сохранении в AMI user-data в незашифрованном виде
    • низкий
    • данные открытого текста доступны для любого пользователя, которому удается войти в систему AMI и который имеет доступ к telnet, curl, wget и т. Д. (Может получить доступ к тексту http://169.254.169.254/1.0/user-data)
    • вы уязвимы для атак через прокси-сервер (например, злоумышленник спрашивает Apache, который может или не может работать на AMI, чтобы получить и переслать открытый текст http://169.254.169.254/1.0/user-data)
  2. Безопасность данных, когда хранится в AMI user-data и шифруется (или расшифровывается) с помощью легкодоступного ключа
    • низкий
    • легкодоступный ключ (пароль) может включать в себя:
      • ключ, жестко запрограммированный в скрипте внутри ABI (где ABI может быть получен злоумышленником)
      • ключ жестко запрограммирован в скрипте на самом AMI, где скрипт может быть прочитан любым пользователем, которому удается войти в AMI
      • любая другая легко доступная информация, такая как открытые ключи и т. Д.
      • любой закрытый ключ (его открытый ключ можно легко получить)
    • при наличии легко доступного ключа (пароля) применяются те же проблемы, что указаны в пункте 1, а именно:
      • расшифрованные данные доступны для любого пользователя, которому удается войти в систему AMI и который имеет доступ к telnet, curl, wget и т. Д. (Может получить доступ к тексту http://169.254.169.254/1.0/user-data)
      • вы уязвимы для атак через прокси-сервер (например, злоумышленник спрашивает Apache, который может или не может работать на AMI, чтобы получить и переслать зашифрованный http://169.254.169.254/1.0/user-data, внешне расшифрованный с помощью легко получаемого ключа)
  3. Безопасность данных, когда хранится в AMI user-data и шифруется с помощью нелегко получаемого ключа
    • средний
    • зашифрованные данные доступны для любого пользователя, которому удается войти в систему AMI и который имеет доступ к telnet, curl, wget и т. Д. (Может получить доступ к зашифрованному http://169.254.169.254/1.0/user-data)
      • попытка расшифровать зашифрованные данные может быть предпринята с помощью атаки методом грубой силы
  4. Безопасность данных, когда хранится в AMI, в защищенном месте (нет необходимости в шифровании)
    • выше
    • данные доступны только одному пользователю, пользователю, которому необходимы данные для работы
      • например. файл принадлежит пользователю: пользователь с маской 0600 или 0400
    • злоумышленник должен иметь возможность выдавать себя за конкретного пользователя, чтобы получить доступ к данным
      • дополнительные уровни безопасности, такие как отказ в прямом входе пользователя в систему (необходимость проходить через root для интерактивного олицетворения), повышают безопасность

Таким образом, любой метод с использованием AMI user-data не является наиболее безопасным, поскольку получение доступа к любому пользователю на машине (самая слабая точка) ставит под угрозу данные.

Это может быть смягчено, если учетные данные S3 требовались только в течение ограниченного периода времени (т. Е. Только во время процесса развертывания), , если AWS позволил вам перезаписать или удалить содержимое user-data, когда сделано с этим (но это, кажется, не имеет место.) Альтернативой было бы создание временных учетных данных S3 для продолжительности процесса развертывания, если это возможно (скомпрометировать эти учетные данные, начиная с user-data, после того, как процесс развертывания завершено и учетные данные были аннулированы с помощью AWS, больше не представляет угрозы безопасности.)

Если вышеприведенное не применимо (например, учетные данные S3, необходимые для развернутых узлов на неопределенный срок) или невозможно (например, невозможно выдать временные учетные данные S3 только для развертывания), тогда лучшим способом остается прикусить пулю и scp учетные данные различные узлы, возможно, параллельно, с правильным владельцем и правами доступа.

11 голосов
/ 20 июня 2010

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

http://www.shlomoswidler.com/2009/08/how-to-keep-your-aws-credentials-on-ec2.html

10 голосов
/ 24 июня 2013

Лучше всего использовать профили экземпляров . Основная идея:

  • Создать профиль экземпляра
  • Создать новую роль IAM
  • Назначьте политику ранее созданной роли, например:

    { "Утверждение": [ { «Сид»: «Стмт1369049349504», «Действие»: «sqs: », «Эффект»: «Разрешить», «Ресурс»: «» } ] }

  • Свяжите вместе роль и профиль экземпляра.

  • Когда вы запускаете новый экземпляр EC2, убедитесь, что вы указали имя профиля экземпляра.

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

Полный пример взят из списка рассылки boto-user:

Во-первых, вы должны создать документ политики JSON, который представляет, к каким службам и ресурсам должна иметь доступ роль IAM. например, эта политика разрешает все действия S3 для группы «my_bucket». Вы можете использовать любую политику, подходящую для вашего приложения.

BUCKET_POLICY = """{
  "Statement":[{
    "Effect":"Allow",
    "Action":["s3:*"],
    "Resource":["arn:aws:s3:::my_bucket"]}]}"""

Далее необходимо создать профиль экземпляра в IAM.

import boto
c = boto.connect_iam()
instance_profile = c.create_instance_profile('myinstanceprofile')

Получив профиль экземпляра, вам нужно создать роль, добавить роль в профиль экземпляра и связать политику с ролью.

role = c.create_role('myrole')
c.add_role_to_instance_profile('myinstanceprofile', 'myrole')
c.put_role_policy('myrole', 'mypolicy', BUCKET_POLICY)

Теперь вы можете использовать этот профиль экземпляра при запуске экземпляра:

ec2 = boto.connect_ec2()
ec2.run_instances('ami-xxxxxxx', ..., instance_profile_name='myinstanceprofile')
7 голосов
/ 19 августа 2013

Я хотел бы отметить, что больше не требуется предоставлять какие-либо учетные данные для вашего экземпляра EC2. Используя IAM, вы можете создать роль для ваших экземпляров EC2. В этих ролях вы можете установить детализированные политики, которые позволяют вашему экземпляру EC2, например, получать конкретный объект из определенного сегмента S3 и не более. Подробнее о ролях IAM можно узнать из документации AWS:

http://docs.aws.amazon.com/IAM/latest/UserGuide/WorkingWithRoles.html

1 голос
/ 28 сентября 2017

Как уже отмечали другие, вам не нужно хранить учетные данные AWS для экземпляра EC2, используя роли IAM - https://aws.amazon.com/blogs/security/a-safer-way-to-distribute-aws-credentials-to-ec2/. Я добавлю, что вы можете использовать тот же метод и для безопасного хранения учетных данных NON-AWS для своего экземпляра EC2, например, если у вас есть некоторые учетные данные, которые вы хотите сохранить в безопасности. Вы сохраняете учетные данные non-aws на S3 Bukcet и используете роль IAM для доступа к этому сегменту. Вы можете найти более подробную информацию об этом здесь - https://aws.amazon.com/blogs/security/using-iam-roles-to-distribute-non-aws-credentials-to-your-ec2-instances/

...