(レポート) SEC308: クラウド内セキュリティ論争 #reinvent

2015.10.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

スピーカー

IMGP1412 copy

Joshua Du Lac, Senior Security Consultant , Amazon Web Services
Don Bailey, Principal Security Engineer , Amazon Web Services

AWSでのセキュリティ

方針は以下の通り。

  • 何を守る必要があるのかを知ること
  • 何がおきているのか、何が変更されたのかをAPIを通じて知ること
  • 検知して通知する機構を作ること
  • 同じプラットフォームで解析、対応ができること

Cloudtrail

JSON形式で記録されるAPI操作ログ。
どのAPIを、いつ、だれが、どのように操作したかが記録される

何が起きているのかを記録できるようになる

CloudWatch Logs

EC2やCloudTrailだけでなく色々なソースから送られたログを監視、蓄積、閲覧ができる
特定のフレーズでアラートを上げることも可能

起きたことを検知して通知できるようになる

CloudTrailで起きたイベントを検知して、通知する環境は以下のCloudFormationテンプレートで設定可能
Using an AWS CloudFormation Template to Create CloudWatch Alarms

テンプレート内には、以下の様記述が複数されている。
FilterPatternに検知したいイベントを設定してフィルタを作成し、フィルタに対してアラームを設定するというのが繰り返されているだけ。

      "CloudTrailChangesMetricFilter": {
          "Type": "AWS::Logs::MetricFilter",
          "Properties": {
              "LogGroupName": { "Ref" : "LogGroupName" },
              "FilterPattern": "{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }",
              "MetricTransformations": [
                  {
                      "MetricNamespace": "CloudTrailMetrics",
                      "MetricName": "CloudTrailEventCount",
                      "MetricValue": "1"
                  }
              ]
          }
      },
      "CloudTrailChangesAlarm": {
          "Type": "AWS::CloudWatch::Alarm",
          "Properties": {
              "AlarmName" : "CloudTrailChanges",
              "AlarmDescription" : "Alarms when an API call is made to create, update or delete a CloudTrail trail, or to start or stop logging to a trail.",
              "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
              "MetricName" : "CloudTrailEventCount",
              "Namespace" : "CloudTrailMetrics",
              "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
              "EvaluationPeriods" : "1",
              "Period" : "300",
              "Statistic" : "Sum",
              "Threshold" : "1"
          }
      }

Multi-Factor Authentication(MFA)

AWSのサービスにアクセスする際にユニークな認証コードを要求する
MFAデバイスには物理デバイスと仮想デバイスが存在する

MFAが無効された時に通知が来るようにDeactivateMFADeviceイベントを通知するようにCloudWatchで設定しましょう

"MFADeactivateMetricFilter": {
          "Type": "AWS::Logs::MetricFilter",
          "Properties": {
              "LogGroupName": { "Ref" : "LogGroupName" },
              "FilterPattern": "{ ($.eventName = DeactivateMFADevice) }",
              "MetricTransformations": [
                  {
                      "MetricNamespace": "CloudTrailMetrics",
                      "MetricName": "MFADeactivateEventCount",
                      "MetricValue": "1"
                  }
              ]
          }
      },

      アラート設定省略

S3バージョニング

S3にアップロードされたファイルのバージョニング管理ができる
S3ロギングと組み合わせることで、ファイルの削除を検知し、削除されたファイルを復元可能

ObjectRemovedイベントを監視して通知する設定を入れましょう

そもそもS3上のファイル削除を防ぐために、権限の確認やMFAの設定をしましょう

不審なログイン

特定のIPからしかログインされないAWS環境の場合は特定IP以外のアクセスを検知し、通知する設定を入れましょう

"MFADeactivateMetricFilter": {
          "Type": "AWS::Logs::MetricFilter",
          "Properties": {
              "LogGroupName": { "Ref" : "LogGroupName" },
              "FilterPattern": "{ ($.eventName = ConsoleLogin) && ($.sourceIPAddress != 55.55.*) }",
              "MetricTransformations": [
                  {
                      "MetricNamespace": "CloudTrailMetrics",
                      "MetricName": "MFADeactivateEventCount",
                      "MetricValue": "1"
                  }
              ]
          }
      },

      アラート設定省略

特定IPからのみアクセスできるようにIAMの設定を入れても良い

"Condition" : {
          "IpAddress" : {
             "aws:SourceIp" : "55.55.0.0/16"
          }
}

AWS Config

AWSリソース構成、設定の履歴、設定変更通知が出来るすごい子
Security geeks should LOVE it!(原文ママ)

開放されたセキュリティグループ

HTTPやHTTPSなど不特定多数にむけたポート以外を不用意に0.0.0.0/0にしていませんか
実際にかなりの数設定されています

