AWS Systems Manager (SSM) fails to UpdateInstanceInformation on SageMaker instance - amazon-web-services

I often get Cloudwatch Authorization alerts because the role attached to my SageMaker instance doesn't seem to have enough SSM (Systems Manager) permissions to UpdateInstanceInformation. My understanding is that the agent amazon-ssm-agent wants to hit an AWS API but fails to do so.
My Role has full SSM permissions:
{
"Action": [
"ssm:*",
"ssmmessages:*"
],
"Resource": "*",
"Effect": "Allow"
}
but the error persists:
{
"eventVersion": "1.05",
"userIdentity": {
"type": "AssumedRole",
"principalId": "XXXXXXXXXXXXX:SageMaker",
"arn": "arn:aws:sts::XXXXXXXXXXXXX:assumed-role/sagemaker_prod_Notebook_Instance_Role/SageMaker",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "XXXXXXXXXXXXX",
"arn": "arn:aws:iam::XXXXXXXXXXXXX:role/sagemaker_prod_Notebook_Instance_Role",
"accountId": "XXXXXXXXXXXXX",
"userName": "sagemaker_prod_Notebook_Instance_Role"
}
},
"invokedBy": "im.amazonaws.com"
},
"eventSource": "ssm.amazonaws.com",
"eventName": "UpdateInstanceInformation",
"sourceIPAddress": "im.amazonaws.com",
"userAgent": "im.amazonaws.com",
"errorCode": "AccessDenied",
"errorMessage": "An unknown error occurred",
"requestParameters": {
"instanceId": "i-045f627a2d2e469b1",
"agentVersion": "2.3.714.0",
"platformType": "Linux",
"agentName": "amazon-ssm-agent"
},
"eventType": "AwsApiCall"
}
Has anyone seen this before ?

This is a bit late but I had a similar issue so I reached out to AWS Support and it seems to be a somewhat of a bug.
I was told that the AWS Sagemaker team has ssm installed by default. The Sagemaker notebook runs in an aws service account, although when a customer assigns Sagemaker a role in their own account the role cannot perform UpdateInstance information via the customer assigned role.
Support suggested I create a lifecycle config and leverage the following code sample to fix it:
https://docs.aws.amazon.com/sagemaker/latest/dg/notebook-lifecycle-config.html
https://github.com/aws-samples/amazon-sagemaker-notebook-instance-lifecycle-config-samples/blob/master/scripts/disable-uninstall-ssm-agent/on-start.sh

Related

Access denied on table access to AWS Lake Formation using AWS EMR

I'm working on a small pet project in which I want to setup AWS Lake Formation, put there some data and then access this data in AWS EMR. I was following instructions in this doc: https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-lake-formation.html. I've already got:
A data lake with some CSVs
Created table schemas for these CSVs
A external IdP (Auth0)
IAM Roles as in the tutorial.
The EMR cluster set up as in tutorial.
The problem is that I cannot access data in data lake. I can list databases and tables but can't perform a SELECT on any table.
I get:
com.amazonaws.emr.recordserver.remote.RecordServerException: com.amazonaws.emr.recordserver.remote.RecordServerException: Error while trying to get temporary table credentials for user: 5000, table: ***, database: ***, catalog: null from Secret Agent.
...
Caused by: SecretAgentClientException{httpResponseCode=Optional[500] message=Access denied for tableArn=arn:aws:glue:eu-west-1:743262912284:TABLE_NAME userId=5000 permissions=SELECT cause.class=null}
I checked the logs in Lake Formation and there I've got a DataAccess event with principal set to the user that I use in Zeppelin notebook.
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AssumedRole",
"principalId": "***",
"arn": "***",
"accountId": "***",
"accessKeyId": "***",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "***",
"arn": "PROPER_ROLE_ARN",
"accountId": "***",
"userName": "PROPER_ROLE"
},
"attributes": {
"creationDate": "2022-01-14T10:26:39Z",
"mfaAuthenticated": "false"
}
}
},
"eventTime": "2022-01-14T10:53:40Z",
"eventSource": "lakeformation.amazonaws.com",
"eventName": "GetDataAccess",
"awsRegion": "eu-west-1",
"sourceIPAddress": "***",
"userAgent": "aws-sdk-java/1.11.970 Linux/4.14.252-195.483.amzn2.x86_64 OpenJDK_64-Bit_Server_VM/25.312-b07 java/1.8.0_312 vendor/Amazon.com_Inc.",
"errorCode": "AccessDenied",
"errorMessage": "Access is not allowed.",
"requestParameters": {
"tableArn": "arn:aws:glue:eu-west-1:***:***",
"permissions": [
"SELECT"
],
"durationSeconds": 3600
},
"responseElements": null,
"additionalEventData": {
"requesterService": "UNKNOWN",
"LakeFormationTrustedCallerInvocation": "true",
"lakeFormationPrincipal": "PROPER_PRINCIPAL_ARN"
},
"requestID": "1e4c02e9-e09e-4906-a96f-c29a882b46de",
"eventID": "b5b26de0-60f4-482c-b670-7fba9d7089e5",
"readOnly": true,
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "***",
"eventCategory": "Management",
"tlsDetails": {
"clientProvidedHostHeader": "lakeformation.eu-west-1.amazonaws.com"
}
}
The assumed role in sessionContext is correct. I've checked policies of created roles multiple times and they are exactly as in the tutorial (they have granted access to the lakeformation and to glue and also to all tables)
Please ensure that you allow each account to run Lake Formation-enabled EMR clusters. You can do so on the Lake Formation console by going to "External Data Filtering" found on the left navigation panel.
https://docs.aws.amazon.com/lake-formation/latest/dg/getting-started-setup.html#emr-switch.

