100% scoren op internet.nl met Cloudflare
Deze handleiding helpt je om de maximale score te halen op internet.nl, met de nieuwe TLS richtlijnen van het NCSC (2025), wanneer je website achter Cloudflare zit. Welke score je kunt halen hangt af van je TLS-configuratie.
Minimum TLS 1.3
De makkelijkste manier om 100% te scoren is simpelweg de minimale TLS-versie op 1.3 te zetten. Op deze manier heb je ook geen Advanced Certificate Manager (ACM) of aangepaste cipher suite configuratie nodig.
De afweging: clients die alleen TLS 1.2 ondersteunen (oudere apparaten, sommige bots) kunnen geen verbinding meer maken. Alle moderne browsers en besturingssystemen ondersteunen TLS 1.3.
Minimum TLS 1.2 met ACM
Wanneer je TLS 1.2 clients moet ondersteunen, kun je op dit moment niet de volledige 100% halen. Cloudflare accepteert namelijk verbindingen waarbij de client alleen SHA-1 als signature-algoritme aanbiedt (ยง3.3.5 van de NCSC richtlijnen).
De impact hiervan is in de praktijk minimaal: SHA-1 wordt alleen gebruikt als de client geen sterkere algoritmes zoals SHA-256 adverteert. De server kiest er dan voor om de verbinding toch te laten slagen in plaats van af te breken. Voor clients die alleen TLS 1.2 ondersteunen is upgraden naar TLS 1.3 de belangrijkste stap โ dat biedt meer veiligheidswinst dan het uitsluiten van SHA-1.
Als onderdeel van Cloudflare's strategie om zoveel mogelijk verkeer af te handelen door middel van moderne, veilige Rust code (zie Cloudflare just got faster and more secure, powered by Rust), zal ook het TLS sessie afhandeling systeem (gebaseerd op NGINX) gemigreerd worden. Dit zal gefaseerd gebeuren en een vaste tijdslijn is er op dit moment niet.
Om de overige cipher suite tests te halen moet Cloudflare geconfigureerd worden met de Modern cipher suite lijst. Hiervoor is Advanced Certificate Manager (ACM) nodig (een betaalde feature).
๐ 100% nodig maar TLS 1.2 vereist?
Heeft jouw organisatie een strikte verplichting om 100% te scoren maar kun je TLS 1.2 niet uitschakelen? Neem dan contact op met je Cloudflare-accountteam โ er zijn opties beschikbaar, maar deze vereisen aanvullende architectuurkeuzes en begeleiding.
Minimum TLS 1.2 zonder ACM
De standaard lijst met cipher suites die gebruikt wordt met Universal SSL is het zgn. "Legacy" security niveau. Deze lijst bevat cipher suites die onvoldoende zijn volgens de NCSC richtlijnen.
Post-quantum cryptografie (PQC)
Helaas ondersteunt internet.nl nog geen rapportage op ondersteuning van hybride sleuteluitwisselingsalgoritmes (waarin 'klassieke' en 'quantumveilige' algoritmes gecombineerd worden). Websites achter Cloudflare ondersteunen dit echter automatisch, zonder verdere configuratie: Post-quantum cryptography.
Cloudflare Radar biedt ook een tool aan om te checken of een website al een hybride sleuteluitwisselingsalgoritme ondersteunt: Radar PQC checker.
Instructies
Hieronder volgen de instructies om Cloudflare op de juiste manier in te stellen. Deze instructies zijn bewust in het Engels.
๐ง Tip: gebruik een AI-agent
Laat je LLM deze pagina lezen (de site serveert ook markdown) en gebruik de Cloudflare Skills om je zone automatisch te configureren.
Scoring 100% on internet.nl with Cloudflare
This guide helps you achieve the maximum score on internet.nl, with the new NCSC TLS guidelines (2025), when your website is behind Cloudflare. The score you can achieve depends on your TLS configuration.
Minimum TLS 1.3
The easiest way to score 100% is to simply set the minimum TLS version to 1.3. This way you also don't need Advanced Certificate Manager (ACM) or custom cipher suite configuration.
The tradeoff: clients that only support TLS 1.2 (older devices, some bots) will no longer be able to connect. All modern browsers and operating systems support TLS 1.3.
Minimum TLS 1.2 with ACM
When you need to support TLS 1.2 clients, you currently cannot achieve the full 100%. Cloudflare accepts connections where the client only offers SHA-1 as a signature algorithm (ยง3.3.5 of the NCSC guidelines).
The practical impact is minimal: SHA-1 is only used when the client doesn't advertise stronger algorithms like SHA-256. The server then chooses to allow the connection rather than dropping it. For clients still on TLS 1.2, upgrading to TLS 1.3 is the most impactful step โ it provides far greater security benefits than eliminating SHA-1.
As part of Cloudflare's strategy to handle as much traffic as possible using modern, secure Rust code (see Cloudflare just got faster and more secure, powered by Rust), the TLS session handling system (based on NGINX) will also be migrated. This will happen in phases and there is no fixed timeline at this point.
To pass the remaining cipher suite tests, Cloudflare must be configured with the Modern cipher suite list. This requires Advanced Certificate Manager (ACM) (a paid feature).
๐ Need 100% but require TLS 1.2?
Does your organization have a strict requirement to score 100% but cannot disable TLS 1.2? Contact your Cloudflare account team โ there are options available, but they require additional architecture decisions and guidance.
Minimum TLS 1.2 without ACM
The default cipher suite list used with Universal SSL is the so-called "Legacy" security level. This list contains cipher suites that are insufficient according to the NCSC guidelines.
Post-quantum cryptography (PQC)
Unfortunately, internet.nl does not yet report on support for hybrid key exchange algorithms (combining 'classical' and 'quantum-safe' algorithms). Websites behind Cloudflare automatically support this, without any configuration: Post-quantum cryptography.
Cloudflare Radar also offers a tool to check whether a website already supports a hybrid key exchange algorithm: Radar PQC checker.
๐ง Tip: use an AI agent
Point your LLM at this page (the site also serves markdown) and use the Cloudflare Skills to configure your zone automatically.
Prerequisites
๐ฐ Advanced Certificate Manager (ACM) โ only needed with minimum TLS 1.2
ACM ($10/zone/month) is required when using minimum TLS 1.2. Without it, you cannot restrict cipher suites to the Modern preset โ the Legacy preset includes CBC, 3DES, and static-RSA ciphers that fail the NCSC-NL TLS guidelines. If you set minimum TLS version to 1.3, ACM is not needed.
All API examples below use $ZONE_ID and $CF_API_TOKEN. Set them in your shell:
export ZONE_ID="<your zone id>"
export CF_API_TOKEN="<token>" Token permissions needed: Zone Settings Write, SSL and Certificates Write, DNS Write, Zone Rulesets Write.
IPv6 Automatic
Nameserver and web server reachability over IPv6.
Nameserver IPv6
Cloudflare's *.ns.cloudflare.com nameservers are dual-stack and covered by AS13335 ROAs. Passes automatically when your registrar delegates to Cloudflare nameservers.
Web server IPv6
For any proxied (orange-cloud) record, Cloudflare automatically serves AAAA responses. The IPv6 Compatibility setting must be enabled (it is by default).
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/ipv6" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"on"}' DNSSEC Configuration needed
Domain signature validation. Requires both enabling at Cloudflare and adding the DS record at your registrar.
A modal will display the DS record values (Algorithm 13, ECDSA P-256/SHA-256, Digest Type 2). Copy these values to your registrar.
# Enable zone signing
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dnssec" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"status":"active"}'
# Retrieve the DS record to add at your registrar
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dnssec" \
-H "Authorization: Bearer $CF_API_TOKEN" โ ๏ธ Registrar action required
Paste the DS record into your registrar's control panel. Without the DS at the parent zone, DNSSEC validation fails.
๐จ Migration warning
If migrating a zone to Cloudflare, disable DNSSEC at the old provider first. Leaving an old DS record during a nameserver swap breaks DNS resolution.
HTTPS & TLS Configuration needed
Covers 12 internet.nl subtests: HTTPS redirect, HSTS, TLS versions, key exchange, compression, renegotiation, 0-RTT, OCSP, EMS, and certificate validation.
HTTPS redirect & SSL mode
Enable Always Use HTTPS and set the encryption mode to Full (strict).
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/ssl" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"strict"}'
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/always_use_https" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"on"}'
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/automatic_https_rewrites" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"on"}' ๐ Origin certificate
Full (strict) requires your origin to present a valid certificate on port 443. Use a Cloudflare Origin CA certificate or a public CA cert.
HSTS
Required: max-age โฅ 31,536,000 (1 year), with includeSubDomains and preload.
Set: Max Age = 12 months, Include subdomains = On, Preload = On, No-Sniff = On.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/security_header" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"value": {
"strict_transport_security": {
"enabled": true,
"max_age": 31536000,
"include_subdomains": true,
"preload": true,
"nosniff": true
}
}
}' TLS version
โน๏ธ Minimum TLS 1.3 vs 1.2
Your choice of minimum TLS version determines both the maximum internet.nl score and whether you need ACM:
- Minimum TLS 1.3 โ 100% score possible. No ACM or cipher suite changes needed โ TLS 1.3 cipher suites are compliant by default. Older TLS 1.2-only clients will be dropped.
- Minimum TLS 1.2 โ 98% score (currently). Requires ACM to set cipher suites to Modern. The SHA-1 hash function limitation prevents 100%.
If you previously configured custom cipher suites (e.g. the Modern preset via ACM), you must first reset them to the default (Legacy) before you can change the minimum TLS version to 1.3. Cloudflare does not allow custom cipher suite configuration combined with minimum TLS 1.3.
Option A: Minimum TLS 1.3 (for 100%)
If you have custom cipher suites configured, reset them first, then set minimum TLS version to 1.3.
(Only needed if you previously changed cipher suites. Skip if they are already on the default.)
# Reset cipher suites to default (only if previously customized)
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/ciphers" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":[]}'
# Set minimum TLS version to 1.3
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/min_tls_version" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"1.3"}' Option B: Minimum TLS 1.2 (for 98%, requires ACM)
Set minimum TLS version to 1.2 and enable TLS 1.3. Then configure cipher suites to Modern (see Cipher suites section below). Do not set TLS 1.3 to "zrt" โ that enables 0-RTT.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/min_tls_version" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"1.2"}'
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/tls_1_3" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"on"}' 0-RTT (must be off)
Internet.nl requires 0-RTT to be disabled. It is off by default โ just confirm.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/0rtt" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{"value":"off"}' Automatic subtests (no configuration needed)
These subtests pass automatically on Cloudflare's edge:
| Subtest | Why it passes |
|---|---|
| Cipher suite order | Cloudflare enforces server cipher preference |
| Key exchange parameters | Only ECDHE (X25519, P-256, P-384); no finite-field DHE |
| Hash functions for key exchange | See note below |
| TLS compression | BoringSSL never offers compression (CRIME mitigated) |
| Secure renegotiation | RFC 5746 supported; client-initiated renegotiation disabled |
| OCSP stapling | High-Reliability OCSP Stapling on all edge certs |
| Extended Master Secret | RFC 7627 EMS advertised by BoringSSL |
| Certificate chain | Universal SSL/ACM certs are publicly-trusted, RSA โฅ 2048 or ECDSA P-256+ |
๐ Hash function for key exchange โ TLS 1.2 limitation
This only applies when minimum TLS version is set to 1.2. If you use minimum TLS 1.3, this limitation does not affect you and you can score 100%.
Internet.nl tests whether the server accepts a TLS 1.2 handshake where the client only offers SHA-1 signature algorithms. Cloudflare accepts such connections and falls back to SHA-1 for the ServerKeyExchange signature. This causes the "insufficiently secure hash function" failure.
In practice, the impact is limited: SHA-1 is only used when the client doesn't advertise stronger algorithms. The server chooses to continue the connection rather than dropping it. TLS 1.3 clients (all modern browsers) are unaffected โ they use only SHA-256+ and also benefit from post-quantum key exchange. For clients still on TLS 1.2, upgrading to TLS 1.3 provides far greater security benefits than addressing this specific hash function fallback.
This is not configurable through any Cloudflare zone setting, cipher suite selection, or certificate type while keeping TLS 1.2 support. This is a Cloudflare platform behavior that cannot currently be resolved at the zone level for TLS 1.2 connections.
Organizations with strict compliance requirements (e.g. public sector) that need to achieve 100% while maintaining TLS 1.2 support can contact their Cloudflare account team to discuss available options โ these involve architectural tradeoffs and are not self-service.
HTTP compression (recommended, not scored)
Brotli/gzip are applied by default. Internet.nl issues an orange warning about BREACH but it does not affect the score.
Cipher suites Configuration needed
Only AEAD ciphers (GCM, ChaCha20-Poly1305) with ECDHE key exchange pass. No CBC, no static-RSA, no 3DES, no SHA-1 HMAC.
๐ฐ Advanced Certificate Manager (ACM) required
Cipher suite customization requires ACM ($10/zone/month). Without ACM, the Legacy preset includes 14 non-compliant ciphers (CBC, 3DES, static-RSA) and cannot pass the internet.nl cipher suite test.
Select By security level โ Modern โ Save. The "Modern" option only appears if ACM is active.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/settings/ciphers" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"value": [
"ECDHE-ECDSA-AES128-GCM-SHA256",
"ECDHE-ECDSA-CHACHA20-POLY1305",
"ECDHE-RSA-AES128-GCM-SHA256",
"ECDHE-RSA-CHACHA20-POLY1305",
"ECDHE-ECDSA-AES256-GCM-SHA384",
"ECDHE-RSA-AES256-GCM-SHA384"
]
}' These 6 ciphers are exactly the Cloudflare "Modern" preset. All are ECDHE + AEAD, covering both ECDSA and RSA leaf certificates. TLS 1.3 ciphers are always enabled automatically.
Security headers Configuration needed
X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Content-Security-Policy.
X-Frame-Options, X-Content-Type-Options, Referrer-Policy
These three headers are handled by the Cloudflare Managed Transform "Add security headers". One toggle, no custom rules needed.
This sets:
X-Frame-Options: SAMEORIGINX-Content-Type-Options: nosniffReferrer-Policy: same-origin
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/managed_headers" \
-X PATCH \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"managed_request_headers": [],
"managed_response_headers": [
{"id": "add_security_headers", "enabled": true},
{"id": "remove_x-powered-by_header", "enabled": true}
]
}' Content-Security-Policy (CSP)
CSP is not included in the Managed Transform. You need a separate Transform Rule. Internet.nl requires a restrictive default-src, explicit frame-ancestors, form-action, and base-uri.
โ ๏ธ CSP pitfalls
'unsafe-inline', 'unsafe-eval', bare https:, and mixing 'none' with other sources all fail internet.nl. Keep it strict.
Expression: true (all requests). Add a Set static header:
- Header name:
Content-Security-Policy - Value:
default-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; object-src 'none'; upgrade-insecure-requests
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_response_headers_transform/entrypoint" \
-X PUT \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"rules": [{
"expression": "true",
"action": "rewrite",
"description": "Set CSP header for internet.nl compliance",
"action_parameters": {
"headers": {
"Content-Security-Policy": {
"operation": "set",
"value": "default-src '\''self'\''; frame-ancestors '\''none'\''; form-action '\''self'\''; base-uri '\''self'\''; object-src '\''none'\''; upgrade-insecure-requests"
}
}
}
}]
}' ๐ง Adapt CSP to your site
If your site loads external scripts, fonts, or images, add specific sources. Avoid 'unsafe-inline' โ use hashes or nonces instead.
security.txt Configuration needed
RFC 9116 vulnerability disclosure file at /.well-known/security.txt.
Cloudflare serves security.txt directly from the edge via the Security Center feature. Required fields: Contact: (โฅ1) and Expires: (within ~1 year).
Fill in: Contact (mailto: URI), Expires (date), Canonical, Preferred-Languages. Save.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/security-center/securitytxt" \
-X PUT \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"enabled": true,
"contact": ["mailto:security@example.com"],
"expires": "2027-04-21T00:00:00Z",
"preferred_languages": "en, nl",
"canonical": ["https://example.com/.well-known/security.txt"]
}' RPKI Automatic
Route Origin Authorization for web server and nameserver IPs.
Cloudflare operates AS13335 with ROAs covering all announced prefixes. All proxied host IPs and nameserver IPs are covered. No configuration needed.
For unproxied (grey-cloud) origins, your hosting provider must publish a ROA. Most major providers (AWS, GCP, Azure, Hetzner, etc.) already do.
SPF Configuration needed
Sender Policy Framework. Record must be present, valid syntax, โค10 DNS lookups, policy -all or ~all.
๐ง Email Routing
If you enable Cloudflare Email Routing, the SPF record is created automatically with include:_spf.mx.cloudflare.net ~all.
Type: TXT, Name: @, Content: v=spf1 include:_spf.mx.cloudflare.net ~all
Replace the include: with your mail provider's SPF mechanism (e.g. include:_spf.google.com for Google Workspace).
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-X POST \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"type": "TXT",
"name": "example.com",
"content": "v=spf1 include:_spf.mx.cloudflare.net ~all",
"ttl": 3600
}' DKIM Configuration needed
DomainKeys Identified Mail. At least one valid DKIM public-key TXT record required.
๐ง Email Routing
If you enable Cloudflare Email Routing, a DKIM record is created automatically at cf2024-1._domainkey.
Type: TXT, Name: <selector>._domainkey, Content: the v=DKIM1; k=rsa; p=... value from your mail provider.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-X POST \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"type": "TXT",
"name": "selector._domainkey.example.com",
"content": "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEB...",
"ttl": 3600
}' For a non-sending (parked) domain, publish a wildcard null key: *._domainkey.example.com TXT "v=DKIM1; p="
DMARC Configuration needed
Policy must be p=quarantine or p=reject. p=none fails.
Cloudflare's DMARC Management creates the record and sets up aggregate reporting to @dmarc-reports.cloudflare.net. Important: DMARC Management defaults to p=none (monitoring mode). For internet.nl you must change the policy to p=reject by editing the TXT record.
Change the content to:
v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; fo=1; rua=mailto:<your-id>@dmarc-reports.cloudflare.net
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-X POST \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"type": "TXT",
"name": "_dmarc.example.com",
"content": "v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s; fo=1; rua=mailto:dmarc@example.com",
"ttl": 3600
}' โ ๏ธ p=none will fail
Internet.nl requires p=quarantine or p=reject. If you use Cloudflare DMARC Management, it starts with p=none for monitoring. Upgrade the policy once you've verified legitimate mail is aligned.
STARTTLS & DANE Provider-dependent
TLS on SMTP port 25 and DANE (TLSA records) for mail servers.
STARTTLS
All TLS subtests (version, ciphers, key exchange, compression, etc.) must pass on every MX host. This is your mail provider's responsibility โ you cannot configure these settings on Cloudflare Email Routing's MX servers.
๐ Email Routing MX servers โ platform limitations
Cloudflare's Email Routing MX servers (route*.mx.cloudflare.net) have the same two platform limitations as the web edge:
- Cipher suites: The MX servers offer legacy ciphers (static-RSA, CBC, 3DES) that fail internet.nl. There is no ACM equivalent for Email Routing โ you cannot restrict MX cipher suites.
- Hash function for key exchange: SHA-1 is accepted as a fallback, same as the website test.
These cost ~3% on the mail test. With Email Routing, the maximum mail score is 97%.
Providers known to pass all STARTTLS subtests: Google Workspace, Microsoft 365, Mailbox.org, Posteo, Migadu, Fastmail.
DANE
Requires a TLSA record at _25._tcp.<mx-host> with DNSSEC on the MX host's parent zone.
โ Cloudflare Email Routing supports DANE
Cloudflare publishes TLSA records and DNSSEC-signs mx.cloudflare.net. DANE existence, validity, and rollover all pass automatically โ no configuration needed on your part.
If you use a different mail provider and control the MX host, you need to publish a TLSA record yourself:
Type: TLSA, Name: _25._tcp.mail, Usage: 3 (DANE-EE), Selector: 1 (SPKI), Matching: 1 (SHA-256), Certificate: SHA-256 hash of SPKI.
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-X POST \
-H "Authorization: Bearer $CF_API_TOKEN" \
--json '{
"type": "TLSA",
"name": "_25._tcp.mail.example.com",
"data": {
"usage": 3, "selector": 1, "matching_type": 1,
"certificate": "<sha256-hex>"
},
"ttl": 3600
}' Links
- internet.nl โ test your website and email configuration
- NCSC ICT-beveiligingsrichtlijnen voor TLS โ the TLS guidelines that internet.nl tests against
- Cloudflare SSL/TLS documentation
- Advanced Certificate Manager (ACM) โ required for custom cipher suites
- internet.nl source code โ open-source test suite
- Cloudflare Skills for AI agents โ use with your LLM to configure Cloudflare