AWS Configで変更された際に来る通知をフィルタして検知

  • 「SecurityGroup」と「Created」がタイトルにある
  • changeType:"CREATE"が本文にある
  • resourceType:"AWS::EC2::SecurityGroup"が本文にある

上記のような通知をフィルタする

0.0.0.0/0が設定されているセキュリティグループが作成された際の対処

  • どのインスタンスにも割り当てられていなければ削除
  • インスタンスに割り当てられていたら、別のセキュリティグループを割り当ててから削除
  • デフォルトセキュリティグループは削除できないので、ルールを修正するか、全てのルールを消す

不適切なAMI使用

使用を想定したAMI以外が起動された際の対処
AMIのホワイトリストを作成して、起動されたAMIと比較しましょう

どうやって比較する?
Lambdaをつかいましょう!!
イベントが起きた時に起動する仕組みを構築できます

matchingRecords,

function(record, complete) {
    var params = {
        InstanceIds: []
    };
    // List each Instance ID
    for (var i = 0; i < record.responseElements.instanceSet.items.length; i++){
        params.InstanceIds.push(record.responseElements.instanceSet.items[i].instanceId);
    }

    // terminate the enumerated instances
    ec2.terminateInstances(param, complete);

CloudTrailで誰が起動したか、何処からのアクセスか、どのサブネットで起動したかを確認しましょう

IAMで構築できるAMIを絞ることも出来ます

Automated IR(Incident Response)

上記のような対策を出来るだけ自動化しちゃいませんか?
Lambdaを使えば出来るよ!

http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/wt-cloudtrail-events-adminuser-prepare.html

var aws  = require('aws-sdk');
var zlib = require('zlib');
var async = require('async');

var EVENT_SOURCE_TO_TRACK = /sns.amazonaws.com/; // 追っかけるサービス 
var EVENT_NAME_TO_TRACK   = /CreateTopic/; // 追っかけるイベント
var DEFAULT_SNS_REGION  = 'us-west-2'; // リージョン
var SNS_TOPIC_ARN       = 'SNS Topic ARN'; // 通知するSNSトピック

var s3 = new aws.S3();
var sns = new aws.SNS({
    apiVersion: '2010-03-31',
    region: DEFAULT_SNS_REGION
});

exports.handler = function(event, context) {
    var srcBucket = event.Records[0].s3.bucket.name;
    var srcKey = event.Records[0].s3.object.key;

    async.waterfall([
        function fetchLogFromS3(next){
            console.log('Fetching compressed log from S3...');
            s3.getObject({
               Bucket: srcBucket,
               Key: srcKey
            },
            next);
        },
        function uncompressLog(response, next){
            console.log("Uncompressing log...");
            zlib.gunzip(response.Body, next);
        },
        function publishNotifications(jsonBuffer, next) {
            console.log('Filtering log...');
            var json = jsonBuffer.toString();
            console.log('CloudTrail JSON from S3:', json);
            var records;
            try {
                records = JSON.parse(json);
            } catch (err) {
                next('Unable to parse CloudTrail JSON: ' + err);
                return;
            }

            // イベント検知
            var matchingRecords = records
                .Records
                .filter(function(record) {
                    return record.eventSource.match(EVENT_SOURCE_TO_TRACK)
                        && record.eventName.match(EVENT_NAME_TO_TRACK);
                });

            // イベントを受けての対応
            console.log('Publishing ' + matchingRecords.length + ' notification(s) in parallel...');
            async.each(
                matchingRecords,
                function(record, publishComplete) {
                    console.log('Publishing notification: ', record);
                    sns.publish({
                        Message:
                            'Alert... SNS topic created: \n TopicARN=' + record.responseElements.topicArn + '\n\n' + 
                            JSON.stringify(record),
                        TopicArn: SNS_TOPIC_ARN
                    }, publishComplete);
                },
                next
            );
        }
    ], function (err) {
        if (err) {
            console.error('Failed to publish notifications: ', err);
        } else {
            console.log('Successfully published all notifications.');
        }
        context.done(err);
    });
};

上記のような「Lambda Responder」を作成する

_SEC308__Wrangling_Security_Events_In_The_Cloud

http://aws.amazon.com/jp/blogs/compute/fanout-s3-event-notifications-to-multiple-endpoints/

ConfigからLambdaも行けるように?
Config Rulesが出てIR aaSが加速!

最後に

CloudTrailやConfigを有効化しても活用できている方はそんなに多くないかと思います。
Automated IRという考え方はめっちゃテンションが上りました。

日本に帰ったらいろいろ検証してみます。

スライド

公開されていたので是非。
分量もあり非常に面白いセッションです。