How to find out who created a Key Pair in aws ec2?

I have full access to AWS account, see all keys that was created and used and need to know the person who owns the private keys. But AWS UI does no provide any information about Key Pairs except ID, Name, Type, Fingerprint
Is it possible to identify who created a certain key pair in AWS EC2?
If CloudTrail is setup it would have recorded the event which includes the user. The Following is lifted from the AWS Cloudtrail docs:
{"Records": [{
"eventVersion": "1.0",
"userIdentity": {
"type": "IAMUser",
"principalId": "EX_PRINCIPAL_ID",
"arn": "arn:aws:iam::123456789012:user/Alice",
"accountId": "123456789012",
"accessKeyId": "EXAMPLE_KEY_ID",
"userName": "Alice",
"sessionContext": {"attributes": {
"mfaAuthenticated": "false",
"creationDate": "2014-03-06T15:15:06Z"
}}
},
"eventTime": "2014-03-06T17:10:34Z",
"eventSource": "ec2.amazonaws.com",
"eventName": "CreateKeyPair",
"awsRegion": "us-east-2",
"sourceIPAddress": "72.21.198.64",
"userAgent": "EC2ConsoleBackend, aws-sdk-java/Linux/x.xx.fleetxen Java_HotSpot(TM)_64-Bit_Server_VM/xx",
"requestParameters": {"keyName": "mykeypair"},
"responseElements": {
"keyName": "mykeypair",
"keyFingerprint": "30:1d:46:d0:5b:ad:7e:1b:b6:70:62:8b:ff:38:b5:e9:ab:5d:b8:21",
"keyMaterial": "\u003csensitiveDataRemoved\u003e"
}
}]}
If cloudTrail was not enabled when the keypair was created i think you might be out of luck. If you have paid support you could ask the question to AWS or otherwise use the AWS forums - they may know more than me.

Instace Type Change log

How do I find out when the Instance size was changed using Cloudtrail? e.g. large -xlarge date, user and so on. One of the instance size have been changed and I'd like to find out which user has changed it
The Logging Amazon EC2, Amazon EBS, and Amazon VPC API Calls with AWS CloudTrail documentation states that:
All Amazon EC2, Amazon EBS, and Amazon VPC actions are logged by CloudTrail and are documented in the Amazon EC2 API Reference.
The Amazon EC2 API Reference shows that the action you're looking for is the one called ModifyInstanceAttribute; in your case you should target events that have "eventName": "ModifyInstanceAttribute" and have the instanceType key in the requestParameters object. The identity of the user (or role) that initiated the action is in userIdentity.
An example of such event in CloudTrail is:
{
"eventVersion": "1.05",
"userIdentity": {
"type": "IAMUser",
"principalId": "XXXXXXXXXXX",
"arn": "arn:aws:iam::XXXXXXXXXX:user/my_user",
"accountId": "XXXXXXXXXX",
"accessKeyId": "XXXXXXXXXX",
"userName": "my_user",
"sessionContext": {
"sessionIssuer": {},
"webIdFederationData": {},
"attributes": {
"mfaAuthenticated": "true",
"creationDate": "2020-11-26T15:49:37Z"
}
}
},
"eventTime": "2020-11-26T16:54:18Z",
"eventSource": "ec2.amazonaws.com",
"eventName": "ModifyInstanceAttribute",
"awsRegion": "eu-west-1",
"sourceIPAddress": "111.22.33.444",
"userAgent": "console.ec2.amazonaws.com",
"requestParameters": {
"instanceId": "i-08999dedafc4xxyyz",
"instanceType": {
"value": "t3.nano"
}
},
"responseElements": {
"requestId": "11111111-2222-472f-ad77-bbeb506b242d",
"_return": true
},
"requestID": "11111111-2222-472f-ad77-bbeb506b242d",
"eventID": "aaaaaaa-c757-4501-8889-4f9d90720c0c",
"eventType": "AwsApiCall",
"recipientAccountId": "XXXXXXXXXX"
}

