A Cloudflare Worker for secure, configurable HTTP redirects by subdomain. It routes requests for specific subdomains (for example foo.example.com) to target URLs (for example secure.com). It also provides optional Basic Auth with support for both single and multiple user/password pairs, rate limiting and security headers.
- Features
- Quick Start
- Environment Variables
- How it Works
- Installation & Development
- Testing
- Author & Licence
- HTTPS Enforcement: Redirects HTTP requests to HTTPS
- Subdomain-Based Redirects: Map a subdomain (e.g.
foo.example.com) to a redirect target URL configured via environment variables (LINK_FOO) - Multi-level Subdomains: Supports subdomains with multiple levels (e.g.
api.v1.example.com), mapping them to environment variables by replacing dots with underscores (LINK_API_V1) - Protected Subdomains with Basic Auth: Require HTTP Basic Auth for configurable subdomains. Supports both a single user/password or multiple user/password pairs per subdomain.
- In-Memory Rate Limiting: Simple per-client + per-subdomain throttling of failed authentication attempts to mitigate brute-force attacks
- Security Headers: Responses include common security headers to reduce risk of common web attacks
You will learn how to deploy the worker to Cloudflare, configure secrets and point DNS records for your subdomains to the worker route. Additionally, you will configure environment variables as secrets for routing and authentication.
Cloudflare always requires a code source (repository or ZIP) to deploy a Worker. Choose one of the following:
- Git (recommended): Fork this repository into your own GitHub/GitLab account.
- ZIP (manual upload): Download the code as a ZIP file and prepare it for upload.
- Log in to the Cloudflare Dashboard.
- Navigate to Workers & Pages -> Workers and create a new Worker with the name
redirect-worker.
Note: See the Environment Variables section below for variable descriptions and an example configuration.
There are multiple ways to provide environment variables for your Worker:
- Cloudflare Dashboard: Set them directly in the Cloudflare Dashboard (Worker -> Settings -> Variables & Secrets). This keeps sensitive values out of your source code and version control.
- Wrangler: You can define them in your
wrangler.tomlfile (not recommended for secrets or sensitive data if your repository is public). - CI pipeline: You can deliver them through your CI/CD pipeline or other deployment automation.
Important: If you deploy using Cloudflare Git integration, any variables set in the Cloudflare Dashboard as plain text or JSON will be overwritten during deployment.
To prevent this:
- Option 1: Add
--keep-varsto your deployment command in Settings -> Build -> Deploy command (e.g.,npx wrangler deploy --keep-vars).- Option 2: Set your variables as secrets in the Dashboard, which are always preserved.
- Cloudflare Git integration (recommended): Connect your forked repository directly to your GitHub/GitLab account in the Cloudflare Dashboard. Cloudflare will build and deploy automatically. Additional information about the Git integration for Cloudflare Workers can be found in the Cloudflare documentation.
- ZIP (manual upload): Upload your prepared ZIP file using the Dashboard’s editor or deployment UI.
- Wrangler: Deploy from your local checkout with
npm run deploy. - CI pipeline: If you want to have control over the CI checks and deployment, you can set up your own pipeline that runs the tests and deploys to Cloudflare. You can use the same CI configuration as this repository, which is available in
.github/workflows/ci.yml. Make sure to update the deployment step with your own Cloudflare API credentials and Worker name. Additional information on setting up CI/CD pipelines for Cloudflare Workers can be found in the Cloudflare documentation.
Important: When using Cloudflare Git integration, go to Settings -> Build -> Branch Control in your Worker project. Make sure to deactivate (uncheck) the option for enabling builds for non-production branches. If this setting is active, any push to your
develop(or other non-production) branch will trigger a deployment to your Worker, which may not be desired for production stability.
- Navigate to Settings -> Routes and add a domain or route for the Worker.
- Point DNS records for your subdomains to the Worker you configured.
ALLOWED_HOST_SUFFIXES- Comma-separated list of allowed host suffixes
- Only requests to hostnames ending with these suffixes will be processed
PROTECTED_SUBDOMAINS- Comma-separated list of subdomains that require authentication
LINK_<SUBDOMAIN>- Redirect target URL for each subdomain
- Example:
LINK_FOOforfoo.example.com - Multi-level subdomains: Dots are replaced with underscores
- Example:
api.v1.example.com->LINK_API_V1
- Basic Auth User/Password Support:
- You can protect a subdomain with either a single user/password or multiple user/password pairs:
- Single user/password:
USER_<SUBDOMAIN>,PASS_<SUBDOMAIN>- Example:
USER_FOO,PASS_FOOforfoo.example.com - Multi-level subdomains: Dots are replaced with underscores
- Example:
api.v1.example.com->USER_API_V1,PASS_API_V1
- Multiple user/password pairs:
USERS_<SUBDOMAIN>- JSON array of user/pass objects for a subdomain
- Example:
USERS_FOO = '[{"user":"alice","pass":"pw1"},{"user":"bob","pass":"pw2"}]' - Multi-level subdomains: Dots are replaced with underscores
- Example:
api.v1.example.com->USERS_API_V1 - If present, this takes precedence over
USER_<SUBDOMAIN>/PASS_<SUBDOMAIN>
FALLBACK_USER,FALLBACK_PASS- Optional fallback credentials if specific subdomain credentials are not set
ALLOWED_HOST_SUFFIXES = ".example.com,.example.org"
PROTECTED_SUBDOMAINS = "foo,secure,api.v1"
LINK_PUBLIC = "https://www.public.com/"
LINK_FOO = "https://foo-website.com/"
# Single user/password for foo.example.com
USER_FOO = "foo_user"
PASS_FOO = "foo_password"
# Or, multiple users for foo.example.com (overrides USER_FOO/PASS_FOO if set)
USERS_FOO = '[{"user":"alice","pass":"pw1"},{"user":"bob","pass":"pw2"}]'
LINK_SECURE = "https://secure.com/"
USER_SECURE = "secure_user"
PASS_SECURE = "secure_password"
LINK_API_V1 = "https://api-v1.company.com/"
USERS_API_V1 = '[{"user":"apiuser","pass":"apipw"}]'
FALLBACK_USER = "fallback_user"
FALLBACK_PASS = "fallback_password"- The worker checks the request hostname against
ALLOWED_HOST_SUFFIXES. - It extracts the subdomain and resolves its redirect target from
LINK_<SUBDOMAIN>. - If the subdomain is listed in
PROTECTED_SUBDOMAINS, the worker enforces Basic Auth using configured credentials. You can use either a single user/password or a list of user/password pairs for each subdomain. - Failed auth attempts are rate-limited per client.
- Valid requests are redirected with proper security headers.
-
Clone the Repository
git clone https://github.com/jasonhaak/redirect-worker.git cd redirect-worker -
Install Dependencies
npm install
-
Configure Environment Variables
- You can set environment variables in your
wrangler.tomlfile.
- You can set environment variables in your
-
Test the Worker Locally
npm wrangler dev
This project uses Vitest for unit tests. Run the suite locally:
npm testThe test suite covers authentication, including both single-user and multi-user Basic Auth, host parsing, rate limiting, security headers and utility functions.
This code was written by Jason Haak and is licensed under the MIT licence.