How to securely create an AWS Account for personal use

Posted by Ben Potter on Tuesday, January 26, 2021

Contents

What it takes to secure an AWS account

When creating an Amazon Web Services (AWS) account it’s important to do it right, and follow the latest best practices especially from AWS Well-Architected Security Pillar. In the tutorial featured in the YouTube video, you will learn how to create a new AWS account from the start, and: Secure with multi-factor authentication (MFA) using a YubiKey Enable AWS Organizations to create and manage accounts Configure AWS Single Sign-On (SSO) for securely access your accounts - (IAM users, groups and access keys are no longer recommended) Configure service control policies (SCP’s) in AWS Organizations to block the use of unused regions, and baseline actions Configure Amazon GuardDuty with email alerts Configure AWS CloudTrail centrally Signing on as AWS SSO user with MFA, and generating temporary credentials (access key) for use if you really need them, reducing the risk if you accidentally put them somewhere (like GitHub).

The reason this tutorial is for personal use is that some trade-offs have been made in to reduce the cost and complexity, for example if it was more than yourself accessing the account you would want to have a separate account just for logs that no one can tamper with. You would also want to enable the Security Hub service to automatically detect misconfigurations.

Video Tutorial

Code for Video Tutorial

The following code is required as referenced by the video tutorial.

Setup a CloudWatch event for GuardDuty findings

In the tutorial after creating the SNS topic and email subscription, you need to setup a CloudWatch event for GuardDuty to trigger, that sends the email.

  1. Open the CloudWatch console at https://console.aws.amazon.com/cloudwatch/
  2. Select Rules from the navigation pane and then Create Rule.
  3. From the Service Name menu, choose GuardDuty.
  4. From the Event Type menu, choose GuardDuty Finding.
  5. In Event Pattern Preview choose Edit.
  6. Paste the below JSON code into Event Pattern Preview and choose Save. Note this example will alert for any Medium to High findings.
{
  "source": [
    "aws.guardduty"
  ],
  "detail-type": [
    "GuardDuty Finding"
  ],
  "detail": {
    "severity": [
      4,
      4.0,
      4.1,
      4.2,
      4.3,
      4.4,
      4.5,
      4.6,
      4.7,
      4.8,
      4.9,
      5,
      5.0,
      5.1,
      5.2,
      5.3,
      5.4,
      5.5,
      5.6,
      5.7,
      5.8,
      5.9,
      6,
      6.0,
      6.1,
      6.2,
      6.3,
      6.4,
      6.5,
      6.6,
      6.7,
      6.8,
      6.9,
      7,
      7.0,
      7.1,
      7.2,
      7.3,
      7.4,
      7.5,
      7.6,
      7.7,
      7.8,
      7.9,
      8,
      8.0,
      8.1,
      8.2,
      8.3,
      8.4,
      8.5,
      8.6,
      8.7,
      8.8,
      8.9
    ]
  }
}
  1. In the Targets section click Add Target.

  2. From the Select Targets menu, choose SNS Topic.

  3. For Select Topic select the name of the SNS Topic you created in Step 1.

  4. Configure the input for the event.

  5. Expand Configure input and then choose Input Transformer.

  6. Copy the following code and paste it into the Input Path field.


{
    "severity": "$.detail.severity",
    "Account_ID": "$.detail.accountId",
    "Finding_ID": "$.detail.id",
    "Finding_Type": "$.detail.type",
    "region": "$.region",
    "Finding_description": "$.detail.description"
}
                            
  1. Copy the following code and paste it into the Input Template field to format the email.
"AWS <Account_ID> has a severity <severity> GuardDuty finding type <Finding_Type> in the <region> region."
"Finding Description:"
"<Finding_description>. "
"For more details open the GuardDuty console at https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?search=id=<Finding_ID>"
  1. Click Configure Details.
  2. In the Configure rule details page, enter a Name and Description for the rule, and then choose Create Rule.

If you would prefer to create a Slack notification instead of email, the tutorial is available in the GuardDuty documentation.

Organizations Service Control Policies (SCP’s)

In the tutorial there is an SCP as an example guardrail baseline, and another for blocking unused regions. The region example allows global services, and both the us-east-1 (N Virginia) and ap-southeast-2 (Sydney) regions, you can modify to your closeset region, or simply use only us-east-1.

Baseline: Copy the following example into the policy replacing the example:

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyRootUser",
			"Effect": "Deny",
			"Action": "*",
			"Resource": "*",
			"Condition": {
				"StringLike": {
					"aws:PrincipalArn": "arn:aws:iam::*:root"
				}
			}
		},
		{
			"Sid": "DenyLeavingOrganization",
			"Effect": "Deny",
			"Action": [
				"organizations:LeaveOrganization"
			],
			"Resource": "*"
		},
		{
			"Sid": "DenyIAMCreateUser",
			"Effect": "Deny",
			"Action": [
				"iam:CreateAccessKey",
				"iam:CreateUser"
			],
			"Resource": "*"
		},
		{
			"Sid": "DenyGuardDutyMods",
			"Effect": "Deny",
			"Action": [
				"guardduty:DeleteDetector",
				"guardduty:DisassociateFromMasterAccount",
				"guardduty:UpdateDetector",
				"guardduty:CreateFilter",
				"guardduty:CreateIPSet"
			],
			"Resource": "*"
		},
		{
			"Sid": "DenyGuardDutyNotificationMods",
			"Effect": "Deny",
			"Action": [
				"events:DeleteRule",
				"events:DisableRule",
				"events:RemoveTargets"
			],
			"Resource": "arn:aws:events:*:*:rule/default/GuardDuty"
		}
	]
}

Region: Copy the following example into the policy replacing the example:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyRegionsExceptForConditionsAndListedGlobalServices",
            "Effect": "Deny",
            "NotAction": [
                "a4b:*",
                "acm:*",
                "aws-marketplace-management:*",
                "aws-marketplace:*",
                "aws-portal:*",
                "awsbillingconsole:*",
                "budgets:*",
                "ce:*",
                "chime:*",
                "cloudfront:*",
                "config:*",
                "cur:*",
                "directconnect:*",
                "ec2:DescribeRegions",
                "ec2:DescribeTransitGateways",
                "ec2:DescribeVpnGateways",
                "fms:*",
                "globalaccelerator:*",
                "health:*",
                "iam:*",
                "importexport:*",
                "kms:*",
                "mobileanalytics:*",
                "networkmanager:*",
                "organizations:*",
                "pricing:*",
                "route53:*",
                "route53domains:*",
                "s3:GetAccountPublic*",
                "s3:ListAllMyBuckets",
                "s3:PutAccountPublic*",
                "shield:*",
                "sts:*",
                "support:*",
                "trustedadvisor:*",
                "waf-regional:*",
                "waf:*",
                "wafv2:*",
                "wellarchitected:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:RequestedRegion": [
                        "us-east-1",
                        "ap-southeast-2"
                    ]
                }
            }
        }
    ]
}

Further reading: AWS Well-Architected Security Pillar