Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

EC2でアプリケーションシークレットを管理する方法

アプリケーションをEC2にデプロイするときは、自動スケーリンググループを使用することをお勧めします。自動スケーリンググループを使用すると、手動で介入することなく、アプリケーションをスケールアップおよびスケールダウンして需要に対応したり、障害が発生したインスタンスから回復したりできます。ただし、それらを機能させるには、起動が終了した後、すべてのインスタンスがライブトラフィックを処理する準備が整っていることを確認してください。新しいサーバーで変更を加えたり、準備が整う前にcapistranoを介して初期デプロイを行ったりすることに慣れている場合は、アプリをサーバーにデプロイするよりも少し手間がかかります。

たとえば、Railsを使用して構築されたユーザー向けのWebアプリケーションがあります。起動が完了すると、各インスタンスでRailsを準備し、ロードバランサーによって転送されたリクエストに応答するのを待つ必要があります。これを実現するには、最初にカスタムを作成しました。 AMIは、アプリやnginxなどでAnsibleを介してプロビジョニングされたインスタンスのスナップショットを取得します。次に、capistranoがデプロイに対して行うことをコピーするスクリプトを呼び出すuserdataを使用して自動スケーリンググループを構成しました。これは、gitから最新のコードを取得し、bundlerを実行します。 on。アプリとそのすべての依存関係が整ったら、何が残っているのでしょうか?

アプリケーションの秘密:デプロイヤーの悩み

アプリケーションシークレットには課題があります。公開できる場所(たとえば、gitレポジトリなど)に保存されないようにする必要がありますが、実行時にアプリで使用できるようにする必要があります。また、自動スケーリングにより、必要なときにアプリに配置するために人間がそこにいることを信頼することはできません。

この問題に対する1つの答えは、HashicorpによるVaultです。これは、アプリが秘密を必要とするまで秘密を秘密にしておくというこの問題を解決するために特別に作成された素晴らしいソフトウェアです。ただし、欠点は、Vaultをプロビジョニングして管理する必要があることです。これは、実行を継続する必要があるもう1つのサービスです。

もう1つのオプションは、シークレットを共有ストレージ(S3、当然)に保存し、インスタンスのみがそのバケットやキーにアクセスできるようにすることです。これは、制限されたS3リソースへのアクセスを許可するポリシーを追加できるIAMロールを使用して実行できます。ただし、S3でこれらすべてのシークレットをプレーンテキストで保存すると、不要な露出が発生する可能性があります。そのバケットまたは全世界にアクセスできる他のユーザーがそのデータを誤って利用できるようにする可能性があります。

素敵じゃないかS3を保存する前に秘密を暗号化し、必要なときにアプリに読み込んで復号化できたら素晴らしいと思いませんか?

秘密の材料:Amazonの鍵管理サービス

Amazonのキー管理サービス(KMS)は、暗号化キーと対話するためのAPIを提供します。 IAMロールおよびtheAws::S3 ::Encryptionモジュールと組み合わせると、S3で暗号化されたまま、シークレットをアプリケーションにロードするのに数行のコードしか必要ありません。

掘り下げる前に、秘密を保存するためにKMSとS3を使用して素晴らしい投稿を書いたDonMillsに感謝する必要があります。 S3のシークレットと一緒にキー情報を保存するのではなく、IAMの役割に依存し、KMSキーを個別に追跡することで、彼のアプローチを少し変更しました。

KMSは、データの暗号化と復号化に使用できるマスター暗号化キーを生成してアクセスを提供します。何かを暗号化するように依頼すると、KMSはマスターキーに基づいて一時キーを渡し、その一時キーは暗号化または復号化に使用できます。

キーを生成するには、IAMコンソールに移動し、[暗号化キー]リンクを選択します。キーを作成するときに、このキーを使用できるIAMユーザーまたはロールを指定するように求められます。自動スケーリンググループの一部となるEC2インスタンスに割り当てられるロールを選択します。キーのARNに注意してください。後で使用します。

ルーの作成:KMSとIAMの同等のパーツ

