Bulletproof your Application: How to Create a Secure and Exclusive Connection between Amazon CloudFront and Application Load Balancer

2023.04.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Introduction:

Have you ever wished to be sure that your website or application can only be accessed over a secure connection and from your CloudFront distribution? In this blog article, we will walk you through the steps to accomplishing this by establishing an Application Load Balancer (ALB) to accept only CloudFront traffic.

Steps:

Step 1: Configure your ALB for HTTPS/SSL. For a secure connection, set your ALB to use HTTPS/SSL. You can get an SSL certificate from a reliable certificate authority (CA) and install it yourself, or you may utilise ACM. This ensures that the traffic on your website or application is encrypted and cannot be intercepted. Create ACM


 elbCertificate:
  Type: AWS::CertificateManager::Certificate
  Properties:
   DomainName: nfs.classmethod.info
   ValidationMethod: DNS
   SubjectAlternativeNames:
    - "*.xxx.xxxxx.com"
   DomainValidationOptions:
    - DomainName: xxx.xxxxx.com
   ValidationDomain: xxx.xxxxx.com
    - DomainName: "*.xxx.xxxxxx.com"
   ValidationDomain: xxx.xxxxx.com
   Tags:
    - Key: "Name"
      Value: !Sub $devio-elb-acm

Use the above output ARN in ALB listener.


 Listener:
  Type: "AWS::ElasticLoadBalancingV2::Listener"
  Properties:
   DefaultActions:
    - TargetGroupArn: !Ref TargetGroup
      Type: forward
      LoadBalancerArn: !Ref ALB
      Port: 443
      Protocol: HTTPS
    Certificates:
     - CertificateArn: arn:aws:acm:ap-northeast-1:xxxxxxxxx:certificate/dxxxxxxxxxxxxxxxxxx
    SslPolicy: ELBSecurityPolicy-2016-08

Step 2: Construct a CloudFront distribution. Then, for your ALB, establish a CloudFront distribution and set it to utilise HTTPS/SSL. You can also utilise an SSL certificate issued by a reputable CA for this purpose or ACM use the us-east-1 region. This ensures that all communication between your users and CloudFront is secured.

Create the ACM in use-east-1 using same way as done in ALB * CloudFormation Snippet for constructing CloudFront distribution:


Resources:
# ------------------------------------------------------------#
# CloudFront
# ------------------------------------------------------------#
 CloudFront:
  Type: AWS::CloudFront::Distribution
  Properties:
   DistributionConfig:
   IPV6Enabled: false
   Logging:
    Bucket:*****.s3.amazonaws.com
    IncludeCookies: false
    Prefix: !Sub '${SystemName}-${EnvType}-cloudfront-logs/'
   Aliases:
    - 'xxxx.xxx.xxxxx.com'
   ViewerCertificate:
    AcmCertificateArn: arn:aws:acm:us-east-1:xxxxxxxxx:certificate/dxxxxxxxxxxxxxxxxxx
   SslSupportMethod: sni-only
   MinimumProtocolVersion: TLSv1
   DefaultCacheBehavior:
   AllowedMethods:
    - GET
    - HEAD
   CachedMethods:
    - GET
    - HEAD
   CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
   TargetOriginId: elbOrigin
   ViewerProtocolPolicy: https-only
   Enabled: true
   Origins:
    - Id: elbOrigin
   DomainName: xxx.xxx.xxxxxxxx.com
   CustomOriginConfig:
   HTTPSPort: '443'
   OriginProtocolPolicy: https-only
   PriceClass: PriceClass_All

Step 3: Specify the ALB as the origin server In your CloudFront distribution, specify the ALB as the origin server. This will ensure that CloudFront forwards the requests to your ALB. Origins: - Id: elbOrigin DomainName: xxx.xxx.xxxxxxxx.com CustomOriginConfig: HTTPSPort: '443' OriginProtocolPolicy: https-only

Step 4: Configure your ALB to accept traffic only from CloudFront Now, it's time to restrict access to your ALB. Create a security group that allows inbound traffic only from the CloudFront CIDR block(use managed prefix list), and assign it to the ALB. This will ensure that your ALB only accepts traffic from CloudFront, and no one can directly access your ALB.


 Resources:
  ElbSecurityGroup:
   Type: AWS::EC2::SecurityGroup
   Properties:
    GroupName: dev-io-elb-sg
    GroupDescription: devio-elb-sg
    VpcId: network-template-VPCID
    SecurityGroupIngress:
     - IpProtocol: tcp
       FromPort: 443
       ToPort: 443
       SourcePrefixListId: pl-58a04531
    Tags:
     - Key: Name
       Value: devio-elb-sg

Step 5: Send the Host header to the ALB. To ensure that the traffic is coming from CloudFront, send the Host header to the ALB. Enabling the "Forward Headers" option in CloudFront and choosing the "Whitelist" option will do this. Next, include the "Host" header in your whitelist.


OriginCustomHeaders
  HeaderName: String
  HeaderValue: String

Step 6: (Optional) For further security, use Amazon WAF. You may optionally utilise Amazon WAF to give an extra degree of protection to your ALB. You can prohibit any traffic that does not fit your stated criteria by creating a web ACL. You can, for example, block requests that contain dangerous SQL injection attempts. Cloudformation Snipets for Creating WAF And associating it with ALB


  WebACL:
    Type: AWS::WAFv2::WebACL
    Properties:
      Name: devio-webacl-alb'
      DefaultAction:
        Block: {}
      Description: AWS WAFv2 WebACL
      Scope: REGIONAL
      VisibilityConfig:
        CloudWatchMetricsEnabled: true
        MetricName: !Sub '${SystemName}-${EnvName}-webacl-alb'
        SampledRequestsEnabled: true
      Rules:
        - Name: AWS-AWSManagedRulesAnonymousIpList
          Priority: 1
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesAnonymousIpList
          OverrideAction:
            Block: {}
          VisibilityConfig:
            CloudWatchMetricsEnabled: true
            MetricName: !Sub '${SystemName}-${EnvType}-AWSManagedRulesAnonymousIpList'
            SampledRequestsEnabled: true

Conclusion:

By following these steps, you can ensure that your website or application is accessible only through a secure connection and only from your CloudFront distribution.