aws re:invent 2016: workshop: adhere to the principle of least privilege by using aws identity and...
TRANSCRIPT
© 2016, Amazon Web Services, Inc. or its Affiliates. All rights reserved.
November 29, 2016
SEC302
Workshop: Adhering to Least-Privilege Principles
Becky Weiss, Senior Principal Engineer, AWS
virtual private cloud
S3 bucket DynamoDB
table
SQS queue Amazon
Kinesis
stream
Application Load
Balancer
Amazon
Redshift cluster
RDS databaseEC2 instances
ECS tasks
Principle of Least Privilege: Definition
“In information security, computer science, and other fields,
the principle of least privilege requires that in a particular
abstraction layer of a computing environment, every
module must be able to access only the information and
resources that are necessary for its legitimate purpose.”
(Wikipedia)
Auditing, Monitoring and Troubleshooting
AWS
CloudTrail
Amazon
CloudWatch Events
and
CloudWatch Logs
AWS
Lambda
What to Expect from the Session
Hands-on practice working with IAM and Amazon VPC
• Techniques for scoping access and connectivity:
allowing exactly what you need.
• Techniques for debugging, auditing, and alarming.
Prerequisites
You will get the most out of this session if you:
• Have some experience with AWS
• Have an AWS account with a working, installed AWS CLI
• Know how to SSH to a Linux host
• Have some basic programming experience (examples
will be in JavaScript)
Handouts
Handouts zip file:
https://s3.amazonaws.com/awsiammedia/public/sample/Le
astPrivilegeWorkshopreInvent/SEC302_handouts.zip
Download and unzip it on your machine
Meet your neighbors!
Look to your left, look to your right…
Introduce yourself!
You’ll be working with your neighbor later in this workshop.
Installing the CLI
OS-specific instructions:
http://docs.aws.amazon.com/cli/latest/userguide/installing.h
tml
Test it:
C:\Users\becky>aws --version
aws-cli/1.10.65 Python/2.7.9 Windows/7 botocore/1.4.55
Configuring the CLI
http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-
getting-started.html
Note: We will be using the us-west-2 region (Oregon) for
this workshop.
I actually could have shown
you these, since I later deleted
the user.
BUT: These are long-term
security credentials. Don’t
share or post them anywhere.
Configuring an IAM User Profile in the CLI
C:\Users\becky>aws configure --profile sec302demo
AWS Access Key ID [None]: AKIA*************
AWS Secret Access Key [None]: ***************************
Default region name [None]: us-west-2
Default output format [None]: json Use the credentials you
were given.
Use the CLI as Sec302DemoUser
C:\Users\becky>aws ec2 describe-vpcs --profile sec302demo
An error occurred (UnauthorizedOperation) when calling the DescribeVpcs operation: You are not authorized to perform this operation.
Handy filter
Attach it
IAM managed policies:
Predefined sets of
commonly-used policies.
You can also write your
own (and we will)
Test Access
> aws ec2 describe-vpcs --profile sec302demo{
"Vpcs": [
{
"VpcId": "vpc-c6a649a1",
"InstanceTenancy": "default",
"State": "available",
"DhcpOptionsId": "dopt-e4650b80",
"CidrBlock": "172.31.0.0/16",
"IsDefault": true
}
]
}
Create an EC2 Key Pair For SSH Access
If you already have an SSH
key:
aws ec2 import-key-pair `
--profile sec302demo `
--key-name Sec302DemoSSH `
--public-key-material file://c:\temp\Sec302DemoPub.txt
To create a new SSH key:
aws ec2 create-key-pair `
--profile sec302demo `
--key-name Sec302DemoSSH
And save the KeyMaterial from the
response
The VPC You Just Created
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0
The Application You Just Launched
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0
Launch an EC2 Instance
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0
SSH security group
Cheat sheet: Launch an EC2 instance
Handout: run_instances_cheat_sheet.txt
> aws ec2 run-instances --profile sec302demo
>> --image-id ami-7172b611
>> --instance-type t2.nano
>> --subnet-id $YOUR_SUBNET_ID
>> --security-group-ids $YOUR_SECURITY_GROUP_ID
>> --key-name Sec302DemoSSH
Resources created by the
SEC302 CloudFormation stack
Verify SSH Access
Test your ssh access, e.g.:
putty.exe -i c:\temp\Sec302DemoPriv.ppk [email protected]
You can now terminate this EC2 instance. We won’t need
it again.
Create an IAM Role for an EC2 Instance
Catchup CloudFormation template handout: ec2_instance_in_iam_role_template.json
This will allow Amazon EC2 to
launch EC2 instances into this
IAM role.
Create an IAM Role for an EC2 Instance
Catchup CloudFormation template handout: ec2_instance_in_iam_role_template.json
Policy for the IAM Role: S3 Read-Only Access
Catchup CloudFormation template handout: ec2_instance_in_iam_role_template.json
Anatomy of an IAM Role
ARN for referring to it later
For use by EC2
Right now, permits all ReadOnly operations in S3.
(We’ll make this more restrictive later.)
Catchup CloudFormation template handout: ec2_instance_in_iam_role_template.json
Launch an EC2 instance
Launching with IAM role:
This EC2 Instance will have S3
ReadOnly permissions
Catchup CloudFormation template handout: ec2_instance_in_iam_role_template.json
Attempt Actions From the EC2 Instance
SSH to your EC2 instance, and from there, try some actions:
# Tell the CLI your default regionaws configure set default.region us-west-2
# This should workaws s3 ls
# This should failaws s3 mb s3://this-will-fail
# This should failaws ec2 describe-instances
Where Are the Credentials?
There are credentials, but:
• They are completely hands-off: You don’t touch them.
• They are temporary and will expire; IAM will automatically rotate
them
To see them:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/Sec302EC2Role; echo
EC2 Instance Metadata Service
Your role name
Making IAM Policy More Restrictive
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive:
Choosing Specific Actions
Only the s3.GetObject action is
allowed
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive:
Choosing Specific Actions
“*” means permission to s3.GetObject on
all S3 objects
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive:
Delete the Old Policy
Detach this managed policy:
We’re going to write our own
Making IAM Policy More Restrictive:
Choosing Specific Actions
Our policy so far:
{ "Version": "2012-10-17", "Statement": [
{ "Sid": "Stmt1474248983000","Effect": "Allow", "Action": [ "s3:GetObject“ ],"Resource": [ "*" ]
}]
}
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Attempt Actions From the EC2 Instance
SSH to your EC2 instance, and from there, try some actions:
# This should fail
aws s3 ls
# This should work: It is s3.GetObject
aws s3 cps3://awsiammedia/public/sample/LeastPrivilegeWorkshopreInvent/SEC302_handouts.zip .
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive:
IAM Resource-Level Policies
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive:
IAM Resource-Level Policies
In English: s3.ListBucket is allowed, only on the specified bucket, only when the prefix matches the
given pattern.
{
"Version": "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action": [ "s3:ListBucket" ],
"Condition" : {
"StringLike": {
"s3:prefix": "AWSLogs/111122223333/CloudTrail/*"
}
},
"Resource": [ "arn:aws:s3:::your-cloudtrail-bucket-name-here" ]
} ]
}
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Use your own bucket name
Use your own account ID
Testing the ListBuckets Policy
SSH to your EC2 instance and try it:
[ec2-user@ip-10-0-2-49 ~]$ aws s3 ls s3://$YOUR_CLOUDTRAIL_BUCKET/AWSLogs/$YOUR_ACCOUNT_ID/CloudTrail/us-west-2/2016/11/29/
2016-11-29 16:28:41 1213 778340376510_CloudTrail_us-west-2_20161001T1625Z_k5gzl4muOxohMXeM.json.gz
2016-11-29 16:38:33 2311 778340376510_CloudTrail_us-west-2_20161001T1630Z_50SqQyuABVqP5igQ.json.gz
2016-11-29 16:33:22 1881 778340376510_CloudTrail_us-west-2_20161001T1630Z_m5PVy8DKqjCtq9pF.json.gz
…Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Making IAM Policy More Restrictive:
IAM Resource-Level Policies
In English: s3.GetObject is allowed, only on objects matching the given pattern.
Add this statement to your policy, inside Statement[]:
{ "Effect": "Allow", "Action": [ "s3:GetObject“ ],"Resource": [
"arn:aws:s3:::<YOUR_CLOUDTRAIL_BUCKET>/AWSLogs/<YOUR_ACCOUNT_ID>/CloudTrail/*" ]}
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Use your own bucket name
and account ID
Testing the GetObject Policy
[ec2-user@ip-10-0-2-49 ~]$ aws s3 cp s3://becky-20161001-cloudtrail/AWSLogs/778340376510/CloudTrail/us-west-2/2016/10/01/778340376510_CloudTrail_us-west-2_20161001T1630Z_m5PVy8DKqjCtq9pF.json.gz .
download: s3://becky-20161001-cloudtrail/AWSLogs/778340376510/CloudTrail/us-west-2/2016/10/01/778340376510_CloudTrail_us-west-2_20161001T1630Z_m5PVy8DKqjCtq9pF.json.gz to ./778340376510_CloudTrail_us-west-2_20161001T1630Z_m5PVy8DKqjCtq9pF.json.gz
Take a minute to unzip this and look at its contents:
# gunzip $CLOUD_TRAIL_FILE.gz# sudo yum -y install jq# jq .Records[0] $CLOUD_TRAIL_FILE
Catchup handout: ec2_instance_in_iam_role_policy_update_template.json
Reference: AWS Services That Work With IAM
Bookmark this page:
http://docs.aws.amazon.com/IAM/latest/UserGuide/referen
ce_aws-services-that-work-with-iam.html
This has pointers to how you can use IAM with each AWS
service.
Grant access to your partner’s account
(or your own, if no partner)
Catchup CloudFormation template handout: iam_role_cross_account_template.json
Permissions for the IAM Role
Choose a managed policy in the creation wizard
Or write your own (inline policies). For example:
{ "Version": "2012-10-17","Statement": [
{ "Effect": "Allow", "Action": [ "ec2:DescribeInstances" ], "Resource": [ "*" ]
} ]
}
Catchup CloudFormation template handout: iam_role_cross_account_template.json
Assuming Your Partner’s IAM Role
> aws sts assume-role --profile sec302demo `
--role-arn arn:aws:iam::111122223333:role/Sec302RoleTestMe `
--role-session-name MyTestSession
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::410436118402:user/sec302demo is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::778340376510:role/Sec302RoleTestMe
Oops! What did we miss?
Your partner’s account
Policy Needed By Sec302DemoUser
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["sts:AssumeRole"],
"Resource": ["arn:aws:iam::<YOUR_PARTNERS_ACCOUNT_ID>:role/Sec302RoleTestMe"]
}
]
}
Catchup CloudFormation template handout: sts_assume_role_policy_template.json
Assuming the IAM Role
C:\Users\becky>aws sts assume-role --profile sec302demo --role-arn arn:aws:iam::778340376510:role/Sec302RoleTestMe --role-session-name MyTestSession{
"AssumedRoleUser": {"AssumedRoleId": "AROAJCO64ENYICVBJQRWM:MyTestSession","Arn": "arn:aws:sts::778340376510:assumed-role/Sec302RoleTestMe/MyTestSe
ssion"},"Credentials": {
"SecretAccessKey": “****","SessionToken": “*****************","Expiration": "2016-09-21T16:57:03Z","AccessKeyId": "ASIA***********"
}}
Temporary credentials: I could have shown them.
They have expired and are useless
Use the Temporary Credentials
> aws configure --profile sec302assumed
AWS Access Key ID [None]: *****
AWS Secret Access Key [None]:*************
Default region name [None]: us-west-2
Default output format [None]: json
> aws configure set aws_session_token*************************** --profile sec302assumed
Try the Temporary Credentials
# Should succeed
aws ec2 describe-instances --profile sec302assumed
# Should fail
aws dynamodb list-tables --profile sec302assumed
More on Permissions for IAM Roles
Permissions for IAM roles should be minimal.
Example yellow flags:
• iam:AssumeRole / iam:PassRole -- If needed, be
specific about the IAM role that this IAM role can
assume
• iam:PutRolePolicy -- Usually only for highly privileged
principals
!
Going Further: IAM Resource-Based Policies
Useful for cross-account access
Supported on some AWS resources, e.g. S3 buckets
Attach policy to the resource itself:
Analogous to access control lists &&
Setting Up the CloudWatch Events Rule
AWS API call via CloudTrail
We will see EC2 API calls
The SEC302 CloudFormation
stack created this.
Catchup CloudFormation handout: cloudwatch_events_aws_api_rule_template.json
Try it: Make EC2 API calls
Make some that succeed
Make some that fail
Get your partner to make some that fail, while
assuming your IAM role
Events Delivered to Your Lambda Function
{ …"detail": {
"eventVersion": "1.05", "userIdentity": {
"type": "AssumedRole", "principalId": "AROAJCO64ENYICVBJQRWM:MyTestSession",
"arn": "arn:aws:sts::410436118402:assumed-role/Sec302RoleTestMe/MyTestSession",
…"eventTime": "2016-09-21T17:03:13Z", "eventSource": "ec2.amazonaws.com", "eventName": "CreateVpc", "awsRegion": "us-west-2","errorCode": "Client.UnauthorizedOperation","errorMessage": "You are not authorized to perform this operation.","requestParameters": { "cidrBlock": "192.168.0.0/16" },…
Someone tried and failed to use
CreateVpc while assuming this role
You Can Do a Lot With These Events
Plenty of details there, including:
• Principal that attempted the call
• API method and request parameters
• Result: Success or error (with detail)
• Response
All of this is also in CloudTrail in S3
But Lambda functions can take actions: Ideas?
Sidebar: IAM Role for the Lambda Function
Managed policy “AWSLambdaBasicExecutionRole”:
Permits writing output to CloudWatch Logs
Sidebar: IAM Role for the Lambda Function
Inline policy “LambdaPublishToSNSTopic”:
Permits publishing to your SNS topic
Sidebar: IAM Role for the Lambda Function
Indicates that AWS Lambda can assume this IAM role
{
"Role": {"AssumeRolePolicyDocument": {
"Version": "2012-10-17","Statement": [ {
"Action": "sts:AssumeRole","Effect": "Allow","Principal": {
"Service": "lambda.amazonaws.com"}
} ]},
…}
AWS Lambda is allowed
to assume this role
Your Turn: Modify the Function Code
Try modifying the AWS Lambda function to do something
more interesting!
For example code that publishes to an SNS topic, see
handout: lambda_function_with_publish_to_sns.js
Another Idea:
Using CloudTrail to Audit Permissions
Least-privilege best practice: Audit IAM roles and users
against actual usage in CloudTrail
Does anyone have permissions that have gone unused?
The Application We Are Running
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0
SSH Security Group
ALB Security Group
Backend Security Group
ALLOW
What You Are Running
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0ALB Security Group
Backend Security Group
Routing for Least-Privilege in a VPC
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0
Routing for Least-Privilege in a VPC
virtual private cloud
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
0.0.0.0/0
VPC subnet
us-west-2b
VPC subnet
us-west-2aVPC subnet
us-west-2c
Access to S3 via VPC Endpoints
Private subnets
Inspecting VPC Flow Logs
Who’s this?# dig +short -x 109.236.86.32 internetpolice.co.
REJECT
UDP Port 53 = DNS
VPC Flow Logs in Lambda
2016-09-24T21:53:46.264Z 5e20015f-82a1-11e6-b2ab-735d6b306893 { "messageType": "DATA_MESSAGE",
"owner": "280328680831", "logGroup": "VPCFlowLogs", "logStream": "eni-18027f46-all","subscriptionFilters": [ "myTrigger" ],"logEvents": [
{ "id": "32888099581059259498575118542779913238350648463663169536","timestamp": 1474753390000, "message": "2 280328680831 eni-18027f46 10.0.2.92 10.0.2.98 8080 32906
6 5 650 1474753390 1474753446 ACCEPT OK" }, …
Available after 10 mins
Lambda Function for Unexpected REJECTs
Your turn: Do something interesting with VPC Flow Logs!
Idea: Try writing a Lambda function that notifies your SNS
topic when within-VPC traffic gets REJECTed.
The code in your Lambda function already unzips and
pretty-prints the messages.
Lambda Function for Unexpected REJECTs
Handout: vpc_flow_logs_rejects.js
Simple Lambda function for notifying an SNS topic
whenever a packet sent within the VPC gets rejected.
Related Sessions
More About IAM:
• SAC317 - IAM Best Practices to Live By
• SEC311 - How to Automate Policy Validation
More About VPC:
• NET201 - Creating Your Virtual Data Center: VPC
Fundamentals and Connectivity Options
• SEC401 - Automated Formal Reasoning About AWS
Systems