What is wrong with this AWS EFS policy?

I'm pretty new at working with AWS and I'm just experimenting and trying to learn. So I have an EC2 instance with an IAM role attached. I also have an EFS filesystem with the below policy in place. My intent was to restrict mounting the access point to EC2 instances with the IAM role attached.
But when I try to mount from the EC2 instance I get access denied.
mount.nfs4: access denied by server while mounting 127.0.0.1:
If I change the principal to "AWS" : "*" I can mount the access point. According to the docs I can specify the IAM role used by the EC2 instance as the principal but it doesn't seem to work.
I suspect my problem is somehow with the role I have attached to the EC2 instance. The role has EFS client actions but when I look at the role in the IAM console and check access adviser, it says the role is never accessed. So I may be doing something fundamentally wrong.
{
"Version": "2020-08-08",
"Id": "access-point-www",
"Statement": [
{
"Sid": "access-point-webstorage",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::12345678:role/wwwservers"
},
"Action": [
"elasticfilesystem:ClientMount",
"elasticfilesystem:ClientWrite"
],
"Resource": "arn:aws:elasticfilesystem:us-east-1:12345678:file-system/fs-987654da",
"Condition": {
"StringEquals": {
"elasticfilesystem:AccessPointArn": "arn:aws:elasticfilesystem:us-east-1:12345678:access-point/fsap-01ffffbfb38217bcd"
}
}
}
]
}
Did you enable IAM mounting? Otherwise AWS tries to mount the EFS volume as a anonymous principle.
For EC2, like your case, you might just provide -o iam as option to your call to mount.
See: https://docs.amazonaws.cn/en_us/efs/latest/ug/efs-mount-helper.html#mounting-IAM-option
For ECS/task definitions this can be done this way:
Like this here:
aws_ecs_task_definition.volume.efs_volume_configuration.authorization_config?
resource "aws_ecs_task_definition" "service" {
family = "something"
container_definitions = file("something.json")
volume {
name = "service-storage"
efs_volume_configuration {
file_system_id = aws_efs_file_system.efs[0].id
root_directory = "/"
transit_encryption = "ENABLED"
authorization_config {
iam = "ENABLED"
}
}
}
}
iam - (Optional) Whether or not to use the Amazon ECS task IAM role defined in a task definition when mounting the Amazon EFS file system. If enabled, transit encryption must be enabled in the EFSVolumeConfiguration. Valid values: ENABLED, DISABLED. If this parameter is omitted, the default value of DISABLED is used.
This will help you if you have errors in your CloudTrail that an anonymous principal tries to mount your EFS. Errors would look something like this then:
{
"eventVersion": "1.08",
"userIdentity": {
"type": "AWSAccount",
"principalId": "",
"accountId": "ANONYMOUS_PRINCIPAL"
},
"eventSource": "elasticfilesystem.amazonaws.com",
"eventName": "NewClientConnection",
"sourceIPAddress": "AWS Internal",
"userAgent": "elasticfilesystem",
"errorCode": "AccessDenied",
"readOnly": true,
"resources": [
{
"accountId": "XXXXXX",
"type": "AWS::EFS::FileSystem",
"ARN": "arn:aws:elasticfilesystem:eu-west-1:XXXXXX:file-system/YYYYYY"
}
],
"eventType": "AwsServiceEvent",
"managementEvent": true,
"eventCategory": "Management",
"recipientAccountId": "XXXXXX",
"sharedEventID": "ZZZZZZZZ",
"serviceEventDetails": {
"permissions": {
"ClientRootAccess": false,
"ClientMount": false,
"ClientWrite": false
},
"sourceIpAddress": "nnnnnnn"
}
}
Note: "principalId": "", and "accountId": "ANONYMOUS_PRINCIPAL"

