Qlyne for Cloudflare
Questi contenuti non sono ancora disponibili nella tua lingua.
A connector that sits in front of your site, inside your own Cloudflare account, and applies the rules you set in the Qlyne dashboard:
- a waiting room on the pages you pick (
/tickets/*,/checkout); - a cap on how many people are on the site at once: visitors go straight in while there is room and wait in line when it is full;
- its own challenge (invisible proof-of-work, no Google or Cloudflare Turnstile) on the pages you pick, plus an “under attack” mode that challenges every page view;
- rate limits per page, counted per IP (IPv6 by its /64) or per API key, token or session;
- blocked and trusted IP addresses, and a rule for Tor exit nodes (challenge or block);
- AI crawlers blocked by category (training, AI search, assistants), in your robots.txt too;
- form protection with no captcha: an invisible trap field and a minimum fill time;
- browsers driven by automation tools (Selenium, Puppeteer, Playwright) refused at the challenge;
- an “observe only” mode that records what would be blocked without blocking anyone;
- counters in the dashboard for each of these.
The connector does not call Qlyne on every request. It keeps your rules in memory for 60 seconds, and the waiting room pass and the challenge clearance are signed with a secret that only your connector and Qlyne know, so it checks them on its own. With a cap on people at once, it also asks Qlyne for a slot when someone without a pass arrives. If Qlyne goes down, the connector lets traffic through: protection may fail, your site does not.
This is HTTP-layer (L7) protection. Volumetric network attacks are Cloudflare’s job.
Before you start
Section titled “Before you start”- The Qlyne free plan covers observe mode, IP addresses, AI crawlers and rate limits. The waiting room, the cap on people at once, the challenge, under attack mode, forms and Tor need the Pro plan.
- Your site must go through Cloudflare (DNS record proxied, orange cloud).
- The connector is a Cloudflare Worker. The Workers free plan allows 100,000 requests a day and bursts of up to 1,000 a minute, and every request on the Worker’s routes counts. Route only the pages that need protection, not images or scripts. Busier sites need the Workers paid plan. When the daily limit runs out, each route does what you set for it in Cloudflare: go to your site without the Worker (fail open) or return error 1027 (fail closed).
1. Create your account
Section titled “1. Create your account”- Open the signup page and pick an account ID, your site’s name and your e-mail.
- Open the confirmation link from your e-mail and click “Activate and generate my key”. Save the API key: it is shown only once.
- On the same page, click “Set my password” and choose your dashboard password. The link lasts 60 minutes; after that, use “Forgot your password?” on the login page.
2. Set the rules
Section titled “2. Set the rules”Log in and open your site. Each item below is in the site menu:
- In Connector › Configuration, click “Generate secret” and save it. It is shown only once.
- Add the pages.
*matches anything:/checkout*covers/checkoutand/checkout/pay.- Bot Management › Configuration, “Challenged routes”: pages bots go after, such as login and checkout.
- Waiting Room › Configuration, “Routes on your site”: the page and the queue it sends people to. Queues, the cap on people at once and the pass are on their own page: Waiting Room.
- WAF & Firewall › Configuration, “Rate limits”: Strict (10 per minute), Normal (60) or Loose (300), counted per IP by default. On an API, or anywhere many people share one address (mobile carriers, offices), count per header (
Authorization,X-API-Key) or per session cookie instead. Requests without that header or cookie are counted per IP, and one IP never goes above 10 times the limit, so making up a new key on every request does not get around it. - Account Protection › Configuration, protected forms: the page with the form and the address it posts to. Use it on forms people type into, such as contact, signup and comments; a one-click form (add to cart) is often sent within 2 seconds and would be refused.
- Optionally, list blocked and trusted IP addresses (WAF & Firewall › IP rules), pick a rule for Tor exit nodes (WAF & Firewall › Configuration) and the AI crawler categories to block (Bot Management › Configuration). Trusted addresses (your office, uptime monitors, partners calling your API) skip every rule.
- Leave the mode in Connector › Configuration on “Observe only” for now.
3. Install the connector
Section titled “3. Install the connector”Under Connector › Configuration, “Install on Cloudflare”, click Download connector. The file already carries your account ID and the Qlyne server address.
From the Cloudflare dashboard, no terminal:
- Workers & Pages, Create, Worker: deploy the “Hello World” example.
- Edit code, replace everything with the downloaded connector, Deploy.
- Settings, Variables and Secrets: add a Secret named
QLYNE_SECRETwith your connector secret. - Settings, Domains & Routes: add a route for each page to protect, for example
shop.example.com/checkout*.
This covers the waiting room, the challenge and under attack mode. Rate limits need Wrangler, because Cloudflare does not let you add them in the dashboard (download wrangler.toml again after updating the connector: version 0.6.0 adds the per-IP ceiling for limits counted per header or cookie):
- Also click Download wrangler.toml and put both files in one folder.
- Set your routes in
wrangler.toml. - Run:
npx wrangler loginnpx wrangler secret put QLYNE_SECRETnpx wrangler deploy4. Watch, then enforce
Section titled “4. Watch, then enforce”Visit a protected page, then check the last 24 hours in the site Overview. Many “Would challenge” on ordinary pages usually means a route is too broad; many “Would rate limit” calls for a looser tier. When the numbers make sense, switch the mode to “Enforce” in Connector › Configuration.
During an attack, the “Under attack” button challenges every page view without a clearance cookie (the connector picks it up within a minute). API calls are not challenged, so apps and integrations keep working.
Waiting room and capacity (Pro)
Section titled “Waiting room and capacity (Pro)”The queue by rate, the cap on how many people are on the site at once and the pass are set the same way on every connector: see Waiting Room.
How the connector decides
Section titled “How the connector decides”For each request on the connector’s routes, in this order:
- Someone coming back from the waiting room with
?qlyne_pass=: the connector checks the pass, keeps it in a cookie for that event and redirects to the same address without the parameter. An invalid pass shows an error page instead of sending the person back to the queue, so a wrong secret never turns into a redirect loop. - Trusted IP address: goes to your site with no rule applied.
- Path behind an access gate (Pro), without a gate session: the “Restricted access” page, or
401with{"code": "GATE_REQUIRED"}for API calls. The gate holds in observe mode too. See Access. - Address the scanner trap caught, on this connector or another one of the site:
403on every route for a while (an “Access blocked” page, or{"code": "ACCESS_BLOCKED"}for API calls). - Blocked IP address, or Tor exit node with the “block” rule:
403, with the same page or{"code": "ACCESS_BLOCKED"}. - Address on the shared reputation list, with “Block” (Pro):
403, with the same page or{"code": "ACCESS_BLOCKED"}. With “Challenge”, its page views get the challenge in step 13. - A scanner trap path:
404, and the address is blocked as in step 4. Googlebot and Bingbot from their published ranges are not caught. See Bot Management. - Your rules (Pro), in order: “Block” gets
403; “Let through” goes to your site with no other rule applied; “Challenge” gets the challenge in step 13; “Only log it” is counted and the request goes on. - Request matching a managed rule (WAF) in “Block” mode:
403, with the same “Access blocked” page or{"code": "ACCESS_BLOCKED"}. In “Observe only” it goes on and is counted. - With the bot score on, a medium or high score gets the action you chose for it (Pro): slowed down, challenged,
403or the decoy page. A form or API call to a route that needs the score (Pro), from a browser that has not run the script, gets403with{"code": "SENSOR_REQUIRED"}. - AI crawler from a blocked category, by user agent:
403. Your/robots.txtis served with aDisallow: /group for those crawlers added at the end. - Page with a rate limit, over the limit:
429. - Challenged page (or a rule with “Challenge”, under attack mode, a Tor exit node with the “challenge” rule or a reputation-listed address with “Challenge”; the last three on page views only), no clearance cookie: the challenge page. API calls get
403with{"code": "CHALLENGE_REQUIRED"}. Googlebot and Bingbot pass when their IP is in the ranges Google and Bing publish. A browser controlled by automation software does not get the clearance. The challenge comes before the waiting room, so a bot that fails it never takes a place in line or a slot on the site. - Protected form: a submission with the decoy field filled, or sent less than 2 seconds after the page loaded, gets
403(a “Form not sent” page, or{"code": "FORM_REJECTED"}). See Account Protection. - Login address (Pro): over the tries per account,
429; a leaked password goes on to your app withQlyne-Leaked-Password: 1. See Account Protection. - Page with a waiting room, event active and not over, no valid pass: redirect to the waiting room. API calls (not asking for HTML) get
403with{"code": "QUEUE_REQUIRED", "waiting_room_url": ...}. With a cap on people at once, the connector first asks Qlyne for a slot; with one, the request goes to your site and the pass is set right away. - Everything else goes to your site.
Static files (scripts, styles, images, fonts) get neither the waiting room, the challenge, the form check nor the login check; blocked addresses, AI crawlers and rate limits still apply.
To block AI crawlers, the connector has to run on your whole site (a route like example.com/*), robots.txt included: crawlers fetch every page. On the Workers free plan that uses more of the daily allowance.
Cookies, all HttpOnly; Secure; SameSite=Lax:
| Cookie | What | Lifetime |
|---|---|---|
qlyne_pass_<event> | waiting room pass, signed by Qlyne | the event’s access token TTL (“Free a slot after” when the queue caps people at once), renewed while the person keeps browsing, up to 2 hours after it was issued |
qlyne_clr | challenge clearance, tied to the IP (the /64 for IPv6) and the browser | “Clearance” in the dashboard (30 minutes by default) |
qlyne_bs | bot score, signed by the connector and tied to the IP and the browser (with the bot score on) | 30 minutes |
Access (Pro)
Section titled “Access (Pro)”A password or a sign-in link by e-mail in front of a path such as /admin* has its own page: Access.
Account Protection (Pro)
Section titled “Account Protection (Pro)”Leaked passwords, tries per account and forms that refuse robots are on their own page: Account Protection.
Managed rules (WAF)
Section titled “Managed rules (WAF)”Managed rules, IP lists and rate limits are set the same way on every connector: see WAF & Firewall. On the Worker, the managed rules read form and JSON bodies up to 16 KB, only with a declared size.
Bot Management
Section titled “Bot Management”The bot score and what each score band gets, the challenge settings, verified bots, AI crawlers, the scanner trap, Tor and shared reputation are on Bot Management. On this connector, everything there works except impostor detection and the challenge for browsers that never ran the script.
Your rules (Pro)
Section titled “Your rules (Pro)”Your own rules (block, challenge, let through or only log, by path, country, network, IP and more) are in WAF & Firewall. On the Worker, country and network come from Cloudflare.
Page Shield
Section titled “Page Shield”Security headers and their grade, the Content Security Policy with its violation list and the consent banner are on Page Shield. On this connector, violations are reported through report-uri only, the banner holds scripts but not image pixels or iframes, and there is no page cache.
Signals to your app
Section titled “Signals to your app”Requests that reach your site carry headers your code can use (turn them off in Connector › Configuration, “Signals to your app”):
| Header | Value |
|---|---|
Qlyne-Country | Two-letter country code |
Qlyne-ASN | The visitor’s network number |
Qlyne-Verified-Bot | googlebot or bingbot, confirmed by IP |
Qlyne-Challenge-Passed | 1 when the visitor solved the challenge, on any page |
Qlyne-Trusted-IP | 1 for an address in your trusted list |
Qlyne-Rule | In observe mode, what would have happened, like would_challenge=/checkout*, would_rate_limit=/api/* |
Qlyne-Leaked-Password | 1 on a login whose password is in a known breach (login protection, sent even with the other signals off) |
Qlyne-Gate-User | The e-mail of who signed in at an access gate (sent even with the other signals off) |
Qlyne-Bot-Score | With the bot score on, the visitor’s score from 0 to 100 |
Qlyne-Bot-Reasons | What raised the score, like automation,no_interaction |
Qlyne-Reputation | 1 for an address other Qlyne accounts saw attacking (shared reputation) |
Qlyne-JA4 | The TLS fingerprint, only on Cloudflare plans with Bot Management (Enterprise) |
Headers with these names sent by the visitor are always removed. Trust them only if your origin accepts only Cloudflare’s IP ranges; otherwise someone can reach the origin directly and send the headers themselves.
Rules as code and metrics
Section titled “Rules as code and metrics”Every rule of a site is also a YAML (or JSON) file you can keep in git, authenticated with the account API key from Plan and API key (one key for every site of the account; the site goes in X-Tenant-ID):
# downloadcurl -H "Authorization: Bearer $QLYNE_API_KEY" -H "X-Tenant-ID: your-account" \ "https://app.qlyne.com/api/protection?format=yaml" > qlyne.yaml# check without saving, then apply (drop ?dry_run=1)curl -X PUT -H "Authorization: Bearer $QLYNE_API_KEY" -H "X-Tenant-ID: your-account" \ -H "Content-Type: application/yaml" --data-binary @qlyne.yaml \ "https://app.qlyne.com/api/protection?dry_run=1"PUT replaces the rules: a section missing from the file goes back to its default, and a list in the file replaces the whole list. Errors come back as 422 with the field that failed (challenge.routes, rules.0.conditions.1.values), and an unknown setting is an error too, so a typo does not pass silently. In a CI, run the ?dry_run=1 call on pull requests and the real one on merge.
GET /api/metrics, with the same key, returns the Prometheus metrics of your account only (decisions by action, queue sizes and the rest), for your own Grafana. The scrape config is under Connector › Configuration, “Rules as code”.
What it does not do
Section titled “What it does not do”- The limits of the challenge, the bot score and AI crawler detection are on Bot Management.
- The pass is not tied to the browser: a copied pass cookie works elsewhere until it expires (at most 2 hours after it was issued). With a cap on people at once, everyone using the copy counts as one person.
- The cap on people at once can be filled by someone with many IP addresses. A challenge on the same pages makes each slot cost a proof-of-work.
- Form protection has limits, such as a bot that waits and leaves the decoy empty: see Account Protection.
Messages in your Cloudflare logs
Section titled “Messages in your Cloudflare logs”| Message | Meaning |
|---|---|
the config is not signed by the Qlyne server | The connector file or QLYNE_CORE_URL does not match the Qlyne server. Download the connector again; nothing is blocked meanwhile. |
the Qlyne server refused the config (401) | QLYNE_SECRET is not the current connector secret. Nothing is blocked until you fix it. |
QLYNE_SECRET is not set, or this is not the connector file downloaded from the dashboard | Add the secret, or download the connector again. Nothing is blocked. |
waiting room pass refused | Someone came back with an invalid or expired pass. If it happens to everyone, check the secret. |
could not reach the Qlyne server | The connector keeps the last rules it had; with none, it lets traffic through. |
could not reach the Qlyne server for an admission, the Qlyne server answered ... to an admission request | Qlyne did not give a slot in time. The connector lets visitors in and asks again 10 seconds later. |