キーを作成したら、IAMコンソールを使用して、選択したIAMロールを編集します。次のようなポリシーを添付して、シークレットが保存されるバケットへのアクセスを許可します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1476277816000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:HeadObject"
            ],
            "Resource": [
                "arn:aws:s3:::yourbucket/secrets.yml"
            ]
        }
    ]
}

キーを設定し、ポリシーをロールにアタッチすると、Aws ::S3 ::Encryption ::Clientインスタンスを介してKMSおよびS3とやり取りできるようになります。シークレットファイルを取得し、そのコンテンツを環境変数にロードするサンプルコードを次に示します。

begin
  es3 = Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID'])
  YAML.load(es3.get_object(bucket: "yourbucket", key: "secrets.yml").body.read).each do |k, v|
    ENV[k] ||= v # Don't override local ENV settings
  end
rescue ArgumentError
  # Raised when no KMS_KEY_ID was found in ENV, so there's nothing to do
rescue Aws::S3::Errors::NoSuchKey
  # No secrets file was found, so there's nothing to do
end

まず、KMSキーのIDを使用して新しいオブジェクトをインスタンス化します。キーのARN(キーを作成したときにIAMコンソールに表示された)は、KMS_KEY_ID環境変数に格納されます。ここでkeyIDをコンストラクターに渡すと、一時的な復号化キーのフェッチが処理されます。 KMSとの通信に使用しているものとは別のクレデンシャルのセットを使用してS3と通信する場合は、ここでオプションとしてAws ::S3::Clientインスタンスを指定できます。ただし、以前にIAMロールを設定した場合は、その必要はありません。Aws::S3 ::Encryption ::Clientは、IAMロールによって提供された資格情報を使用して新しいAws ::S3::Clientインスタンスを作成するためです。

暗号化されたS3クライアントの準備ができたら、#get_objectを使用してS3からデータをフェッチし、KMSが提供するキーを使用してデータを復号化します。データを取得したら、それを使ってやりたいことができます。データはYAMLであるため、アプリケーションコードで使用できるように、キーと値のペアをENVにロードして詰め込みます。

このコードをRailsアプリケーションの初期化ファイルにドロップすれば、準備は完了です。さて、あなたがあなたの秘密をS3に保存したら、それはそうです。 :)適切なIAMロールで実行されているインスタンスにIRBコンソールがあるとすると、次のようにしてシークレットを保存できます:

# Encrypt the data from /path/to/secrets.yml and store it on S3
Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID']).
  put_object(bucket: "yourbucket", key: "secrets.yml", body: File.read("/path/to/secrets.yml"))
すぐにサービスを提供

これで、シークレットを暗号化したまま、自動スケーリンググループに追加される新しいインスタンスで常にシークレットを使用できるようになります。誰もが勝ちます! :)


  1. Amazon EC2インスタンスのセキュリティグループを管理する方法は?

    セキュリティグループは、AmazonEC2インスタンスのセキュリティにおいて重要な役割を果たします。セキュリティグループは、インスタンスへの着信接続と発信接続を制御する責任があります。これらは基本的に、すべてのEC2インスタンスの仮想ファイアウォールとして機能します。 EC2インスタンスを起動するときに、セキュリティグループを指定するように求められます。そうしない場合は、デフォルトのセキュリティグループが使用されます。インスタンスを起動すると、それに関連付けられているセキュリティグループを簡単に変更できます。 セキュリティグループは、実際にはネットワークインターフェイスに関連付けられています

  2. RailsアプリケーションでOmniAuth-Twitterを使用する方法

    このチュートリアルでは、アプリケーションのユーザーがTwitterアカウントを使用してログインできるようにする方法を学習します。これを行うには、OAuthなどのツールを使用すると簡単になります。 OmniAuthのTwitter戦略を含むOmniAuth-Twitterを利用します。 飛び込みましょう! はじめに Railsアプリケーションを生成することから始めます。ターミナルから、コマンドを実行して実行します。 rails new Tuts-Social -T Gemfileを開き、ブートストラップgemを追加します。 #Gemfile...gem bootstra