Skip to content

IP-Block-Ltd/ipblock-aws-cloudfront

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚠️ Status: untested. This extension is provided as-is and has not been tested in production. Please feel free to fork, modify, improve, and open pull requests.

Licensed under GNU GPLv3 (see LICENSE).

IP Block - AWS CloudFront (Lambda@Edge)

Screens CloudFront traffic against ip-block.com at the edge, returning a 403 (or redirect) for blocked visitors and letting clean requests continue to your origin.

  • Trigger: CloudFront Viewer Request
  • Runtime: Node.js 20.x Lambda@Edge (us-east-1, then replicated)
  • Client IP source: request.clientIp
  • Decision cache: warm-container in-memory map (per-IP)

Files

File Purpose
index.js The Lambda@Edge handler (screen -> allow/block)
README.md This document (deploy + IAM steps)

Why Lambda@Edge and not a CloudFront Function?

CloudFront offers two edge compute options:

  • CloudFront Functions - ultra-light JS, runs on every request, but the sandbox cannot make network calls (no fetch/http, no external I/O). It therefore cannot call the ip-block.com API. Use it only for header/URL rewrites.
  • Lambda@Edge - full Node.js with outbound networking. This is required to call an external screening API, so this integration uses Lambda@Edge on the viewer-request trigger.

How it works

  1. Reads the real client IP from request.clientIp.
  2. Skips the lookup for whitelisted IPs and when enabled=false.
  3. Checks an in-process cache (persists while the edge container stays warm).
  4. On a miss, POSTs to https://api.ip-block.com/v1/check with a ~1s timeout using the Node https module, then caches the decision for cacheTtls.
  5. Blocks only when the API returns {"action":"block"}. Any error, timeout, non-2xx, or missing action fails open unless failOpen=false.

Configuration

Lambda@Edge does not support environment variables, so configuration is inline in the CONFIG object at the top of index.js. Edit it before publishing:

Field Default Meaning
enabled true Master on/off switch
siteId - Your ip-block.com site id
apiKey - Your API key
apiUrl https://api.ip-block.com/v1/check Screening endpoint
failOpen true Allow on error/timeout
cacheTtl 300 Seconds to cache a per-IP decision
timeoutMs 1000 API timeout (~1s)
blockAction "403" "403" or "redirect"
redirectUrl https://www.ip-block.com/blocked.php Used when blockAction="redirect"
whitelist [] IPs to always allow

Prefer not to inline the key? At cold start, read it from AWS Secrets Manager or SSM Parameter Store instead (adds a little latency; grant the role access).

Deploy

Lambda@Edge functions must be created in us-east-1 and published as a numbered version (aliases and $LATEST are not allowed on the trigger).

# 1. Package the function
cd extensions/AWS-CloudFront
zip -r function.zip index.js

# 2. Create the function in us-east-1
aws lambda create-function \
  --function-name ip-block-protection \
  --runtime nodejs20.x \
  --handler index.handler \
  --role arn:aws:iam::<ACCOUNT_ID>:role/ip-block-edge-role \
  --zip-file fileb://function.zip \
  --region us-east-1

# 3. Publish an immutable version (note the returned Version number)
aws lambda publish-version \
  --function-name ip-block-protection \
  --region us-east-1

Then attach it to your distribution: CloudFront console -> your distribution -> Behaviors -> edit the behavior -> Function associations -> Viewer request = Lambda@Edge -> paste the versioned ARN (arn:aws:lambda:us-east-1:<ACCOUNT_ID>:function:ip-block-protection:<VERSION>) -> save and wait for the distribution to deploy.

Updating: edit index.js, update-function-code, publish-version, then point the behavior at the new version ARN.

IAM

Execution role (ip-block-edge-role) trust policy must allow both edge services to assume it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": ["lambda.amazonaws.com", "edgelambda.amazonaws.com"]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Attach AWSLambdaBasicExecutionRole for CloudWatch Logs (logs are written in each edge Region). Add secretsmanager:GetSecretValue / ssm:GetParameter only if you choose to load the API key from a secret store.

Protecting a SaaS storefront

Put a CloudFront distribution in front of the SaaS custom domain (origin = the platform's hostname) and attach this function to the viewer-request event. Every visitor is screened at the edge before CloudFront forwards to the origin.

About

IP Block protection for AWS CloudFront (Lambda@Edge) — ip-block.com integration. Untested at the moment; please feel free to modify. GPLv3.

Topics

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors