I hope someone can help me with this.
Is it possible to save session output of the SSM Session Manager to an S3 bucket in another AWS Account? I can't get it working, my bucket policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SSMBucketPermissionsCheck",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::<bucket-name>"
},
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"Service": "ssm.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<bucket-name>/<account-id>/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
}
]
}
I suspect that you need to grant access to the instance role rather than the SSM service. Something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": " SSMBucketDelivery",
"Effect": "Allow",
"Principal": {
"AWS": "123456789012"
},
"Action": ["s3:PutObject","s3:PutObjectAcl"],
"Resource": "arn:aws:s3:::<bucket-name>/<account-id>/*"
}
]
}
I'm not sure if writing to a bucket in a different region is supported.
If you want encryption enabled on your bucket, you might need to use the SSE-KMS encryption method, and in the key policy grant access to the other account so that it can encrypt the data. Not sure what KMS permissions this needs. I'd first try it out with an unencrypted bucket and a policy like the above to get the log delivery working, then figure out how to deal with encryption.
Hey @thedevopsmachine ! Thx for your reply. Your policy seems to work. The only thing is for some reason the ACL for the files in my S3 buckets are not set, which will lead to that the owner of the bucket is not able to retrieve the file. I think the bucket-owner-full-control is not in the header during the putObject action. Any thoughts on that?
It looks like the agent should be setting the ACL, but it does so after it has written the file. However, for some reason the exception handler only logs at the Debug level.
https://github.com/aws/amazon-ssm-agent/blob/master/agent/s3util/s3util.go#L99
There might be something going wrong there. Try enabling debug logging on the agent to see if there is an error message being written to the log during this operation.
Ok I just enable debug-logging:
The last relevant message is:
Successfully uploaded file to %!(EXTRA string=https://bucket-ssm.s3.eu-west-1.amazonaws.com/99999999999/joost.saanen.console-0fee74fad09abfc0a.log)
No further logging regarding to this session.
Ok, I found the problem. Apparently I had to add the following policy to my instance role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:PutObjectAcl",
"Resource": "<bucket>/<path>"
}
]
}
Closing issue as you seem to have resolve it. Feel free to open another issue if you run into any other issues.
I feel like the original PutObject S3 API call should include the correct ACL?
Also the AWS managed IAM Policy should include the PutObjectAcl action?
Using bucket-owner-full-control as the ACL is what other cross-account services such as Cloudtrail do.
@JoostSaanen
Hello, I would like to achieve the same thing - log to another account's bucket - however on the Session Manager Preferences page of AWS management console I am unable to specify the external bucket. The web page validation says 'The specified bucket does not exist!'.
Any hints?
Thanks
@komushi Can you post your bucket policy here?
I was able to send the SSH logs into a cross account S3 bucket which is KMS encrypted
EC2 instance policy I used is specified here: https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-instance-profile.html#instance-profile-custom-s3-policy
KMS key to encrypt s3 bucket in the logging account only needs "ViaService S3" or Explicitly whitelist s3 service like below
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow Admin",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow Cryptography",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:DescribeKey",
"kms:Decrypt",
"kms:CreateGrant"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.us-east-1.amazonaws.com",
"kms:CallerAccount": "1234567890"
}
}
}
]
}
S3 bucket in the logging account -> bucket policy looks like this
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSALBPutLogs",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0987654321:root"
},
"Action": [
"s3:PutObjectAcl",
"s3:PutObject",
"s3:GetEncryptionConfiguration"
],
"Resource": [
"arn:aws:s3:::asdfghjkl/*",
"arn:aws:s3:::asdfghjkl"
]
}
]
}
1234567890 -> logging account
0987654321 -> where your ec2 instance and Session manager is
Most helpful comment
I feel like the original PutObject S3 API call should include the correct ACL?
Also the AWS managed IAM Policy should include the PutObjectAcl action?
Using
bucket-owner-full-controlas the ACL is what other cross-account services such as Cloudtrail do.