How to fix AWS Config generating AccessDenied error?

I am trying to allow AWS Config to write to a non-public S3 bucket.
Based on the official documentation, I should have two policies assigned to the AWS role. However, It is not possible to add any policy to the service-linked role, neither to create a custom new service-linked role for AWS config.
As such, how can I stop receiving the S3 AccessDenied error without making the bucket public?
edit: here is the error log:
{
"eventVersion": "1.07",
"userIdentity": {
"type": "AssumedRole",
"principalId": "xxxxxxxxxxxxxxxxxxxxx:AWSConfig-BucketConfigCheck",
"arn": "arn:aws:sts::xxxxxxxxxxxx:assumed-role/AWSServiceRoleForConfig/AWSConfig-BucketConfigCheck",
"accountId": "xxxxxxxxxxxx",
"accessKeyId": "xxxxxxxxxxxxxxxxxxxx",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "xxxxxxxxxxxxxxxxxxxxx",
"arn": "arn:aws:iam::xxxxxxxxxxxx:role/aws-service-role/config.amazonaws.com/AWSServiceRoleForConfig",
"accountId": "xxxxxxxxxxxx",
"userName": "AWSServiceRoleForConfig"
},
"attributes": {
"creationDate": "2020-04-30T00:43:57Z",
"mfaAuthenticated": "false"
}
},
"invokedBy": "AWS Internal"
},
"eventTime": "2020-04-30T00:43:57Z",
"eventSource": "s3.amazonaws.com",
"eventName": "PutObject",
"awsRegion": "eu-west-1",
"sourceIPAddress": "xxx.xxx.xxx.xxx",
"userAgent": "[AWSConfig]",
"errorCode": "AccessDenied",
"errorMessage": "Access Denied",
"requestParameters": {
"bucketName": "aws-config-bucket-xxxxxxxxxxxx",
"Host": "aws-config-bucket-xxxxxxxxxxxx.s3.eu-west-1.amazonaws.com",
"x-amz-acl": "bucket-owner-full-control",
"x-amz-server-side-encryption": "AES256",
"key": "AWSLogs/xxxxxxxxxxxx/Config/ConfigWritabilityCheckFile"
},
"responseElements": null,
"additionalEventData": {
"SignatureVersion": "SigV4",
"CipherSuite": "ECDHE-RSA-AES128-SHA",
"bytesTransferredIn": 0,
"AuthenticationMethod": "AuthHeader",
"x-amz-id-2": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=",
"bytesTransferredOut": 243
},
"requestID": "xxxxxxxxxxxxxxxx",
"eventID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"readOnly": false,
"resources": [
{
"type": "AWS::S3::Object",
"ARN": "arn:aws:s3:::aws-config-bucket-xxxxxxxxxxxx/AWSLogs/xxxxxxxxxxxx/Config/ConfigWritabilityCheckFile"
},
{
"accountId": "xxxxxxxxxxxx",
"type": "AWS::S3::Bucket",
"ARN": "arn:aws:s3:::aws-config-bucket-xxxxxxxxxxxx"
}
],
"eventType": "AwsApiCall",
"managementEvent": false,
"recipientAccountId": "xxxxxxxxxxxx",
"vpcEndpointId": "vpce-xxxxxxxx",
"eventCategory": "Data"
}
I found the answer here: https://forums.aws.amazon.com/thread.jspa?threadID=314156
When AWS Config sends configuration information to an Amazon S3
bucket in another account, it first attempts to use the IAM role, but
this attempt fails if the access policy for the bucket does not grant
WRITE access to the IAM role. In this event, AWS Config sends the
information again, this time as the AWS Config service principal.
I checked my logs and there was an AWS Config service principal log, the same second as the AccessDenied, that was being accepted. Therefore, the error can be safely ignored. I have updated my Cloudwatch alarm to ignore it:
{($.errorCode="*UnauthorizedOperation") || (($.errorCode="AccessDenied*") && (($.userIdentity.type!="AssumedRole") || ($.userAgent!="[AWSConfig]")))}