# CloudFlare Setup Guide This guide covers setting up CloudFlare for Wizamart, including CDN, proxy, WAF, and R2 storage. ## Overview CloudFlare provides: | Feature | Benefit | |---------|---------| | **CDN** | Global edge caching for static assets | | **Proxy** | Hide origin IP, DDoS protection | | **WAF** | Web Application Firewall (basic rules free) | | **R2** | S3-compatible object storage (~$5/mo) | | **SSL** | Free SSL certificates | --- ## Quick Start ### 1. Add Your Domain to CloudFlare 1. Create a CloudFlare account at [cloudflare.com](https://cloudflare.com) 2. Add your domain and follow the setup wizard 3. Update your domain's nameservers to CloudFlare's ### 2. Configure DNS Records Create these DNS records (with proxy enabled - orange cloud): | Type | Name | Content | Proxy | |------|------|---------|-------| | A | @ | Your server IP | ✅ Proxied | | A | www | Your server IP | ✅ Proxied | | A | api | Your server IP | ✅ Proxied | | CNAME | media | your-bucket.r2.dev | ✅ Proxied | ### 3. Enable CloudFlare in Wizamart ```env # .env CLOUDFLARE_ENABLED=true ``` This enables the CloudFlare middleware to: - Extract real client IPs from `CF-Connecting-IP` - Read client country from `CF-IPCountry` - Track requests via `CF-Ray` header --- ## SSL/TLS Configuration ### Recommended: Full (Strict) Mode 1. Go to **SSL/TLS** > **Overview** 2. Select **Full (strict)** 3. This requires a valid SSL certificate on your origin server ### Origin Certificates For the origin server, you can use: 1. **Let's Encrypt** (recommended for VPS): ```bash sudo certbot --nginx -d yourdomain.com ``` 2. **CloudFlare Origin Certificate** (15-year free cert): - Go to **SSL/TLS** > **Origin Server** - Create Certificate - Install on your server --- ## Caching Configuration ### Page Rules for Static Assets Create page rules for optimal caching: **Rule 1: Static Assets** - URL: `*yourdomain.com/static/*` - Setting: Cache Level → Cache Everything - Setting: Edge Cache TTL → 1 month **Rule 2: Uploads** - URL: `*yourdomain.com/uploads/*` - Setting: Cache Level → Cache Everything - Setting: Edge Cache TTL → 1 week **Rule 3: API (No Cache)** - URL: `*yourdomain.com/api/*` - Setting: Cache Level → Bypass ### Cache Rules (New Interface) Or use the newer Cache Rules: ``` Expression: (http.request.uri.path starts with "/static/") Action: Cache eligible → Override → 30 days ``` --- ## Cloudflare R2 Storage ### Create R2 Bucket 1. Go to **R2** in CloudFlare dashboard 2. Click **Create bucket** 3. Name: `wizamart-media` 4. Location: Choose region closest to your users ### Create API Token 1. Go to **R2** > **Manage R2 API Tokens** 2. Create new token with: - Permission: Object Read & Write - Bucket: Select your bucket 3. Save the **Access Key ID** and **Secret Access Key** ### Configure Wizamart ```env # .env STORAGE_BACKEND=r2 R2_ACCOUNT_ID=your_account_id R2_ACCESS_KEY_ID=your_access_key R2_SECRET_ACCESS_KEY=your_secret_key R2_BUCKET_NAME=wizamart-media ``` ### Enable Public Access (Optional) For direct public access to uploaded files: 1. Go to **R2** > Your bucket > **Settings** 2. Enable **Public Access** 3. Note the public URL: `https://your-bucket.account-id.r2.dev` Or use a custom domain: 1. Go to **R2** > Your bucket > **Settings** > **Custom Domains** 2. Add `media.yourdomain.com` 3. Update `.env`: ```env R2_PUBLIC_URL=https://media.yourdomain.com ``` --- ## Security Settings ### WAF Rules (Free Tier) Enable these managed rules: 1. **CloudFlare Managed Ruleset** - Basic protection 2. **OWASP Core Ruleset** - SQL injection, XSS protection ### Rate Limiting Create rate limiting rules for the API: - URL: `/api/*` - Rate: 100 requests per minute - Action: Challenge or Block ### Bot Fight Mode 1. Go to **Security** > **Bots** 2. Enable **Bot Fight Mode** --- ## Nginx Configuration for CloudFlare When using CloudFlare proxy, update Nginx to trust CloudFlare IPs: ```nginx # /etc/nginx/conf.d/cloudflare.conf # CloudFlare IP ranges set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 108.162.192.0/18; set_real_ip_from 131.0.72.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 162.158.0.0/15; set_real_ip_from 172.64.0.0/13; set_real_ip_from 173.245.48.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 190.93.240.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; # IPv6 set_real_ip_from 2400:cb00::/32; set_real_ip_from 2606:4700::/32; set_real_ip_from 2803:f800::/32; set_real_ip_from 2405:b500::/32; set_real_ip_from 2405:8100::/32; set_real_ip_from 2a06:98c0::/29; set_real_ip_from 2c0f:f248::/32; real_ip_header CF-Connecting-IP; ``` --- ## Environment Variables Reference | Variable | Description | Default | |----------|-------------|---------| | `CLOUDFLARE_ENABLED` | Enable CF header processing | `false` | | `STORAGE_BACKEND` | Storage backend (`local` or `r2`) | `local` | | `R2_ACCOUNT_ID` | CloudFlare account ID | - | | `R2_ACCESS_KEY_ID` | R2 API access key | - | | `R2_SECRET_ACCESS_KEY` | R2 API secret key | - | | `R2_BUCKET_NAME` | R2 bucket name | `wizamart-media` | | `R2_PUBLIC_URL` | Custom public URL for R2 | - | --- ## Verification ### Check CloudFlare is Working 1. **Check headers** in browser DevTools: - `CF-Ray` header should be present - `CF-Cache-Status` shows caching status 2. **Test from command line**: ```bash curl -I https://yourdomain.com/static/css/main.css # Should see CF-Ray and CF-Cache-Status headers ``` ### Check R2 is Working 1. **Upload a test file** via the admin media library 2. **Check the URL** - should point to R2 or your custom domain 3. **Verify in CloudFlare dashboard** - file should appear in bucket ### Check Real IP Logging With `CLOUDFLARE_ENABLED=true`: ```bash # Check application logs journalctl -u wizamart | grep "real_ip" ``` --- ## Troubleshooting ### 521 Error (Web Server Down) - Ensure your origin server is running - Check firewall allows CloudFlare IPs - Verify SSL certificate is valid ### 522 Error (Connection Timed Out) - Check origin server is responding - Verify port 443 is open - Check server isn't overloaded ### 525 Error (SSL Handshake Failed) - Ensure origin has valid SSL certificate - Try CloudFlare Origin Certificate - Check SSL mode is correct (Full vs Full Strict) ### R2 Access Denied - Verify API token has correct permissions - Check bucket name is correct - Ensure bucket policy allows the operation --- ## Cost Estimate | Service | Free Tier | Paid Usage | |---------|-----------|------------| | CDN | Unlimited | Free | | WAF | Basic rules | $20/mo for advanced | | R2 Storage | 10 GB/mo | $0.015/GB | | R2 Requests | 10M Class A, 10M Class B | $0.36/M, $0.0036/M | | SSL | Free | Free | **Typical monthly cost for small-medium site: ~$5-15**