Wednesday, January 30, 2019

How to have AWS Config send an SNS notification if a VPC's allows unrestricted incoming SSH traffic.


This is to have AWS Config send an SNS notification if a VPC's allow unrestricted incoming SSH traffic.


General Overview:

In order to configure a region to start recording AWS Config, you need to enable it.  If you have many accounts and every account at this point has 15 regions, that's alot of work on GUI, so we will
do most using CLI.  
Steps:
  1. Configure an S3 bucket to hold all the awsconfig data.
  2. Configure SNS Topic for this in each region
  3. Create an IAM Role for AWS Config to send to S3/SNS/Get the data
  4. Enable aws config per account in each region.
  5. Create an Aggregator in the main account to receive all the data from all the other accounts/regions
  6. Authorize this above aggregator in each and ever account/region
  7. Test that it works.

S3:

  1. We need to create a S3 bucket to hold all these configurations.  Since S3 is a single name across all AWS, I created a bucket called awsconfig-bucket in one account and allowed all the other accounts to write to it.  
    1. we need to allow all the other accounts to write to the bucket
    2. You can get the canonical account ID by doing this:  
      | => aws s3api list-buckets --profile xxx | grep OWNER
      OWNER XXX-XXXX 8d1da5691369aa323454339960db71b048b21de4db6f6b8b698e83df0c27129b4

    3. Next, we need the bucket policy set on the S3 bucket, For a bucket to receive log files from multiple accounts, (ref: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-set-bucket-policy-for-multiple-accounts.html ) otherwise you will get an error like: 
      An error occurred (InsufficientDeliveryPolicyException) when calling the PutDeliveryChannel operation: Insufficient delivery policy to s3 bucket

We'll put this policy in, inline or call it something:

  1. {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AWSCloudTrailAclCheck20131101",
          "Effect": "Allow",
          "Principal": {
            "Service": "config.amazonaws.com"
          },
          "Action": "s3:GetBucketAcl",
          "Resource": "arn:aws:s3:::awsconfig-bucket"
        },
        {
          "Sid": "AWSCloudTrailWrite20131101",
          "Effect": "Allow",
          "Principal": {
            "Service": "config.amazonaws.com"
          },
          "Action": "s3:PutObject",
          "Resource": [
            "arn:aws:s3:::awsconfig-bucket/AWSLogs/xxxxxxx/*",
            "arn:aws:s3:::awsconfig-bucket/AWSLogs/xxxxxxx/*",
            "arn:aws:s3:::awsconfig-bucket/AWSLogs/xxxxxxx/*" 
          ],
          "Condition": {
            "StringEquals": {
              "s3:x-amz-acl": "bucket-owner-full-control"
            }
          }
        }
      ]
    }
  2. AWS CONFIG


    1. the command to enable awsconfig is like this:
      aws configservice subscribe --s3-bucket awsconfig-bucket --sns-topic arn:aws:sns:us-west-2:xxxxxxxxxxx:awsconfig --iam-role arn:aws:iam::xxxxxx:role/aws_config_s3_role --profile xxxxxx --region us-west-2
      Therefore we have to enable all the components in the command, i.e SNS and S3 and configure the IAM role:

      SNS: 

      You have to have an SNS topic, otherwise it gives you an error.  So we create "dummy" SNS topics just for the command to work:
      for z in `cat list_of_regions.txt` ; do echo "aws sns create-topic --name awsconfig --profile `echo $PROFILE` --region $z"; done

    So we get something like this:

    aws sns create-topic --name awsconfig --profile xxxxxxx --region us-west-2
    Then we need to create this for every region in every account. (using the bash one liner)
  3. IAM: 

    1. Next we create an IAM role per account that grants AWS Config permissions to access the Amazon S3 bucket, access the Amazon SNS topic,  and get configuration details for supported AWS resources.   Lets call this role awsconfig_role We attach 3 policies to this user: AWSConfigRoleAmazonSNSRole (AWS managed policies) and create a policy to write to the S3 bucket:

| => cat s3_policy.json 
{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "VisualEditor0",

            "Effect": "Allow",

            "Action": "s3:*",

            "Resource": [

                "arn:aws:s3:::awsconfig-bucket",

                "arn:aws:s3:::*/*"

            ]

        }

    ]

}

Also in the trust relationship, we add this policy in JSON:
| => cat trust_relationship_awsconfig.json 
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "config.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

This is so that AWSConfig can assume this role to do all its stuff.
We can do this in this CLI:
aws iam create-role --role-name awsconfig_role --assume-role-policy-document file://trust_relationship_awsconfig.json --profile XXXX
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AWSConfigRole --role-name awsconfig_role --profile XXXX
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AmazonSNSRole --role-name awsconfig_role --profile XXXX
aws iam put-role-policy --role-name awsconfig_role --policy-name S3_AWSCONFIG_BUCKET --policy-document file://s3_policy.json --profile XXXX
so now we use the same configuration to create this role in all 23 accounts.
for z in `cat list_of_accounts.txt` ; do echo "aws iam create-role --role-name awsconfig_role --assume-role-policy-document file://trust_relationship_awsconfig.json --profile $z"; done
for z in `cat list_of_accounts.txt` ; do echo "aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AWSConfigRole --role-name awsconfig_role --profile $z"; done
for z in `cat list_of_accounts.txt` ; do echo "aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AmazonSNSRole --role-name awsconfig_role --profile $z"; done
for z in `cat list_of_accounts.txt` ; do echo "aws iam put-role-policy --role-name awsconfig_role --policy-name S3_AWSCONFIG_BUCKET --policy-document file://s3_policy.json --profile $z"; done

AGGREGATOR

5. Next we need to create an aggregator in the main account for all the accounts and all regions. ( we do this now so it sends authorizations to all accounts/regions)
aws configservice put-configuration-aggregator --configuration-aggregator-name XXXX_ALL --account-aggregation-sources "[{\"AccountIds\": [\"123456789\",\"12343333333\",\"AccountID3\"],\"AllAwsRegions\": true}]" 
(you can put all the accountID's you need, I put all of them)
You can check that this worked by doing this:  
| => aws configservice describe-configuration-aggregators
CONFIGURATIONAGGREGATORS arn:aws:config:us-east-1:12344555445:config-aggregator/config-aggregator-aphkgdyd XXXX_ALL 1546544013.02 1547232995.08
ACCOUNTAGGREGATIONSOURCES True
ACCOUNTIDS 123456789112
ACCOUNTIDS 123456789113
ACCOUNTIDS 123456789114
ACCOUNTIDS 123456789115
ACCOUNTIDS 123456789116
ACCOUNTIDS 123456789117
... there rest of the accounts came here, I cut them out for the purpose of this page.

6. Finally, after adding all the source accounts, authorizations are sent everywhere (all regions of every account) so we need to authorize all of them:
This is what it looks like from the GUI (however we don't want to log into ALL accounts * 16 regions, hundreds of times to do this !) 

We do this with CLI:
This is for example to authorize the region of us-east-1 in the account of 12344555445
aws configservice put-aggregation-authorization --authorized-account-id 12344555445 --authorized-aws-region us-east-1 --profile 12344555445 --region us-east-1