Удалить Content-Length используя AWS Lambda@Edge - PullRequest
0 голосов
/ 01 мая 2020

У меня есть следующая настройка CloudFront с помощью AWS шаблона CloudFormation:

  CloudFrontDistribution:  
    Type: AWS::CloudFront::Distribution
    DependsOn:
    - LoggingBucket
    - LambdaEdgeFunction
    Properties:
      DistributionConfig:
        Comment: 'Route to multiple origins with CloudFront'
        Enabled: true
        IPV6Enabled: !Ref 'IPV6Enabled'
        Logging:
          Bucket: !Sub '${LoggingBucket}.s3.amazonaws.com'
        HttpVersion: http2
        Comment: !Join [ '', [!Ref 'AWS::StackName', ' Cloud Front']]
        Aliases: 
          - !Ref 'AlternateDomainNames'
        ViewerCertificate:
          AcmCertificateArn: !Ref ACMCertificateArn
          SslSupportMethod: !Ref 'SslSupportMethod' #sni-only
          MinimumProtocolVersion: !Ref 'MinimumProtocolVersion' #TLSv1.1_2016
        Origins:
        - Id: APIGOrigin
          DomainName: !Sub ${ApiGatewayId}.execute-api.eu-west-1.amazonaws.com
          OriginPath: !Sub /${ApiStage}
          CustomOriginConfig:
            HTTPSPort: 443
            OriginProtocolPolicy: https-only
          OriginCustomHeaders:
            - HeaderName: 'X-From-CDN'
              HeaderValue: !Ref VerifyFromCfHeaderVal
        DefaultCacheBehavior:
          AllowedMethods: ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
          CachedMethods: ["GET", "HEAD", "OPTIONS"]
          ForwardedValues:
            Headers:
            - Access-Control-Request-Headers
            - Access-Control-Request-Method
            - Origin
            - Authorization
            - Accept
            # - Host APIG needs to use SNI
            QueryString: !Ref 'QueryString'
            Cookies:
              Forward: !Ref 'ForwardCookies'
          TargetOriginId: APIGOrigin
          ViewerProtocolPolicy: https-only
          Compress: !Ref 'Compress'
          DefaultTTL: !Ref 'DefaultTTL'
          MaxTTL: !Ref 'MaxTTL'
          MinTTL: !Ref 'MinTTL'
          SmoothStreaming: 'false'
          # Lambda
          LambdaFunctionAssociations:
            - EventType: !Ref 'LambdaEventType'
              LambdaFunctionARN: !Ref 'LambdaEdgeVersion'
        CustomErrorResponses:
        - ErrorCachingMinTTL: 0
          ErrorCode: 400
        - ErrorCachingMinTTL: 1
          ErrorCode: 403
        - ErrorCachingMinTTL: 5
          ErrorCode: 500

Таким образом, каждый раз, когда отправляет исходное сообщение шлюза API, он запускает Lambda@Edge, который в настоящее время у меня выглядит так:

# LAMBDA@EDGE FUNCTION
  LambdaEdgeFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Description: !Sub 'A custom Lambda@Edge function for serving custom headers from CloudFront Distribution'
      FunctionName: !Sub '${AppName}-lambda-edge-${Environment}'
      Handler: index.handler
      Role: !GetAtt 'LambdaEdgeIAMRole.Arn'
      MemorySize: 128
      Timeout: 5
      Code:
        ZipFile: !Sub |
          'use strict';

           exports.handler = (event, context, callback) => {
              console.log('Adding additional headers to CloudFront response.');

              const response = event.Records[0].cf.response;
              console.log("Response received:\n", JSON.stringify(response));
              response.headers['strict-transport-security'] = [{
              key: 'Strict-Transport-Security',
              value: 'max-age=86400; includeSubdomains; preload',
              }];
              response.headers['x-content-type-options'] = [{
              key: 'X-Content-Type-Options',
              value: 'nosniff',
              }];
              response.headers['x-frame-options'] = [{
                  key:   'X-Frame-Options',
                  value: "DENY"
              }];
              response.headers['content-security-policy'] = [{
                  key:   'Content-Security-Policy',
                  value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"
              }];
              response.headers['x-xss-protection'] = [{
                  key:   'X-XSS-Protection',
                  value: "1; mode=block"
              }];
              response.headers['referrer-policy'] = [{
                  key:   'Referrer-Policy',
                  value: "same-origin"
              }];
              console.log('Remove Content-Length headers from CloudFront response..');
              delete response.headers["Content-Length"]
              callback(null, response);
            };
      Runtime: nodejs12.x

Когда я отправляю запрос моей конечной точке, я все еще вижу Content-Length в ответе:

curl -i --http1.1 \ 
  --url https://cdn.domain.tld/s/94163e58494
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Content-Length: 316
Connection: keep-alive
Server: CloudFront
Date: Thu, 30 Apr 2020 17:54:54 GMT
Referrer-Policy: same-origin
X-Frame-Options: DENY
x-amz-apigw-id: Lz-VPFnLDoEFbig=
Cache-Control: max-age=0, no-cache, private
Location: http://google.com
Via: 1.1 15c672a1a9***.cloudfront.net (CloudFront), 1.1 0b7c0b1558a4*****.cloudfront.net (CloudFront)
Strict-Transport-Security: max-age=86400; includeSubdomains; preload
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'
X-XSS-Protection: 1; mode=block
x-amzn-RequestId: 0a29a0a9-c14f-4c14-b773-d57813cf91c3
X-Amzn-Trace-Id: Root=1-5eab10ee-50d2c5e08498c8689ad025e0;Sampled=0
X-Amz-Cf-Pop: LHR52-C1
X-Cache: Miss from cloudfront
X-Amz-Cf-Pop: LHR52-C1
X-Amz-Cf-Id: c1KMNm2DOHzfzsIYLBeShWVlxVyaN8yO33hZ3aAAjVIR03x2gx49sw==


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='http://google.com'" />

        <title>Redirecting to http://google.com</title>
    </head>
    <body>
        Redirecting to <a href="http://google.com">http://google.com</a>.
    </body>
</html>

Я следовал https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/ руководство, но я все еще не могу понять, как удалить Content-Length из ответа - возможно ли это?

Любой совет очень ценится

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

Похоже, вы не можете изменить заголовок только для чтения, так как вы получаете эту ошибку:

The Lambda function result failed validation: The function tried to add, delete, or change a read-only header.
0 голосов
/ 03 мая 2020

Что такое LambdaEventType? Для редактирования ответа CloudFront необходимо указать viewer-response.

Ваша функция должна удалять content-length, а не Content-Length, так как имена заголовков в массиве заголовков ожидаются строчными.

delete response.headers["content-length"]

Документация говорит:

Ключи в объекте заголовков являются строчными версиями стандартных имен заголовков HTTP. Использование строчных клавиш дает вам доступ к значениям заголовка без учета регистра.

...