Bootstrap FreeKB - Amazon Web Services (AWS) - Resolve "Access Denied for bucket" for Network Load Balancer
Amazon Web Services (AWS) - Resolve "Access Denied for bucket" for Network Load Balancer

Updated:   |  Amazon Web Services (AWS) articles

I got this error when attempting to update my Network Load Balancer to store it's access logs in my S3 Bucket my-bucket-abcdefg.

]$ aws elbv2 modify-load-balancer-attributes \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/my-load-balancer/19dd9f59a3a084d8/1478a1951aa0a25c \
--attributes \
Key=access_logs.s3.enabled,Value=true \
Key=access_logs.s3.bucket,Value=my-bucket-abcdefg\
Key=access_logs.s3.prefix,Value=my-application-load-balancer-logs

An error occurred (InvalidConfigurationRequest) when calling the ModifyLoadBalancerAttributes operation: Access Denied for bucket: my-bucket-abcdefg. Please check S3bucket permission

 

Here are the most command reason this error is returned.

  • The S3 Bucket and Load Balancer are in different AWS accounts
  • The S3 Bucket and Load Balancer are in different regions
  • The S3 Bucket does not have a policy that allows access to the Bucket
  • The S3 Bucket has Public Access Blocked
  • The user attempting to access the Bucket does not have permission to access the Bucket
  • The S3 Bucket is using KMS Encryption
  • The Network Load Balancer is not using a TLS Listener
  • The S3 Bucket and Network Load Balancer prefix settings do not match

Regions

The aws elbv2 describe-load-balancers command can be used to determine the region the load balancer is in (us-east-1 in this example).

]$ aws elbv2 describe-load-balancers --query 'LoadBalancers[?LoadBalancerName==`my-load-balancer`]'
[
    {
        "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/my-load-balancer/19dd9f59a3a084d8",

 

The s3api get-bucket-location command can be used to return the location of the S3 Bucket. By default, S3 Buckets reside in the us-east-1 region. S3 Buckets in the us-east-1 region will have LocationConstraint null.

~]$ aws s3api get-bucket-location --bucket my-bucket-ozckkxpoon
{
    "LocationConstraint": null
}

 

On the other hand, S3 Buckets in a region other than us-east-1 will list the region.

~]$ aws s3api get-bucket-location --bucket my-bucket-uygwfdeyxq
{
    "LocationConstraint": "us-east-2"
}

 


S3 Bucket Policy

Create a JSON file that contained the following, to allow access to the S3 bucket.

  • Replace 0123456789 with your AWS Account ID
  • Replace my-bucket with the name of your S3 Bucket
{
    "Version": "2012-10-17",
    "Id": "AWSLogDeliveryWrite",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
                },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::my-bucket",
            "Condition": {
                "StringEquals": {
                "aws:SourceAccount": ["0123456789"]
                },
                "ArnLike": {
                "aws:SourceArn": ["arn:aws:logs:us-east-1:0123456789:*"]
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::my-bucket/AWSLogs/0123456789/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": ["0123456789"]
                },
                "ArnLike": {
                    "aws:SourceArn": ["arn:aws:logs:us-east-1:0123456789:*"]
                }
            }
        }
    ]
}

 

