AWS認証情報をユーザーデータとしてEC2インスタンスに渡すための最良の方法は何ですか?
-
22-07-2019 - |
質問
EC2インスタンスがS3とSQSをクエリする必要があるAWSに基づくジョブ処理アーキテクチャを持っています。インスタンスを実行してAPIにアクセスできるようにするために、資格情報は、base64エンコードシェルスクリプトの形式でユーザーデータ(-f)として送信されます。例:
$ 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
各インスタンスは、initスクリプトにハードコードされた「secret-password」を使用してec2.zipをデコードおよび復号化します。動作しますが、アプローチには2つの問題があります。
- 「zip -P」はあまり安全ではありません
- パスワードはインスタンスにハードコードされています(常に「secret-password」です)
この方法は、こちら
で説明した方法と非常に似ています。よりエレガントな、または受け入れられているアプローチはありますか? gpgを使用して資格情報を暗号化し、インスタンスに秘密キーを保存して解読することは、現在検討しているアプローチですが、注意点はありません。 AWSキーペアを直接使用できますか? APIの非常に明白な部分が欠落していますか?
解決
資格情報をマシンに保存(または転送、使用、削除)できます。
安全なチャネルを介して資格情報を転送できます(たとえば、キーペアなどの非対話型認証で scp
を使用)。カスタム暗号化を実行する必要はありません(アクセス許可がキーファイルで常に 0400
に適切に設定します。たとえば、マスターファイルにアクセス許可を設定し、 scp -p
)
上記で質問に答えられない場合は、より具体的な詳細をお知らせください。セットアップと達成しようとしているもの。 EC2アクションは、中央の場所から複数のノードで開始されますか?複数のノードと中央の場所の間でSSHを利用できますか?その他
編集
AMIのパラメーター化を検討しました。 AMIは最初にユーザーデータ( ec2-run-instances -f user-data-file
)にAWSキーを入力しますか? AMIは、これらのインスタンスごとのパラメーターを http://169.254.169.254/1.0/user-data
から動的に取得できます。
更新
OK、これまでに説明したさまざまなアプローチのセキュリティを重視した比較に進みます:
- AMIに保存されている場合のデータのセキュリティ暗号化されていない
user-data
- 低
- クリアテキストデータには、AMIへのログオンを管理し、
telnet
、curl
、任意のユーザーがアクセスできます。 > wget
など(クリアテキストhttp://169.254.169.254/1.0/user-data
にアクセスできます) - プロキシリクエスト攻撃に対して脆弱です(たとえば、攻撃者がAMIで実行されているかどうかにかかわらずApacheにクリアテキスト
http://169.254.169.254/1.0/user-dataを取得および転送するように要求します。
)
- AMI
user-data
に保存され、簡単に取得可能なキーで暗号化(または復号化)できる場合のデータのセキュリティ- 低
- 簡単に入手できるキー(パスワード)には以下が含まれます。
- ABI内のスクリプトにハードコードされたキー(攻撃者がABIを入手できる場所)
- AMI自体のスクリプトにハードコードされたキー。このスクリプトは、AMIへのログオンを管理している任意のユーザーが読み取り可能です
- 公開鍵など、他の簡単に入手できる情報
- 任意の秘密鍵(公開鍵はすぐに入手できる場合があります)
- 簡単に入手できるキー(パスワード)が与えられた場合、ポイント1で特定された同じ問題が適用されます。
- 復号化されたデータには、AMIへのログインを管理し、
telnet
、curl
、にアクセスできる任意のユーザーがアクセスできます。 wget
など(クリアテキストhttp://169.254.169.254/1.0/user-data
にアクセスできます) - プロキシ要求攻撃に対して脆弱です(たとえば、攻撃者は、AMIで実行されているかどうかにかかわらず、Apacheに暗号化された
http://169.254.169.254/1.0/user-data
、簡単に入手できるキーで完全に解読されます)
- 復号化されたデータには、AMIへのログインを管理し、
- AMI
user-data
に保存され、簡単に取得できないキーで暗号化された場合のデータのセキュリティ- 平均
- 暗号化されたデータは、AMIへのログオンを管理し、
telnet
、curl
、にアクセスできる任意のユーザーがアクセスできます。 wget
など(暗号化されたhttp://169.254.169.254/1.0/user-data
にアクセスできます)- ブルートフォース攻撃を使用して、暗号化されたデータを復号化しようとすることができます
- AMIの安全な場所に保存された場合のデータのセキュリティ(暗号化するための付加価値なし)
他のヒント
安全にEC2インスタンスにシークレットを渡すさまざまな方法と、賛否両論を検討した記事を書きました。それぞれの短所。
http:// www.shlomoswidler.com/2009/08/how-to-keep-your-aws-credentials-on-ec2.html
最良の方法は、インスタンスプロファイルを使用することです。基本的な考え方は次のとおりです。
- インスタンスプロファイルを作成
- 新しいIAMロールを作成する
-
以前に作成したロールにポリシーを割り当てます。例:
{ " Statement&quot ;: [ { " Sid&quot ;:" Stmt1369049349504&quot ;, "アクション&quot ;:" sqs:&quot ;, " Effect&quot ;:" Allow&quot ;, "リソース&quot ;:" " } ] }
-
ロールとインスタンスプロファイルを関連付けます。
- 新しいEC2インスタンスを開始するときは、必ずインスタンスプロファイル名を指定してください。
すべてが正常に機能し、EC2インスタンス内からAWSサービスへの接続に使用するライブラリがインスタンスメタデータからの認証情報の取得をサポートしている場合、コードはAWSサービスを使用できます。
boto-userメーリングリストからの完全な例:
最初に、IAMロールがアクセスする必要があるサービスとリソースを表すJSONポリシードキュメントを作成する必要があります。たとえば、このポリシーは、バケット「my_bucket」のすべてのS3アクションを許可します。アプリケーションに適したポリシーを使用できます。
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')
EC2インスタンスに認証情報を提供する必要はもうないことを指摘したいと思います。 IAMを使用して、EC2インスタンスのロールを作成できます。これらのロールでは、EC2インスタンスが特定のS3バケットから特定のオブジェクトを取得することを許可する詳細なポリシーを設定できます。 IAMロールの詳細については、AWSドキュメントをご覧ください:
http://docs.aws.amazon.com/IAM/ latest / UserGuide / WorkingWithRoles.html
他の人が既に指摘しているように、IAMロールを使用してEC2インスタンスのAWS認証情報を保存する必要はありません- https:// aws .amazon.com / blogs / security / a-safer-way-to-distribute-aws-credentials-to-ec2 / 。 EC2インスタンスの NON-AWS認証情報を安全に保存するためにも同じ方法を使用できることを追加します。たとえば、安全に保ちたいdb認証情報がある場合などです。 AWS以外の認証情報をS3 Bukcetに保存し、IAMロールを使用してそのバケットにアクセスします。 詳細については、こちらをご覧ください- https://aws.amazon.com/blogs/security/using-iam-roles-to-distribute-non-aws-credentials-to-your-ec2-instances/