Cloudflare ========== Maintenance ----------- Create an `account API token `__ using the *Read all resources* template that includes *All zones from an account*, and set the ``CLOUDFLARE_API_TOKEN`` environment variable. To compare zones' resources, run: .. code-block:: bash uv run manage.py cloudflare zones > cloudflare-zones.txt To review account-level resources, run: .. code-block:: bash uv run manage.py cloudflare account -a ACCOUNT_ID > cloudflare-account.txt To confirm that no other resources are used, run: .. code-block:: bash uv run manage.py cloudflare unused -a ACCOUNT_ID .. admonition:: Limitations The Terraform `Cloudflare Provider `__ doesn't support DMarc Management and omits Cloudflare-managed rulesets: - ``ddos_l7`` - ``http_request_firewall_managed`` - ``http_request_sanitize`` Zone-level ---------- .. _dns: DNS ~~~ .. _dns-ttl: TTL ^^^ The Time to Live (TTL) of a DNS record indicates how long DNS clients should cache the DNS record. Set the TTL as follows: .. list-table:: :header-rows: 1 * - Purpose - Record type - TTL * - Hostname - A and AAAA - 1 day (86400 seconds) * - High availability service - CNAME - 5 min (300 seconds) * - Other - CNAME - 1 hour (3600 seconds) Proxy status ^^^^^^^^^^^^ .. attention:: `"Proxying is on by default when you onboard a domain via the dashboard." `__ Disable the proxy where relevant. - Proxy A, AAAA and CNAME records for web traffic to OCP servers. .. attention:: If a service expects the client's IP, reconfigure it to use the `CF-Connecting-IP `__ header: for example, `WordFence `__. Inform server operators (like RBC Group and Datanomix) to reconfigure web server logging to use the ``CF-Connecting-IP`` header, as we do for Apache and Nginx. - Proxy A, AAAA and CNAME records for `URL forwarding `__. - Don't proxy A, AAAA or CNAME records for web traffic to Qlik Sense. - Don't proxy A, AAAA or CNAME records for third-party servers, like `GitHub Pages `__, `Netlify `__ or `Super `__. - `Ports for SSH and non-web protocols are closed. `__ Therefore: - **DO NOT** proxy A or AAAA records for hostnames, like ``ocp99``. - **DO NOT** proxy CNAME records for PostgreSQL endpoints. .. tip:: If requests return HTTP 403, determine the reason in `Security Analytics `__. .. note:: Advanced Certificate Manager is required to order an advanced certificate for `sub-subdomains `__ (or to use `Total TLS `__). Reference: `Cloudflare documentation `__ Records reference ^^^^^^^^^^^^^^^^^ .. seealso:: :ref:`monitor-dmarc-reports` .. note:: ``MS=…`` TXT records For `Microsoft domain verification `__ can be deleted. .. list-table:: :header-rows: 1 * - Type - Name - Value - Source * - MX - ``@`` - ``aspmx.l.google.com`` name - `Google Workspace `__ * - MX - ``mail.noreply`` - ``feedback-smtp.us-east-1.amazonses.com`` - `Amazon SES `__ MAIL FROM * - MX - ``noreply`` - ``inbound-smtp.us-east-1.amazonaws.com`` - `Amazon SES `__ receiving * - CNAME - Various - ``ocp##.open-contracting.org`` - OCP * - CNAME - Various - ``pages.dev`` name - GitHub * - CNAME - Various - ``cname.super.so`` - Super * - CNAME - ``cdn.credere`` - ``cloudfront.net`` name - `AWS CloudFront `__ * - CNAME - ``_….cdn.credere`` - ``acm-validations.aws`` name - `AWS Certificate Manager `__ * - CNAME - ``…._domainkey.noreply`` - ``dkim.amazonses.com`` name - `Amazon SES `__ domain * - CNAME - - ``k2._domainkey`` - ``k3._domainkey`` - ``mcsv.net`` name - `Mailchimp `__ * - CNAME - - ``payments`` - ``pr._domainkey`` - ``pr2._domainkey`` - ``sendgrid.net`` name - `Trolley `__ (`SendGrid `__) * - TXT - ``@`` - SPF policy - `Google Workspace `__ * - TXT - ``google._domainkey`` - DKIM key record - `Google Workspace `__ * - TXT - ``sign._domainkey`` - DKIM key record - `SendPulse `__ * - TXT - ``_dmarc`` - DMARC policy - `Google Workspace `__ * - TXT - ``mail.noreply`` - SPF policy - `Amazon SES `__ MAIL FROM * - TXT - ``_dmarc.noreply`` - DMARC policy - `Amazon SES `__ domain * - TXT - ``_smtp._tls`` - `SMTP TLS Reporting `__ policy - `Valimail `__ * - TXT - ``_atproto`` - `DID `__ - `Bluesky `__ * - TXT - ``@`` - ``google-site-verification=…`` - `Google Search Console `__ (per `user `__) * - TXT - ``@`` - ``atlassian-domain-verification=…`` - `Atlassian `__ SSL/TLS ~~~~~~~ `Configure encryption mode `__ is set to *Full (Strict)* to prevent man-in-the-middle attacks, etc. This means that, if certificates don't renew, downtime will occur, unlike when set to *Full*. We get notifications for expiring certificates to mitigate this. SSL/TLS is `configured `__ to `match `__ origin servers: Cipher suites (if enabled) By security Level > Modern Always Use HTTPS Checked Minimum TLS Version TLS 1.2 HTTP Strict Transport Security (HSTS): Enable HSTS (Strict-Transport-Security) Checked Max Age Header (max-age) 12 months Apply HSTS policy to subdomains (includeSubDomains) Checked Preload Checked Security > Settings ~~~~~~~~~~~~~~~~~~~ Continuous script monitoring Checked Manage your robots.txt Disable robots.txt configuration .. attention:: When adding a domain, unchecking *Instruct AI bot traffic with robots.txt* sets this to "Content Signals Policy" instead of "Disable robots.txt configuration". Browser integrity check Unchecked (to allow all requests to ``https://standard.open-contracting.org/schema/``) .. note:: - **DO NOT** enable `Block AI bots `__. Increasingly, users access our content via LLMs. - **DO NOT** enable `Manage your robots.txt `__. Increasingly, users access our content via LLMs. - **DO NOT** enable Bot fight mode. It `"cannot be customized, adjusted, or reconfigured via WAF custom rules" `__ in order to, for example, `allow WordPress sites to reach themselves `__ or to allow all requests to ``https://standard.open-contracting.org/schema/`` from users and CI. Speed ~~~~~ Settings ^^^^^^^^ Content Optimization Speed Brain Checked (see :ref:`cloudflare-rum`) Early Hints Checked Protocol Optimization 0-RTT Connection Resumption Checked Smart Shield ^^^^^^^^^^^^ Use the wizard to check *Smart Tiered Cache*. Caching > Configuration ~~~~~~~~~~~~~~~~~~~~~~~ Browser Cache TTL Respect Existing Headers Rules > Overview ~~~~~~~~~~~~~~~~ To redirect a domain, use the *Redirect to a different domain* template. Account-level ------------- .. _cloudflare-rum: Analytics & logs ~~~~~~~~~~~~~~~~ After migrating nameservers to Cloudflare: Web analytics > Manage site > Real User Measurements (RUM) Enable, excluding visitor data in the EU Pages ~~~~~ - `Login to Cloudflare `__ - Click the *Create application* button - Click the *Pages* tab - Click the *Get started* button for *Import an existing Git repository* - Select the organization from the *GitHub account* dropdown - Select the repository, `configuring access `__ if needed - Click the *Begin setup* button - Set the *Project name* to the repository name - Select the branch from the *Production branch* dropdown, e.g. ``build``, ``gh-pages`` or ``main`` - Click the *Save and Deploy* button - Click the *Custom domains* tab, Click the *Set up a custom domain* button, and follow the prompts Miscellaneous ~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 * - Service - Used by - Domain * - `Turnstile `__ - `Fluent Forms `__ (also available for Highlight and Share) - open-spending.eu .. tip:: When reading details in the `Audig logs `__, the `API documentation `__ describes the ``resource`` values.