Your S3 ARN resource with a prefix.

  • arn:aws:s3:::bucket-name/prefix/AWSLogs/aws-account-id/*

Your S3 ARN resource without a prefix.

  • arn:aws:s3:::bucket-name/AWSLogs/aws-account-id/*

 

Use the aws s3api put-bucket-policy​ command to attach the policy to the S3 Bucket.

aws s3api put-bucket-policy --bucket my-bucket-abcdefg --policy file://policy.json

 

Notice in this example that user/johndoe is being granted s3:PutObject permission to arn:aws:s3:::my-bucket-abcdefg/*. The aws iam list-attached-user-policies command can be used to determine if johndoe policy allows s3:PutObject. In this example, johndoe has AdministratorAccess, thus he definitely has permission.

]$ aws iam list-attached-user-policies --user-name johndoe 
{
    "AttachedPolicies": [
        {
            "PolicyName": "AdministratorAccess",
            "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
        }
    ]
}

 


Public Access block

Use the aws s3api get-public-access-block command to check if your S3 Bucket has Public Access blocked.

~]$ aws s3api get-public-access-block --bucket my-bucket-abcdefg
{
    "PublicAccessBlockConfiguration": {
        "BlockPublicAcls": true,
        "IgnorePublicAcls": true,
        "BlockPublicPolicy": true,
        "RestrictPublicBuckets": true
    }
}

 

The aws s3api delete-public-access-block command can be used to remove the public access block from the S3 Bucket.

aws s3api delete-public-access-block --bucket my-bucket-abcdefg

 

And confirm the Public Access Blocks were removed.

]$ aws s3api get-public-access-block --bucket my-bucket-abcdefg
{
    "PublicAccessBlockConfiguration": {
        "BlockPublicAcls": false,
        "IgnorePublicAcls": false,
        "BlockPublicPolicy": false,
        "RestrictPublicBuckets": false
    }
}

 


Access Control List (ACL)

The aws s3api get-bucket-acl command can be used to list an S3 Bucket Access Control List (ACL). In this example, user johndoe has been granted FULL_CONTROL.

~]$ aws s3api get-bucket-acl --bucket my-bucket-abcdefg
{
    "Owner": {
        "DisplayName": "johndoe",
        "ID": "ab0e0a12345678903a77c82240d5cb3fc41ff11cc312345678977a5f8e743743"
    },
    "Grants": [
        {
            "Grantee": {
                "DisplayName": "johndoe",
                "ID": "ab0e0a12345678903a77c82240d5cb3fc41ff11cc312345678977a5f8e743743",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        }
    ]
}

 


Server Side Encryption

By default, an S3 Bucket should have Server-side encryption with Amazon S3 managed keys (SSE-S3) enabled. In this scenario, the server side encryption should not be the cause of the Access Denied.

~]$ aws s3api get-bucket-location --bucket my-bucket-abcdefg
{
    "ServerSideEncryptionConfiguration": {
        "Rules": [
            {
                "ApplyServerSideEncryptionByDefault": {
                    "SSEAlgorithm": "AES256"
                },
                "BucketKeyEnabled": true
            }
        ]
    }
}

 

On the other hand, if the Bucket has AWS KMS key stored in AWS Key Management Service (SSE-KMS), the Bucket Policy will most likely need to include the kms Actions.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [ 
        "s3:*",
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
    ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::my-bucket-abcdefg/AWSLogs/123456789012/*",
        "arn:aws:s3:::my-bucket-abcdefg/*",
        "arn:aws:s3:::my-bucket-abcdefg"
      ],
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/johndoe"
        ]
      }
    }
  ]
}

 


Network Load Balancer Listener

If you are getting "Access Denied for Bucket" when attempting to configure one of your Network Load Balancer to write it's access logs to the S3 Bucket, the Network Load Balancer must be using a Listener that has the TLS protocol.

The aws elbv2 describe-listeners command can be used to list your Load Balancer Listeners, to determine if the Listener is using the TLS protocol. Something like this should be returned.

]$ aws elbv2 describe-listeners --listener-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/net/my-load-balancer/19dd9f59a3a084d8/1478a1951aa0a25c
{
    "Listeners": [
        {
            "ListenerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/net/my-load-balancer/19dd9f59a3a084d8/1478a1951aa0a25c",
            "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/net/my-load-balancer/19dd9f59a3a084d8",
            "Port": 443,
            "Protocol": "TLS",
            "Certificates": [
                {
                    "CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/631d3f41-4a1a-4ef8-9e40-076a180a7770"
                }
            ],
            "SslPolicy": "ELBSecurityPolicy-2016-08",
            "DefaultActions": [
                {
                    "Type": "forward",
                    "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-https-target-group/26bc8c47b785bb0e",
                    "Order": 1,
                    "ForwardConfig": {
                        "TargetGroups": [
                            {
                                "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-http-target-group/26bc8c47b785bb0e"
                            }
                        ]
                    }
                }
            ]
        }
    ]
}

 


The S3 Bucket and Network Load Balancer prefix settings must match.

For example, if the policy attached to the S3 Bucket includes a prefix, then the Network Load Balancer must be configured with the same prefix. For example, let's say your S3 Bucket contains "my-prefix". In this scenario, when configuring your Network Load Balancer to log it's access logs to the S3 Bucket, "my-prefix" should be include. 

arn:aws:s3:::my-bucket/my-prefix/AWSLogs/0123456789/*

 

On the other hand, if your S3 Bucket does not contain a prefix, when configuring your Network Load Balancer to log it's access logs to the S3 Bucket, you should not include a prefix.

arn:aws:s3:::my-bucket/AWSLogs/0123456789/*

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 6fe351 in the box below so that we can be sure you are a human.