Lambda function URL using Cloudfront OAC

0

Hi,

I tried to configure one of my lambda url to be accessible only though CloudFront OAC. I tried to follow this guide: Restricting access to an AWS Lambda function URL origin. Unfortunetly it doesn't seemed to work. When I try to access my lambda through is URL, I get this error: {"Message":"Forbidden"}. Here are the steps I followed : I created a Cloudfront OAC like this:

CloudFrontOacLambda:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig: 
          Description: OAC to access lambda function url
          Name: MyName
          OriginAccessControlOriginType: lambda
          SigningBehavior: always
          SigningProtocol: sigv4

I configured my cloudfront distribution to use this OAC:

...
Origins
 - DomainName: !Select [2, !Split ["/", !Ref LambdaFunctionUrl ]] # Remove https:// from URL. 
          Id: LambdaOrigin
          OriginAccessControlId: !GetAtt CloudFrontOacLambda.Id
          CustomOriginConfig:
            HTTPSPort: 443
            OriginProtocolPolicy: https-only

I updated my KMS key policy to allow CloudFront to it :

...
Effect: Allow
              Principal:
                Service: cloudfront.amazonaws.com
              Action:
                - kms:Decrypt
                - kms:Encrypt
                - kms:GenerateDataKey*
              Resource: "*"
              Condition:
                StringEquals:
                  "AWS:SourceArn": !Sub "arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${MyDistribID}"

I updated the resource-based policy of my lambda using aws cli as described in the documentation:

aws lambda add-permission \
--statement-id "AllowCloudFrontServicePrincipal" \
--action "lambda:InvokeFunctionUrl" \
--principal "cloudfront.amazonaws.com" \
--source-arn "arn:aws:cloudfront::123456789012:distribution/MyDistribID" \
--function-name FUNCTION_URL_NAME

I removed the previous policy of my lambda that provide public access.

After doing this, my fonction url is not accessible anymore (using direct Url OR or using Cloudfront).

Can someone help me and tell me what I missed ? Thanks a lot for your help !

質問済み 1ヶ月前162ビュー
2回答
0

Hello.

Are you accessing the Lambda URL directly?
Are you accessing the CloudFront URL (https://example.cloudfront.net/) instead of the Lambda URL?
Also, is the CloudFront distribution ID set in the Lambda resource-based policy correct?

profile picture
エキスパート
回答済み 1ヶ月前
profile pictureAWS
エキスパート
レビュー済み 1ヶ月前
  • I can't access the URL, directly or using the distribution url. Always the same error : {"Message":"Forbidden"} On the lambda ressource-based policy, il I add the default public policy, the url is accessible (directly or using cloudfront url).

  • By the way, is the authentication method for the Lambda function URL set to IAM authentication? a
    If the authentication method is IAM, you can access it from CloudFront if the following resource-based policy is set for Lambda.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:ap-northeast-1:account-id:function:cloudfront",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/xxxxxxxxxxx"
            }
          }
        }
      ]
    }
    
  • If the authentication method was "NONE", access was not possible without the following resource-based policy.

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "StatementId": "FunctionURLAllowPublicAccess",
          "Effect": "Allow",
          "Principal": "*",
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:ap-northeast-1:account-id:function:cloudfront",
          "Condition": {
            "StringEquals": {
              "lambda:FunctionUrlAuthType": "NONE"
            }
          }
        },
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:ap-northeast-1:account-id:function:cloudfront",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::account-id:distribution/xxxxxxxxxxx"
            }
          }
        }
      ]
    }
    
  • No it is not, as the documentation does not ask to configure it. This is the configuration described in the doc :

    aws lambda add-permission \
    --statement-id "AllowCloudFrontServicePrincipal" \
    --action "lambda:InvokeFunctionUrl" \
    --principal "cloudfront.amazonaws.com" \
    --source-arn "arn:aws:cloudfront::123456789012:distribution/DistributionID" \
    --function-name FUNCTION_URL_NAME
    

    But I tried to set it, but it doesn't seemed to work either. This is my current Lambda Policy (without IAM autnentication):

    {
      "Version": "2012-10-17",
      "Id": "default",
      "Statement": [
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:region:1234567890:function:myFunc",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::1234567890:distribution/MyDistribID"
            }
          }
        }
      ]
    }
    
  • I tried this one but it doesn't work either:

    {
      "Version": "2012-10-17",
      "Id": "default",
      "Statement": [
        {
          "Sid": "test",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:region:123456789012:function:myFunc",
          "Condition": {
            "StringEquals": {
              "lambda:FunctionUrlAuthType": "AWS_IAM"
            },
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/MyDistrib"
            }
          }
        }
      ]
    }
    
0

Ok, I found what I missed ! The Policy was good BUT the function URL Auth type must be set to "AWS_IAM" ! This part was not described in the AWS documentation. Thanks for your help @Riku_Kobayashi

Here is my policy that works :

{
  "Version": "2012-10-17",
  "Id": "default",
  "Statement": [
    {
      "Sid": "AllowCloudFrontServicePrincipal",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "lambda:InvokeFunctionUrl",
      "Resource": "arn:aws:lambda:region:accountid:function:myFunction",
      "Condition": {
        "ArnLike": {
          "AWS:SourceArn": "arn:aws:cloudfront::accountid:distribution/distribID"
        }
      }
    }
  ]
}
```
回答済み 1ヶ月前
  • @willysup - I am having similar issues however it only doesn't work when I send a POST with body data to CF to send to the lambda. If you POST with body data does it succesfully send to your lambda?

ログインしていません。 ログイン 回答を投稿する。

優れた回答とは、質問に明確に答え、建設的なフィードバックを提供し、質問者の専門分野におけるスキルの向上を促すものです。

質問に答えるためのガイドライン

関連するコンテンツ