Cloudflare setup for business websites: speed and security, step by step
Putting a business website behind Cloudflare takes an afternoon and removes whole categories of problems: slow pages for distant visitors, traffic floods, bots hammering your login. It also introduces new ways to break things if it is done carelessly. This guide covers the setup order, the settings that matter, and the mistakes we see most often.
TL;DR
- Cloudflare does three jobs for you: DNS, a global cache (CDN) and a security layer in front of your server (DDoS protection, firewall rules, bot filtering).
- Use SSL mode Full (strict), never Flexible. Then lock your server so it accepts web traffic only from Cloudflare, otherwise attackers can simply bypass it.
- Cache static files aggressively, never cache private or admin pages, and purge the cache automatically when you deploy.
- Add a few targeted rules: rate limit login and checkout, and exempt payment webhooks from challenges.
- Mail records must stay DNS-only, and your logs need the real visitor IP restored. These two details cause most "it broke after Cloudflare" tickets.
Cloudflare sits between your visitors and your server. Visitors connect to Cloudflare's nearby data center, which serves cached files directly, filters hostile traffic and forwards the rest to your server. For a business, that means faster pages for customers far from your hosting location, protection from simple denial-of-service floods and a place to enforce security rules without changing application code. Many plans start free, and paid plans add features, so check the current plan comparison before deciding.
It is not a substitute for patched software and secure code. Our PHP security checklist still applies. Think of Cloudflare as a strong front door, not a replacement for locking the rooms inside.
Before you start
- Take inventory of your DNS. Export or screenshot every record at your current DNS provider, including mail (MX, SPF, DKIM, DMARC) and verification records. A missed record is the classic way to break email during a migration.
- Know who owns the domain registrar account and make sure it is a company account with multi-factor authentication. You will change the nameservers there.
- Lower the TTL of your key records a day ahead if you can, so changes spread faster.
- Pick a quiet time and tell the team. Plan a rollback: the old nameservers, written down.
Step 1: add the site and review DNS
Add your domain in the Cloudflare dashboard. It scans existing records. Compare them with your inventory and fix gaps. For each record choose between two modes:
- Proxied (orange cloud): traffic goes through Cloudflare. Use for your website and web application hostnames.
- DNS only (grey cloud): Cloudflare just answers the DNS query. Use for mail servers, SSH or FTP hostnames, and anything that is not HTTP or HTTPS traffic.
Then update the nameservers at your registrar. Once the site shows as active, check your site and send a test email.
Step 2: set up encryption correctly
This is the setting that breaks the most sites. Cloudflare has several SSL/TLS modes:
- Flexible: encrypts visitor to Cloudflare but sends traffic to your server unencrypted. It looks like it works, but the second leg is open, and it often causes redirect loops. Avoid it.
- Full: encrypts both legs but does not verify your server's certificate.
- Full (strict): encrypts both legs and verifies the certificate on your server. This is the one to use.
Install a valid certificate on your server first. A Cloudflare Origin CA certificate or a free Let's Encrypt certificate both work. Then switch to Full (strict), turn on Always Use HTTPS, set a minimum TLS version of 1.2, and enable HSTS only after everything works over HTTPS, because HSTS tells browsers to refuse plain HTTP for a long time.
Step 3: make Cloudflare impossible to bypass
If attackers know your server's real IP address, they can send traffic straight to it and skip every protection you configured. Fix this in two ways:
- Allow web traffic to your server only from Cloudflare's published IP ranges.
- Restore the real visitor IP in your web server, because otherwise every request in your logs, rate limits and analytics appears to come from Cloudflare.
#!/usr/bin/env bash
# /opt/cf/update_cloudflare_ips.sh - run weekly from cron
set -euo pipefail
IPS="$(curl -fsS https://www.cloudflare.com/ips-v4) $(curl -fsS https://www.cloudflare.com/ips-v6)"
# 1) real visitor IP for Nginx
OUT=/etc/nginx/conf.d/cloudflare_real_ip.conf
{
for r in $IPS; do echo "set_real_ip_from $r;"; done
echo "real_ip_header CF-Connecting-IP;"
} > "$OUT.tmp" && mv "$OUT.tmp" "$OUT"
nginx -t && nginx -s reload
# 2) firewall: allow HTTPS only from Cloudflare (remove any generic "allow 443" rule first)
for r in $IPS; do ufw allow proto tcp from "$r" to any port 443 comment 'cloudflare'; done
One important detail for Docker users: ports published by Docker bypass ufw rules. Bind containers to localhost behind a reverse proxy, or restrict access in Docker's DOCKER-USER firewall chain. For stronger isolation, Cloudflare Tunnel lets your server make an outbound connection only, so it needs no open inbound web ports at all. For payments webhooks and other server-to-server integrations, make sure the IP rules still let those requests through if they do not go via Cloudflare.
Step 4: caching rules
By default Cloudflare caches static files such as images, CSS and JavaScript, but not HTML. A sensible policy for a typical PHP site:
- Static assets: cache for a long time (a month or more). Use versioned file names or a query string such as
app.css?v=123so a new deployment is picked up immediately. - Public HTML pages (marketing pages, blog): can be cached for minutes to hours with a Cache Rule. Test carefully.
- Never cache: admin, account, cart, checkout, API endpoints and any page that depends on a login cookie. Create a bypass rule for these paths and for requests carrying your session cookie.
Purge automatically after each deployment so customers never see stale files. Create an API token with only the "Cache Purge" permission for this zone, and call it from your deploy script:
# purge selected files after a deployment
curl -sS -X POST "https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"files":["https://example.com/css/app.css","https://example.com/js/app.js"]}'
Faster pages also help search and conversions. See our Core Web Vitals guide for PHP sites for what to fix on the server side once the CDN is in place.
Step 5: firewall, bots and rate limiting
- Turn on the managed WAF rules available on your plan. They block common attack patterns before they reach your code.
- Enable bot protection suited to your plan and watch the analytics before tightening anything.
- Rate limit sensitive endpoints: login, password reset, sign-up and checkout. Brute-force and card-testing attacks target exactly these.
- Exempt trusted machine traffic: payment provider webhooks, monitoring services and your own integrations must not be hit by browser challenges, since a challenge page returned to a webhook looks like a failure.
# Custom rule 1: block probes for secrets and repositories (action: Block)
(http.request.uri.path contains "/.env" or http.request.uri.path contains "/.git" or http.request.uri.path contains "wp-config")
# Custom rule 2: let payment webhooks through (action: Skip, security features)
(http.request.uri.path in {"/webhooks/stripe" "/webhooks/paypal"})
# Rate limiting rule: at most 10 login attempts per minute per IP
(http.request.uri.path eq "/login" and http.request.method eq "POST") => 10 requests / 1 minute / IP
Rule syntax and available fields vary by plan, so treat these as templates and test in "log" mode first. Keep application-level protections too: webhook signature checks, as in our Stripe webhooks guide, never depend on network rules alone.
Step 6: verify the setup
# is traffic going through Cloudflare?
curl -sI https://example.com | grep -iE "^(server|cf-cache-status|cf-ray)"
# does the origin refuse direct access? (replace with your server IP; expect a timeout or refusal)
curl -sI --max-time 8 https://203.0.113.10 -H "Host: example.com" -k
# are the nameservers and mail records right?
dig NS example.com +short
dig MX example.com +short
dig TXT example.com +short
Check a static file twice: the second response should show cf-cache-status: HIT. Check the login, checkout and admin flows with a real browser, and send and receive a test email.
Common mistakes
- Flexible SSL and the redirect loops that follow.
- Proxying the mail hostname (it must be DNS only) or forgetting a mail record during the move.
- Caching private pages, so one customer sees another's account page. Always bypass cache for logged-in traffic.
- Leaving the origin exposed: the real IP is visible in old DNS records, email headers or certificate logs. Restrict the firewall and consider changing the IP if it has leaked.
- Not restoring the real IP, which breaks rate limits, logs and fraud checks.
- Challenging webhooks and APIs, which causes silent failures in payments and integrations.
- Request size limits: proxied requests have a maximum body size depending on the plan. Check the current limit if your application accepts large uploads.
- Forgetting monitoring. Add alerts for certificate and domain expiry and keep uptime checks, as described in our backup and monitoring guide.
A one-page checklist
- DNS inventory exported, registrar account secured.
- Site added, records reviewed, proxied only for web hostnames.
- Origin certificate installed, SSL mode Full (strict), Always Use HTTPS on.
- Firewall limited to Cloudflare ranges, real visitor IP restored.
- Cache rules for static assets, bypass for private paths, purge in the deploy script.
- Managed WAF on, rate limits for login and checkout, webhooks exempted.
- Verification commands run, alerts configured, rollback documented.
How we can help
We configure Cloudflare, hosting and deployment pipelines for PHP applications and connect them to payment, CRM and messaging systems. Read about our integrations service or book a short call and we will review your DNS, SSL and caching setup against this checklist.
Frequently asked questions
Is Cloudflare worth it for a small business website?
For most public websites, yes. Faster delivery of static files, DDoS protection, free managed DNS and easy HTTPS are valuable even on a free plan. Paid plans add stronger firewall, bot and performance features. Check the current plan comparison for what you need.
Which SSL mode should I use?
Full (strict). It encrypts traffic between the visitor and Cloudflare and between Cloudflare and your server, and it verifies your server's certificate. Avoid Flexible, which leaves the connection to your server unencrypted and often causes redirect loops.
Can attackers bypass Cloudflare?
Yes, if they find your server's real IP and it accepts traffic from anywhere. Restrict your firewall to Cloudflare's published IP ranges, or use Cloudflare Tunnel, and change the IP if it has leaked.
Why did my email stop working after moving DNS to Cloudflare?
Usually a mail record was missed in the migration, or the mail hostname was set to proxied. Mail records such as MX, SPF, DKIM and DMARC must be present and the mail server hostname must be DNS only.
Should I cache HTML pages on Cloudflare?
You can for public pages like marketing and blog content, using Cache Rules and a sensible expiry. Never cache admin, account, cart, checkout or any personalized page, and purge the cache on each deployment.
Free discovery call
Bring a messy stack or stalled integration - Integrono will map the smartest first move.
You get a senior take on budget traps, dependencies and whether to buy, glue or build - before paid work starts. The CEO stays in the loop.