
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Fri, 03 Apr 2026 17:03:56 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Why we're rethinking cache for the AI era]]></title>
            <link>https://blog.cloudflare.com/rethinking-cache-ai-humans/</link>
            <pubDate>Thu, 02 Apr 2026 13:00:00 GMT</pubDate>
            <description><![CDATA[ The explosion of AI-bot traffic, representing over 10 billion requests per week, has opened up new challenges and opportunities for cache design. We look at some of the ways AI bot traffic differs from humans, how this impacts CDN cache, and some early ideas for how Cloudflare is designing systems to improve the AI and human experience. ]]></description>
            <content:encoded><![CDATA[ <p>Cloudflare data shows that 32% of traffic across our network originates from <a href="https://radar.cloudflare.com/traffic"><u>automated traffic</u></a>. This includes search engine crawlers, uptime checkers, ad networks — and more recently, AI assistants looking to the web to add relevant data to their knowledge bases as they generate responses with <a href="https://developers.cloudflare.com/reference-architecture/diagrams/ai/ai-rag/"><u>retrieval-augmented generation</u></a> (RAG). Unlike typical human behavior, <a href="https://www.cloudflare.com/learning/ai/what-is-agentic-ai/"><u>AI agents</u></a>, crawlers, and scrapers’ automated behavior may appear aggressive to the server responding to the requests. </p><p>For instance, AI bots frequently issue high-volume requests, often in parallel. Rather than focusing on popular pages, they may access rarely visited or loosely related content across a site, often in sequential, complete scans of the websites. For example, an AI assistant generating a response may fetch images, documentation, and knowledge articles across dozens of unrelated sources.</p><p>Although Cloudflare already makes it easy to <a href="https://blog.cloudflare.com/introducing-ai-crawl-control/"><u>control and limit</u></a> automated access to your content, many sites may <i>want</i> to serve AI traffic. For instance, an application developer may want to guarantee that their developer documentation is up-to-date in foundational AI models, an e-commerce site may want to ensure that product descriptions are part of LLM search results, or publishers may want to get paid for their content through mechanisms such as <a href="https://blog.cloudflare.com/introducing-pay-per-crawl/"><u>pay per crawl</u></a>.</p><p>Website operators therefore face a dichotomy: tune for AI crawlers, or for human traffic. Given both exhibit widely different traffic patterns, current cache architectures force operators to choose one approach to save resources.</p><p>In this post, we’ll explore how AI traffic impacts storage cache, describe some challenges associated with mitigating this impact, and propose directions for the community to consider adapting CDN cache to the AI era.</p><p>This work is a collaborative effort with a team of researchers at <a href="https://ethz.ch/en.html"><u>ETH Zurich</u></a>. The full version of this work was published at the 2025 <a href="https://acmsocc.org/2025/index.html"><u>Symposium on Cloud Computing</u></a> as “<a href="https://dl.acm.org/doi/10.1145/3772052.3772255"><u>Rethinking Web Cache Design for the AI Era</u></a>” by Zhang et al.</p>
    <div>
      <h3>Caching </h3>
      <a href="#caching">
        
      </a>
    </div>
    <p>Let's start with a quick refresher on <a href="https://www.cloudflare.com/learning/cdn/what-is-caching/"><u>caching</u></a>. When a user initiates a request for content on their device, it’s usually sent to the Cloudflare data center closest to them. When the request arrives, we check to see if we have a valid cached copy. If we do, we can serve the content immediately, resulting in a fast response, and a happy user. If the content isn't available to read from our cache, (a "cache miss"), our data centers reach out to the <a href="https://www.cloudflare.com/learning/cdn/glossary/origin-server/"><u>origin server</u></a> to get a fresh copy, which then stays in our cache until it expires or other data pushes it out. </p><p>Keeping the right elements in our cache is critical for reducing our cache misses and providing a great user experience — but what’s “right” for human traffic may be very different from what’s right for AI crawlers!</p>
    <div>
      <h3>AI traffic at Cloudflare</h3>
      <a href="#ai-traffic-at-cloudflare">
        
      </a>
    </div>
    <p>Here, we’ll focus on AI crawler traffic, which has emerged as the most active AI bot type <a href="https://blog.cloudflare.com/crawlers-click-ai-bots-training/"><u>in recent analyses</u></a>, accounting for 80% of the self-identified AI bot traffic we see. AI crawlers fetch content to support real-time AI services, such as answering questions or summarizing pages, as well as to harvest data to build large training datasets for models like <a href="https://www.cloudflare.com/learning/ai/what-is-large-language-model/"><u>LLMs</u></a>.</p><p>From <a href="https://radar.cloudflare.com/ai-insights"><u>Cloudflare Radar</u></a>, we see that the vast majority of single-purpose AI bot traffic is for training, with search as a distant second. (See <a href="https://blog.cloudflare.com/ai-crawler-traffic-by-purpose-and-industry/"><u>this blog post</u></a> for a deep discussion of the AI crawler traffic we see at Cloudflare).</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3WQUiQ36rvMb8rNKruwdLd/1e9003057720b68829c6df3337a840ec/image2.png" />
          </figure><p>While both search and training crawls impact cache through numerous sequential, long-tail accesses, training traffic has properties such as high unique URL ratio, content diversity, and crawling inefficiency that make it even more impactful on cache.</p>
    <div>
      <h3>How does AI traffic differ from other traffic for a CDN?</h3>
      <a href="#how-does-ai-traffic-differ-from-other-traffic-for-a-cdn">
        
      </a>
    </div>
    <p>AI crawler traffic has three main differentiating characteristics: high unique URL ratio, content diversity, and crawling inefficiency.</p><p><a href="https://commoncrawl.github.io/cc-crawl-statistics/plots/crawlsize"><u>Public crawl statistics</u></a> from <a href="https://commoncrawl.org/"><u>Common Crawl</u></a>, which performs large-scale web crawls on a monthly basis, show that over 90% of pages are unique by content. Different AI crawlers also target <a href="https://blog.cloudflare.com/ai-bots/"><u>distinct content types</u></a>: e.g., some specialize in technical documentation, while others focus on source code, media, or blog posts. Finally, AI crawlers do not necessarily follow optimal crawling paths. A substantial fraction of fetches from popular AI crawlers result in 404 errors or redirects, <a href="https://dl.acm.org/doi/abs/10.1145/3772052.3772255"><u>often due to poor URL handling</u></a>. The rate of these ineffective requests varies depending on how well the crawler is tuned to target live, meaningful content. AI crawlers also typically do not employ browser-side caching or session management in the same way human users do. AI crawlers can launch multiple independent instances, and because they don’t share sessions, each may appear as a new visitor to the CDN, even if all instances request the same content.</p><p>Even a single AI crawler is likely to dig deeper into websites and <a href="https://dl.acm.org/doi/epdf/10.1145/3772052.3772255"><u>explore a broader range of content than a typical human user.</u></a> Usage data from Wikipedia shows that <b>pages once considered "long-tail" or rarely accessed are now being frequently requested, shifting the distribution of content popularity within a CDN's cache.</b> In fact, AI agents may iteratively loop to refine search results, scraping the same content repeatedly. We model this to show that this iterative looping leads to low content reuse and broad coverage. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7yH1QLIGCU3mJGXID27Cik/3ba56ff02865b7b141743815d0909be0/image1.png" />
          </figure><p>Our modeling of AI agent behavior shows that as they iteratively loop to refine search results (a common pattern for retrieval-augmented generation), they maintain a consistently high <b>unique access ratio </b>(the red columns above) — typically between 70% and 100%. This means that each loop, while generally increasing <b>accuracy</b> for the agent (represented here by the blue line), is constantly fetching new, unique content rather than revisiting previously seen pages. </p><p><b>This repeat access to long-tail assets churns the cache that the human traffic relies on. That could make existing pre-fetching and traditional cache invalidation strategies less effective as the amount of crawler traffic increases.  </b></p>
    <div>
      <h3>How does AI traffic impact cache?</h3>
      <a href="#how-does-ai-traffic-impact-cache">
        
      </a>
    </div>
    <p>For a <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/"><u>CDN</u></a>, a cache miss means having to go to the origin server to fetch the requested content.  Think of a cache miss like your local library not having a book in house, so you have to wait to get the book from inter-library loan. You’ll get your book eventually, but it will take longer than you wanted. It will also inform your library that having that book in stock locally could be a good idea.  </p><p>As a result of their broad, unpredictable access patterns with long-tail reuse, AI crawlers significantly raise the cache miss rate. And many of our typical methods to improve our cache hit rate, such as <a href="https://blog.cloudflare.com/introducing-speed-brain/"><u>cache speculation</u></a> or prefetching, are significantly less effective.  </p><p>The first chart below shows the difference in cache hit rates for a single node in Cloudflare’s CDN with and without our <a href="https://radar.cloudflare.com/bots/directory?category=AI_CRAWLER&amp;kind=all"><u>identified AI crawlers</u></a>. While the impact of crawlers is still relatively limited, there is a clear drop in hit rate with the addition of AI crawler traffic. We manage our cache with an algorithm called “least recently used”, or LRU. This means that the least-requested content can be evicted from cache first to make space for more popular content when storage space is full. The drop in hit rate implies that LRU is struggling under the repeated scan behavior of AI crawlers.</p><p>The bottom figure shows Al cache misses during this time. Each of those cache misses represents a request to the origin, slowing response times as well as increasing egress costs and load on the origin. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6rsbyos9tv8wzbbXJTrAYh/522b3fed76ce69bb96eb9aaff51ea1b1/image3.png" />
          </figure><p>This surge in AI bot traffic has had real-world impact. The following table from our paper shows the effects on several large websites. Each example links to its source report.</p><table><tr><td><p><b>System</b></p></td><td><p><b>Reported AI Traffic Behavior</b></p></td><td><p><b>Reported Impact</b></p></td><td><p><b>Reported Mitigations</b></p></td></tr><tr><td><p><a href="https://www.wikipedia.org/"><u>Wikipedia</u></a></p></td><td><p>Bulk image scraping for model training<a href="https://diff.wikimedia.org/2025/04/01/how-crawlers-impact-the-operations-of-the-wikimedia-projects/"><u><sup>1</sup></u></a></p></td><td><p>50% surge in multimedia bandwidth usage<a href="https://diff.wikimedia.org/2025/04/01/how-crawlers-impact-the-operations-of-the-wikimedia-projects/"><u><sup>1</sup></u></a></p></td><td><p>Blocked crawler traffic<a href="https://diff.wikimedia.org/2025/04/01/how-crawlers-impact-the-operations-of-the-wikimedia-projects/"><u><sup>1</sup></u></a></p></td></tr><tr><td><p><a href="https://sourcehut.org/"><u>SourceHut</u></a></p></td><td><p>LLM crawlers scraping code repositories<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://status.sr.ht/issues/2025-03-17-git.sr.ht-llms/"><u><sup>3</sup></u></a> </p></td><td><p>Service instability and slowdowns<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://status.sr.ht/issues/2025-03-17-git.sr.ht-llms/"><u><sup>3</sup></u></a> </p></td><td><p>Blocked crawler traffic<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://status.sr.ht/issues/2025-03-17-git.sr.ht-llms/"><u><sup>3</sup></u></a> </p></td></tr><tr><td><p><a href="https://about.readthedocs.com/"><u>Read the Docs</u></a></p></td><td><p>AI crawlers download large files hundreds of times daily<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://about.readthedocs.com/blog/2024/07/ai-crawlers-abuse/"><u><sup>4</sup></u></a></p></td><td><p>Significant bandwidth increase<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://about.readthedocs.com/blog/2024/07/ai-crawlers-abuse/"><u><sup>4</sup></u></a></p></td><td><p>Temporarily blocked crawler traffic, performed IP-based rate limiting, reconfigured CDN to improve caching<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://about.readthedocs.com/blog/2024/07/ai-crawlers-abuse/"><u><sup>4</sup></u></a></p></td></tr><tr><td><p><a href="https://www.fedoraproject.org/"><u>Fedora</u></a></p></td><td><p>AI scrapers recursively crawl package mirrors<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://cryptodamus.io/en/articles/news/ai-web-scrapers-attacking-open-source-here-s-how-to-fight-back"><u><sup>5</sup></u></a><sup>,</sup><a href="https://www.scrye.com/blogs/nirik/posts/2025/03/15/mid-march-infra-bits-2025/"><u><sup>6</sup></u></a></p></td><td><p>Slow response for human users<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://cryptodamus.io/en/articles/news/ai-web-scrapers-attacking-open-source-here-s-how-to-fight-back"><u><sup>5</sup></u></a><sup>,</sup><a href="https://www.scrye.com/blogs/nirik/posts/2025/03/15/mid-march-infra-bits-2025/"><u><sup>6</sup></u></a></p></td><td><p>Geo-blocked traffic from known bot sources along with blocking several subnets and even countries<a href="https://incidentdatabase.ai/cite/1001/"><u><sup>2</sup></u></a><sup>,</sup><a href="https://cryptodamus.io/en/articles/news/ai-web-scrapers-attacking-open-source-here-s-how-to-fight-back"><u><sup>5</sup></u></a><sup>,</sup><a href="https://www.scrye.com/blogs/nirik/posts/2025/03/15/mid-march-infra-bits-2025/"><u><sup>6</sup></u></a></p></td></tr><tr><td><p><a href="https://diasporafoundation.org/"><u>Diaspora</u></a></p></td><td><p>Aggressive scraping without respecting robots.txt<a href="https://diaspo.it/posts/2594"><u><sup>7</sup></u></a></p></td><td><p>Slow response and downtime for human users<a href="https://diaspo.it/posts/2594"><u><sup>7</sup></u></a></p></td><td><p>Blocked crawler traffic and added rate limits<a href="https://diaspo.it/posts/2594"><u><sup>7</sup></u></a></p></td></tr></table><p>The impact is severe: Wikimedia experienced a 50% surge in multimedia bandwidth usage due to bulk image scraping. Fedora, which hosts large software packages, and the Diaspora social network suffered from heavy load and poor performance for human users. Many others have noted bandwidth increases or slowdowns from AI bots repeatedly downloading large files. While blocking crawler traffic mitigates some of the impact, a smarter cache architecture would let site operators serve AI crawlers while maintaining response times for their human users.</p>
    <div>
      <h3>AI-aware caching</h3>
      <a href="#ai-aware-caching">
        
      </a>
    </div>
    <p>AI crawlers power live applications such as <a href="https://www.cloudflare.com/learning/ai/retrieval-augmented-generation-rag/"><u>retrieval-augmented generation (RAG)</u></a> or real-time summarization, so latency matters. That’s why these requests should be routed to caches that can balance larger capacity with moderate response times. These caches should still preserve freshness, but can tolerate slightly higher access latency than human-facing caches. </p><p>AI crawlers are also used for building training sets and running large-scale content collection jobs. These workloads can tolerate significantly higher latency and are not time-sensitive. As such, their requests can be served from deep cache tiers that take longer to reach (e.g., origin-side SSD caches), or even delayed using queue-based admission or rate-limiters to prevent backend overload. This also opens the opportunity to defer bulk scraping when infrastructure is under load, without affecting interactive human or AI use cases.</p><p>Existing projects like Cloudflare’s <a href="https://blog.cloudflare.com/an-ai-index-for-all-our-customers/"><u>AI Index</u></a> and <a href="https://blog.cloudflare.com/markdown-for-agents/"><u>Markdown for Agents</u></a> allow website operators to present a simplified or reduced version of websites to known AI agents and bots. We're making plans to do much more to mitigate the impact of AI traffic on CDN cache, leading to better cache performance for everyone. With our collaborators at ETH Zurich, we’re experimenting with two complementary approaches: first, traffic filtering with AI-aware caching algorithms; and second, exploring the addition of an entirely new cache layer to siphon AI crawler traffic to a cache that will improve performance for both AI crawlers and human traffic. </p><p>There are several different types of cache replacement algorithms, such as LRU (“Least Recently Used”), LFU (“Least Frequently Used”), or FIFO (“First-In, First-Out”), that govern how a storage cache chooses to evict elements from the cache when a new element needs to be added and the cache is full. LRU is often the best balance of simplicity, low-overhead, and effectiveness for generic situations, and is widely used. For mixed human and AI bot traffic, however, our initial experiments indicate that a different choice of cache replacement algorithm, particularly using <a href="https://cachemon.github.io/SIEVE-website/"><u>SEIVE</u></a> or <a href="https://s3fifo.com/"><u>S3FIFO</u></a>, could allow human traffic to achieve the same hit rate with or without AI interference. We are also experimenting with developing more directly workload-aware, machine learning-based caching algorithms to customize cache response in real time for a faster and cheaper cache.  </p><p>Long term, we expect that a separate cache layer for AI traffic will be the best way forward. Imagine a cache architecture that routes human and AI traffic to distinct tiers deployed at different layers of the network. Human traffic would continue to be served from edge caches located at CDN PoPs, which prioritize responsiveness and <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cache-hit-ratio/"><u>cache hit rates</u></a>. For AI traffic, cache handling could vary by task type. </p>
    <div>
      <h3>This is just the beginning</h3>
      <a href="#this-is-just-the-beginning">
        
      </a>
    </div>
    <p>The impact of AI bot traffic on cloud infrastructure is only going to grow over the next few years. We need better characterization of the effects on CDNs across the globe, along with bold new cache policies and architectures to address this novel workload and help make a better Internet. </p><p>Cloudflare is already solving the problems we’ve laid out here. Cloudflare reduces bandwidth costs for customers who experience high bot traffic with our AI-aware caching, and with our <a href="https://www.cloudflare.com/ai-crawl-control/"><u>AI Crawl Control</u></a> and <a href="https://www.cloudflare.com/paypercrawl-signup/"><u>Pay Per Crawl</u></a> tools, we give customers better control over who programmatically accesses their content.</p><p>We’re just getting started exploring this space. If you're interested in building new ML-based caching algorithms or designing these new cache architectures, please apply for an internship! We have <a href="https://www.cloudflare.com/en-gb/careers/jobs/?department=Early+Talent"><u>open internship positions</u></a> in Summer and Fall 2026 to work on this and other exciting problems at the intersection of AI and Systems.  </p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cache]]></category>
            <guid isPermaLink="false">635WBzM8GMiVZhyzKFeWMf</guid>
            <dc:creator>Avani Wildani</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
        </item>
        <item>
            <title><![CDATA[Bringing more transparency to post-quantum usage, encrypted messaging, and routing security]]></title>
            <link>https://blog.cloudflare.com/radar-origin-pq-key-transparency-aspa/</link>
            <pubDate>Fri, 27 Feb 2026 06:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare Radar has added new tools for monitoring PQ adoption, KT logs for messaging, and ASPA routing records to track the Internet's migration toward more secure encryption and routing standards.  ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Cloudflare Radar already offers a wide array of <a href="https://radar.cloudflare.com/security/"><u>security insights</u></a> — from application and network layer attacks, to malicious email messages, to digital certificates and Internet routing.</p><p>And today we’re introducing even more. We are launching several new security-related data sets and tools on Radar: </p><ul><li><p>We are extending our post-quantum (PQ) monitoring beyond the client side to now include origin-facing connections. We have also released a new tool to help you check any website's post-quantum encryption compatibility. </p></li><li><p>A new Key Transparency section on Radar provides a public dashboard showing the real-time verification status of Key Transparency Logs for end-to-end encrypted messaging services like WhatsApp, showing when each log was last signed and verified by Cloudflare's Auditor. The page serves as a transparent interface where anyone can monitor the integrity of public key distribution and access the API to independently validate our Auditor’s proofs. </p></li><li><p>Routing Security insights continue to expand with the addition of global, country, and network-level information about the deployment of ASPA, an emerging standard that can help detect and prevent BGP route leaks. </p></li></ul>
    <div>
      <h2>Measuring origin post-quantum support</h2>
      <a href="#measuring-origin-post-quantum-support">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2gs0x3zMZTxios168jT9xW/179d8959b5e0939835cf6facef797457/1.png" />
          </figure><p>Since <a href="https://x.com/CloudflareRadar/status/1788277817362329983"><u>April 2024</u></a>, we have tracked the aggregate growth of client support for post-quantum encryption on Cloudflare Radar, chronicling its global growth from <a href="https://radar.cloudflare.com/adoption-and-usage?dateStart=2024-01-01&amp;dateEnd=2024-01-31#post-quantum-encryption-adoption"><u>under 3% at the start of 2024</u></a>, to <a href="https://radar.cloudflare.com/adoption-and-usage?dateStart=2026-02-01&amp;dateEnd=2026-02-28#post-quantum-encryption-adoption"><u>over 60% in February 2026</u></a>. And in October 2025, <a href="https://blog.cloudflare.com/pq-2025/#what-you-can-do-today-to-stay-safe-against-quantum-attacks"><u>we added the ability</u></a> for users to <a href="https://radar.cloudflare.com/adoption-and-usage#browser-support"><u>check</u></a> whether their browser supports <a href="https://developers.cloudflare.com/ssl/post-quantum-cryptography/pqc-support/#x25519mlkem768"><code><u>X25519MLKEM768</u></code></a> — a hybrid key exchange algorithm combining classical <a href="https://www.rfc-editor.org/rfc/rfc8410"><code><u>X25519</u></code></a> with <a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf"><u>ML-KEM</u></a>, a lattice-based post-quantum scheme standardized by NIST. This provides security against both classical and quantum attacks. </p><p>However, post-quantum encryption support on user-to-Cloudflare connections is only part of the story.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/67cvSmOaISIHjrKKRHKPzg/e0ccf032658904fd6beaa7de7340b561/2.png" />
          </figure><p>For content not in our CDN cache, or for uncacheable content, Cloudflare’s edge servers establish a separate connection with a customer’s origin servers to retrieve it. To accelerate the transition to quantum-resistant security for these origin-facing fetches, we <a href="https://blog.cloudflare.com/post-quantum-to-origins/"><u>previously introduced an API</u></a> allowing customers to opt in to preferring post-quantum connections. Today, we’re making post-quantum compatibility of origin servers visible on Radar.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6KvV2meYLEPbNIQyHP6yji/9477a134c8f5f6a7aaecd6257cd59981/3.png" />
          </figure><p>The new origin post-quantum support graph on Radar illustrates the share of customer origins supporting <code>X25519MLKEM768</code>. This data is derived from <a href="https://blog.cloudflare.com/automatically-secure/"><u>our automated TLS scanner,</u></a> which probes TLS 1.3-compatible origins and aggregates the results daily. It is important to note that our scanner tests for support rather than the origin server's specific preference. While an origin may support a post-quantum key exchange algorithm, its local TLS key exchange preference can ultimately dictate the encryption outcome.</p><p>While the headline graph focuses on post-quantum readiness, the scanner also evaluates support for classical key exchange algorithms. Within the Radar <a href="https://radar.cloudflare.com/explorer?dataSet=post_quantum.origin&amp;groupBy=key_agreement#result"><u>Data Explorer view</u></a>, you can also see the full distribution of these supported TLS key exchange methods.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5PBOoQSCcIAQrYezKp1pJU/d4218aba59deef6c21df53856a93040a/4.png" />
          </figure><p>As shown in the graphs above, approximately 10% of origins could benefit from a post-quantum-preferred key agreement today. This represents a significant jump from less than 1% at the start of 2025 — <a href="https://radar.cloudflare.com/explorer?dataSet=post_quantum.origin&amp;groupBy=key_agreement&amp;dt=2025-01-01_2025-12-31"><u>a 10x increase in just over a year</u></a>. We expect this number to grow steadily as the industry continues its migration. This upward trend likely accelerated in 2025 as many server-side TLS libraries, such as <a href="https://openssl-library.org/post/2025-04-08-openssl-35-final-release/"><u>OpenSSL 3.5.0+</u></a>,<a href="https://www.gnutls.org/"><u> GnuTLS 3.8.9+</u></a>, and <a href="https://go.dev/doc/go1.24#cryptotlspkgcryptotls"><u>Go 1.24+</u></a>, enabled hybrid post-quantum key exchange by default, allowing platforms and services to support post-quantum connections simply by upgrading their cryptographic library dependencies.</p><p>In addition to the Radar and Data Explorer graphs, the <a href="https://developers.cloudflare.com/api/resources/radar/subresources/post_quantum/subresources/origin/"><u>origin readiness data is available through the Radar API</u></a> as well.</p><p>As an additional part of our efforts to help the Internet transition to post-quantum cryptography, we are also launching <a href="https://radar.cloudflare.com/post-quantum#website-support"><u>a tool to test whether a specific hostname supports post-quantum encryption</u></a>. These tests can be run against any publicly accessible website, as long as they allow connections from Cloudflare’s <a href="https://www.cloudflare.com/ips/"><u>egress IP address ranges</u></a>. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5dgwK3i7IeLLSUt5xnk4lf/276e25dda3389f6e0ad83a26acd08fec/5.png" />
          </figure><p><sub><i>A screenshot of the tool in Radar to test whether a hostname supports post-quantum encryption.</i></sub></p><p>The tool presents a simple form where users can enter a hostname (such as <a href="https://radar.cloudflare.com/post-quantum?host=cloudflare.com%3A443"><code><u>cloudflare.com</u></code></a> or <a href="https://radar.cloudflare.com/post-quantum?host=www.wikipedia.org%3A443"><code><u>www.wikipedia.org</u></code></a>) and optionally specify a custom port (the default is <a href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=443"><u>443, the standard HTTPS port</u></a>). After clicking "Test", the result displays a tag indicating PQ support status alongside the negotiated TLS key exchange algorithm. If the server prefers PQ secure connections, a green "PQ" tag appears with a message confirming the connection is "post-quantum secure." Otherwise, a red tag indicates the connection is "not post-quantum secure", showing the classical algorithm that was negotiated.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3rfEG4dMlwR4FJkaKXTRWF/8cab135242057ce57f3b0e4a92be4cec/6.png" />
          </figure>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/PXu3kjzwhVkb29kIFREOn/41785c06297e0667ff9e2b261ae9b819/7.png" />
          </figure><p>Under the hood, this tool uses <a href="https://developers.cloudflare.com/containers/"><u>Cloudflare Containers</u></a> — a new capability that allows running container workloads alongside Workers. Since the Workers runtime is not exposed to details of the underlying TLS handshake, Workers cannot initiate TLS scans. Therefore, we created a Go container that leverages the <a href="https://pkg.go.dev/crypto/tls"><code><u>crypto/tls</u></code></a> package's support for post-quantum compatibility checks. The container runs on-demand and performs the actual handshake to determine the negotiated TLS key exchange algorithm, returning results through the <a href="https://developers.cloudflare.com/api/resources/radar/subresources/post_quantum/subresources/tls/methods/support/"><u>Radar API</u></a>.</p><p>With the addition of these origin-facing insights, complementing the existing client-facing insights, we have moved all the post-quantum content to <a href="https://radar.cloudflare.com/post-quantum"><u>its own section on Radar</u></a>. </p>
    <div>
      <h2>Securing E2EE messaging systems with Key Transparency</h2>
      <a href="#securing-e2ee-messaging-systems-with-key-transparency">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/71b8HJK1iT0udJscvkqqI4/778efb329047fca017ff2cf4153330ad/8.png" />
          </figure><p><a href="https://www.cloudflare.com/learning/privacy/what-is-end-to-end-encryption/"><u>End-to-end encrypted (E2EE)</u></a> messaging apps like WhatsApp and Signal have become essential tools for private communication, relied upon by billions of people worldwide. These apps use <a href="https://www.cloudflare.com/learning/ssl/how-does-public-key-encryption-work/"><u>public-key cryptography</u></a> to ensure that only the sender and recipient can read the contents of their messages — not even the messaging service itself. However, there's an often-overlooked vulnerability in this model: users must trust that the messaging app is distributing the correct public keys for each contact.</p><p>If an attacker were able to substitute an incorrect public key in the messaging app's database, they could intercept messages intended for someone else — all without the sender knowing.</p><p>Key Transparency addresses this challenge by creating an auditable, append-only log of public keys — similar in concept to <a href="https://radar.cloudflare.com/certificate-transparency"><u>Certificate Transparency</u></a> for TLS certificates. Messaging apps publish their users' public keys to a transparency log, and independent third parties can verify and vouch that the log has been constructed correctly and consistently over time. In September 2024, Cloudflare <a href="https://blog.cloudflare.com/key-transparency/"><u>announced</u></a> such a Key Transparency auditor for WhatsApp, providing an independent verification layer that helps ensure the integrity of public key distribution for the messaging app's billions of users.</p><p>Today, we're publishing Key Transparency audit data in a new <a href="https://radar.cloudflare.com/key-transparency"><u>Key Transparency section</u></a> on Cloudflare Radar. This section showcases the Key Transparency logs that Cloudflare audits, giving researchers, security professionals, and curious users a window into the health and activity of these critical systems.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1LZ1DUzv0SCgBa0XqDURKP/26ccd8b0741073895cbb52aa7f1d5643/image11.png" />
          </figure><p>The new page launches with two monitored logs: WhatsApp and Facebook Messenger Transport. Each monitored log is displayed as a card containing the following information:</p><ul><li><p><b>Status:</b> Indicates whether the log is online, in initialization, or disabled. An "online" status means the log is actively publishing key updates into epochs that Cloudflare audits. (An epoch represents a set of updates applied to the key directory at a specific time.)</p></li><li><p><b>Last signed epoch:</b> The most recent epoch that has been published by the messaging service's log and acknowledged by Cloudflare. By clicking on the eye icon, users can view the full epoch data in JSON format, including the epoch number, timestamp, cryptographic digest, and signature.</p></li><li><p><b>Last verified epoch:</b> The most recent epoch that Cloudflare has verified. Verification involves checking that the transition of the transparency log data structure from the previous epoch to the current one represents a valid tree transformation — ensuring the log has been constructed correctly. The verification timestamp indicates when Cloudflare completed its audit.</p></li><li><p><b>Root:</b> The current root hash of the <a href="https://github.com/facebook/akd"><u>Auditable Key Directory (AKD)</u></a> tree. This hash cryptographically represents the entire state of the key directory at the current epoch. Like the epoch fields, users can click to view the complete JSON response from the auditor.</p></li></ul><p>The data shown on the page is also available via the Key Transparency Auditor API, with endpoints for <a href="https://developers.cloudflare.com/key-transparency/api/auditor-information/"><u>auditor information</u></a> and <a href="https://developers.cloudflare.com/key-transparency/api/namespaces/"><u>namespaces</u></a>.</p><p>If you would like to perform audit proof verification yourself, you can follow the instructions in our <a href="https://blog.cloudflare.com/key-transparency/"><u>Auditing Key Transparency blog post</u></a>. We hope that these use cases are the first of many that we publish in this Key Transparency section in Radar — if your company or organization is interested in auditing for your public key or related infrastructure, you can <a href="https://www.cloudflare.com/lp/privacy-edge/"><u>reach out to us here</u></a>.</p>
    <div>
      <h2>Tracking RPKI ASPA adoption</h2>
      <a href="#tracking-rpki-aspa-adoption">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2LAbrwY9ziVbe1BzfUyl7K/821a40f86c62dd9b44f7bcaee018dd28/10.png" />
          </figure><p>While the <a href="https://www.cloudflare.com/learning/security/glossary/what-is-bgp/"><u>Border Gateway Protocol (BGP)</u></a> is the backbone of Internet routing, it was designed without built-in mechanisms to verify the validity of the paths it propagates. This inherent trust has long left the global network vulnerable to route leaks and hijacks, where traffic is accidentally or maliciously detoured through unauthorized networks.</p><p>Although <a href="https://en.wikipedia.org/wiki/Resource_Public_Key_Infrastructure"><u>RPKI</u></a> and <a href="https://www.arin.net/resources/manage/rpki/roas/"><u>Route Origin Authorizations (ROAs)</u></a> have successfully hardened the origin of routes, they cannot verify the path traffic takes between networks. This is where <a href="https://datatracker.ietf.org/doc/draft-ietf-sidrops-aspa-verification/"><u>ASPA (Autonomous System Provider Authorization)</u></a><b> </b>comes in. ASPA extends RPKI protection by allowing an <a href="https://www.cloudflare.com/learning/network-layer/what-is-an-autonomous-system/"><u>Autonomous System (AS)</u></a> to cryptographically sign a record listing the networks authorized to propagate its routes upstream. By validating these Customer-to-Provider relationships, ASPA allows systems to detect invalid path announcements with confidence and react accordingly.</p><p>While the specific IETF standard remains <a href="https://datatracker.ietf.org/doc/draft-ietf-sidrops-aspa-verification/"><u>in draft</u></a>, the operational community is moving fast. Support for creating ASPA objects has already landed in the portals of Regional Internet Registries (RIRs) like <a href="https://www.arin.net/announcements/20260120/"><u>ARIN</u></a> and <a href="https://labs.ripe.net/author/tim_bruijnzeels/aspa-in-the-rpki-dashboard-a-new-layer-of-routing-security/"><u>RIPE NCC</u></a>, and validation logic is available in major software routing stacks like <a href="https://www.undeadly.org/cgi?action=article;sid=20231002135058"><u>OpenBGPD</u></a> and <a href="https://bird.network.cz/?get_doc&amp;v=20&amp;f=bird-5.html"><u>BIRD</u></a>.</p><p>To provide better visibility into the adoption of this emerging standard, we have added comprehensive RPKI ASPA support to the <a href="https://radar.cloudflare.com/routing"><u>Routing section</u></a> of Cloudflare Radar. Tracking these records globally allows us to understand how quickly the industry is moving toward better path validation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6SI6A5vd2bAp3QnBAsJFmZ/24e11445eb0309252d759e88dbf2ba62/11.png" />
          </figure><p>Our new ASPA deployment view allows users to examine the growth of ASPA adoption over time, with the ability to visualize trends across the five <a href="https://en.wikipedia.org/wiki/Regional_Internet_registry"><u>Regional Internet Registries</u></a> (RIRs) based on AS registration. You can view the entire history of ASPA entries, dating back to October 1, 2023, or zoom into specific date ranges to correlate spikes in adoption with industry events, such as the introduction of ASPA features on ARIN and RIPE NCC online dashboards.</p><p>Beyond aggregate trends, we have also introduced a granular, searchable explorer for real-time ASPA content. This table view allows you to inspect the current state of ASPA records, searchable by AS number, AS name, or by filtering for only providers or customer ASNs. This allows network operators to verify that their records are published correctly and to view other networks’ configurations.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/K97G5TC7O1MYwkvFbrdTl/85b27f807401f85d2bbe140f1611a034/12.png" />
          </figure><p>We have also integrated ASPA data directly into the country/region routing pages. Users can now track how different locations are progressing in securing their infrastructure, based on the associated ASPA records from the customer ASNs registered locally.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6mhZyfrHexdo1GDAoKZEd7/44b63675595a01939fa4748210d8c482/13.png" />
          </figure><p>On individual AS pages, we have updated the Connectivity section. Now, when viewing the connections of a network, you may see a visual indicator for "ASPA Verified Provider." This annotation confirms that an ASPA record exists authorizing that specific upstream connection, providing an immediate signal of routing hygiene and trust.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3lVJY4fZWv3KaFdKwLHfAV/aeb2bc27bdccb6a9025345dbaed5b762/14.png" />
          </figure><p>For ASes that have deployed ASPA, we now display a complete list of authorized provider ASNs along with their details. Beyond the current state, Radar also provides a detailed timeline of ASPA activity involving the AS. This history distinguishes between changes initiated by the AS itself ("As customer") and records created by others designating it as a provider ("As provider"), allowing users to immediately identify when specific routing authorizations were established or modified.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ZIlAn2l0sDTLCyEMMcBI9/871b8d7abffe17b3aee060502eaa4c1c/15.png" />
          </figure><p>Visibility is an essential first step toward broader adoption of emerging routing security protocols like ASPA. By surfacing this data, we aim to help operators deploy protections and assist researchers in tracking the Internet's progress toward a more secure routing path. For those who need to integrate this data into their own workflows or perform deeper analysis, we are also exposing these metrics programmatically. Users can now access ASPA content snapshots, historical timeseries, and detailed changes data using the newly introduced endpoints in the<a href="https://developers.cloudflare.com/api/resources/radar/subresources/bgp/subresources/rpki/subresources/aspa/"> <u>Cloudflare Radar API</u></a>.</p>
    <div>
      <h2>As security evolves, so does our data</h2>
      <a href="#as-security-evolves-so-does-our-data">
        
      </a>
    </div>
    <p>Internet security continues to evolve, with new approaches, protocols, and standards being developed to ensure that information, applications, and networks remain secure. The security data and insights available on Cloudflare Radar will continue to evolve as well. The new sections highlighted above serve to expand existing routing security, transparency, and post-quantum insights already available on Cloudflare Radar. </p><p>If you share any of these new charts and graphs on social media, be sure to tag us: <a href="https://x.com/CloudflareRadar"><u>@CloudflareRadar</u></a> (X), <a href="https://noc.social/@cloudflareradar"><u>noc.social/@cloudflareradar</u></a> (Mastodon), and <a href="https://bsky.app/profile/radar.cloudflare.com"><u>radar.cloudflare.com</u></a> (Bluesky). If you have questions or comments, or suggestions for data that you’d like to see us add to Radar, you can reach out to us on social media, or contact us via <a><u>email</u></a>.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5jAzDXss7PvszWkwGC0q2g/df14de40bf268052fac11239952fc1ed/16.png" />
          </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Radar]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Routing]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">1Iy1Qvw9TsOhRwgjUYqFxO</guid>
            <dc:creator>David Belson</dc:creator>
            <dc:creator>Mingwei Zhang</dc:creator>
            <dc:creator>André Jesus</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Sabina Zejnilovic</dc:creator>
            <dc:creator>Thibault Meunier</dc:creator>
            <dc:creator>Mari Galicer</dc:creator>
        </item>
        <item>
            <title><![CDATA[Measuring characteristics of TCP connections at Internet scale]]></title>
            <link>https://blog.cloudflare.com/measuring-network-connections-at-scale/</link>
            <pubDate>Wed, 29 Oct 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ Researchers and practitioners have been studying connections almost as long as the Internet that supports them. Today, Cloudflare’s global network receives millions of connections per second. We explore various characteristics of TCP connections, including lifetimes, sizes, and more. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Every interaction on the Internet—including loading a web page, streaming a video, or making an API call—starts with a connection. These fundamental logical connections consist of a stream of packets flowing back and forth between devices.</p><p>Various aspects of these network connections have captured the attention of researchers and practitioners for as long as the Internet has existed. The interest in connections even predates the label, as can be seen in the seminal 1991 paper, “<a href="https://dl.acm.org/doi/10.1145/115994.116003"><u>Characteristics of wide-area TCP/IP conversations</u></a>.” By any name, the Internet measurement community has been steeped in characterizations of Internet communication for <i>decades</i>, asking everything from “how long?” and “how big?” to “how often?” – and those are just to start.</p><p>Surprisingly, connection characteristics on the wider Internet are largely unavailable. While anyone can  use tools (e.g., <a href="https://www.wireshark.org/"><u>Wireshark</u></a>) to capture data locally, it’s virtually impossible to measure connections globally because of access and scale. Moreover, network operators generally do not share the characteristics they observe — assuming that non-trivial time and energy is taken to observe them.</p><p>In this blog post, we move in another direction by sharing aggregate insights about connections established through our global CDN. We present characteristics of <a href="https://developers.cloudflare.com/fundamentals/reference/tcp-connections/"><u>TCP</u></a> connections—which account for about <a href="https://radar.cloudflare.com/adoption-and-usage"><u>70% of HTTP requests</u></a> to Cloudflare—providing empirical insights that are difficult to obtain from client-side measurements alone.</p>
    <div>
      <h2>Why connection characteristics matter</h2>
      <a href="#why-connection-characteristics-matter">
        
      </a>
    </div>
    <p>Characterizing system behavior helps us predict the impact of changes. In the context of networks, consider a new routing algorithm or transport protocol: how can you measure its effects? One option is to deploy the change directly on live networks, but this is risky. Unexpected consequences could disrupt users or other parts of the network, making a “deploy-first” approach potentially unsafe or ethically questionable.</p><p>A safer alternative to live deployment as a first step is simulation. Using simulation, a designer can get important insights about their scheme without having to build a full version. But simulating the whole Internet is challenging, as described by another highly seminal work, “<a href="https://dl.acm.org/doi/10.1145/268437.268737"><u>Why we don't know how to simulate the Internet</u></a>”.</p><p>To run a useful simulation, we need it to behave like the real system we’re studying. That means generating synthetic data that mimics real-world behavior. Often, we do this by using statistical distributions — mathematical descriptions of how the real data behaves. But before we can create those distributions, we first need to characterize the data — to measure and understand its key properties. Only then can our simulation produce realistic results.</p>
    <div>
      <h2>Unpacking the dataset</h2>
      <a href="#unpacking-the-dataset">
        
      </a>
    </div>
    <p>The value of any data depends on its collection mechanism. Every dataset has blind spots, biases, and limitations, and ignoring these can lead to misleading conclusions. By examining the finer details — how the data was gathered, what it represents, and what it excludes — we can better understand its reliability and make informed decisions about how to use it. Let’s take a closer look at our collected telemetry.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5ksUQ7xlzXPWp2hH7eX4dG/124456d20c6fd5e7e185d68865aee6fa/image5.png" />
          </figure><p><b>Dataset Overview</b>. The data describes TCP connections, labeled <i>Visitor to Cloudflare</i> in the above diagram, which serve requests via HTTP 1.0, 1.1, and 2.0 that make up <a href="https://radar.cloudflare.com/adoption-and-usage">about 70%</a> of all 84 million HTTP requests per second, on average, received at our global CDN servers.</p><p><b>Sampling.</b> The passively collected snapshot of data is drawn from a uniformly sampled 1% of all TCP connections to Cloudflare between October 7 and October 15, 2025. Sampling takes place at each individual client-facing server to mitigate biases that may appear by sampling at the datacenter level.</p><p><b>Diversity.</b> Unlike many large operators, whose traffic is primarily their own and dominated by a few services such as search, social media, or streaming video, the vast majority of Cloudflare’s workload comes from our customers, who choose to put Cloudflare in front of their websites to help protect, improve performance, and reduce costs. This diversity of customers brings a wide variety of web applications, services, and users from around the world. As a result, the connections we observe are shaped by a broad range of client devices and application-specific behaviors that are constantly evolving.</p><p><b>What we log.</b> Each entry in the log consists of socket-level metadata captured via the Linux kernel’s <a href="https://man7.org/linux/man-pages/man7/tcp.7.html"><u>TCP_INFO</u></a> struct, alongside the SNI and the number of requests made during the connection. The logs exclude individual HTTP requests, transactions, and details. We restrict our use of the logs to connection metadata statistics such as duration and number of packets transmitted, as well as the number of HTTP requests processed.</p><p><b>Data capture.</b> We have elected to represent ‘useful’ connections in our dataset that have been fully processed, by characterizing only those connections that close gracefully with <a href="https://blog.cloudflare.com/tcp-resets-timeouts/#tcp-connections-from-establishment-to-close"><u>a FIN packet</u></a>. This excludes connections intercepted by attack mitigations, or that timeout, or that abort because of a RST packet.</p><p>Since a graceful close does not in itself indicate a ‘useful’ connection, <b>we additionally require at least one successful HTTP request</b> during the connection to filter out idle or non-HTTP connections from this analysis — interestingly, these make up 11% of all TCP connections to Cloudflare that close with a FIN packet.</p><p>If you’re curious, we’ve also previously blogged about the details of Cloudflare’s <a href="https://blog.cloudflare.com/how-we-make-sense-of-too-much-data/"><u>overall logging mechanism</u></a> and <a href="https://blog.cloudflare.com/http-analytics-for-6m-requests-per-second-using-clickhouse/"><u>post-processing pipeline</u></a>.  </p>
    <div>
      <h2>Visualizing connection characteristics</h2>
      <a href="#visualizing-connection-characteristics">
        
      </a>
    </div>
    <p>Although networks are inherently dynamic and trends can change over time, the large-scale patterns we observe across our global infrastructure remain remarkably consistent over time. While our data offers a global view of connection characteristics, distributions can still vary according to regional traffic patterns.</p><p>In our visualizations we represent characteristics with <a href="https://en.wikipedia.org/wiki/Cumulative_distribution_function"><u>cumulative distribution function (CDF)</u></a> graphs, specifically their <a href="https://en.wikipedia.org/wiki/Empirical_distribution_function"><u>empirical equivalents</u></a>. CDFs are particularly useful for gaining a macroscopic view of the distribution. They give a clear picture of both common and extreme cases in a single view. We use them in the illustrations below to make sense of large-scale patterns. To better interpret the distributions, we also employ log-scaled axes to account for the presence of extreme values common to networking data.</p><p>A long-standing question about Internet connections relates to “<a href="https://en.wikipedia.org/wiki/Elephant_flow"><u>Elephants and Mice</u></a>”; practitioners and researchers are entirely aware that most flows are small and some are huge, yet little data exists to inform the lines that divide them. This is where our presentation begins.</p>
    <div>
      <h3>Packet Counts</h3>
      <a href="#packet-counts">
        
      </a>
    </div>
    <p>Let’s start by taking a look at the distribution of the number of <i>response</i> packets sent in connections by Cloudflare servers back to the clients.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5qaPCul0l7bdOQfaxL1Wbn/d0ef9cc108ba35d49593029baed7cb86/image12.png" />
          </figure><p>On the graph, the x-axis represents the number of response packets sent in log-scale, while the y-axis shows the cumulative fraction of connections below each packet count. The average response consists of roughly 240 packets, but the distribution is highly skewed. The median is 12 packets, which indicates that 50% of Internet connections consist of <i>very few packets</i>.<i> </i>Extending further to<i> </i>the 90th percentile, connections carry only 107 packets.</p><p>This stark contrast highlights the heavy-tailed nature of Internet traffic: while a few connections transport massive amounts of data—like video streams or large file transfers—most interactions are tiny, delivering small web objects, microservice traffic, or API responses.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Mf6VwD2Xq8aBwQP1V9aX5/1a20d6fa2caab5c719591db8b232f6a1/image11.png" />
          </figure><p>The above plot breaks down the packet count distribution by HTTP protocol version. For HTTP/1.X (both HTTP 1.0 and 1.1 combined) connections, the median response consists of just 10 packets, and 90% of connections carry fewer than 63 response packets. In contrast, HTTP/2 connections show larger responses, with a median of 16 packets and a 90th percentile of 170 packets. This difference likely reflects how HTTP/2 multiplexes multiple streams over a single connection, often consolidating more requests and responses into fewer connections, which increases the total number of packets exchanged per connection. HTTP/2 connections also have additional control-plane frames and flow-control messages that increase response packet counts.</p><p>Despite these differences, the combined view displays the same heavy-tailed pattern: a small fraction of connections carry enormous volumes of data (<a href="https://en.wikipedia.org/wiki/Elephant_flow"><u>elephant flows</u></a>), extending to millions of packets, while most remain lightweight (<a href="https://en.wikipedia.org/wiki/Mouse_flow"><u>mice flows</u></a>).</p><p>So far, we’ve focused on the total number of packets sent from our servers to clients, but another important dimension of connection behavior is the balance between packets sent and received, illustrated below.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5VZeU0d2EYLxPl3SaTPJBb/6b46a793d6eea178838c4f5b2572caf1/image2.png" />
          </figure><p>The x-axis shows the ratio of packets sent by our servers to packets received from clients, visualized as a CDF. Across all connections, the median ratio is 0.91, meaning that in half of connections, clients send slightly more packets than the server responds with. This excess of client-side packets primarily reflects <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a> handshake initiation (ClientHello), HTTP control request headers, and data acknowledgements (ACKs), causing the client to typically transmit more packets than the server returns with the content payload — particularly for low-volume connections that dominate the distribution.</p><p>The mean ratio is higher, at 1.28, due to a long tail of client-heavy connections, such as large downloads typical of CDN workloads. Most connections fall within a relatively narrow range: 10% of connections have a ratio below 0.67, and 90% are below 1.85. However, the long-tailed behavior highlights the diversity of Internet traffic: extreme values arise from both upload-heavy and download-heavy connections. The variance of 3.71 reflects these asymmetric flows, while the bulk of connections maintain a roughly balanced upload-to-download exchange.</p>
    <div>
      <h3>Bytes sent</h3>
      <a href="#bytes-sent">
        
      </a>
    </div>
    <p>Another dimension to look at the data is using bytes sent by our servers to clients, which captures the actual volume of data delivered over each connection. This metric is derived from tcpi_bytes_sent, also covering (re)transmitted segment payloads while excluding the TCP header, as defined in <a href="https://github.com/torvalds/linux/blob/v6.14/include/uapi/linux/tcp.h#L222-L312"><u>linux/tcp.h</u></a> and aligned with <a href="https://www.rfc-editor.org/rfc/rfc4898.html"><u>RFC 4898</u></a> (TCP Extended Statistics MIB).</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1VZs6F65RQjyyEUUxZSP2L/b0edd986738e9128c16dcbecb7d83761/image3.png" />
          </figure><p>The plots above break down bytes sent by HTTP protocol version. The x-axis represents the total bytes sent by our servers over each connection. The patterns are generally consistent with what we observed in the packet count distributions.</p><p>For HTTP/1.X, the median response delivers 4.8 KB, and 90% of connections send fewer than 51 KB. In contrast, HTTP/2 connections show slightly larger responses, with a median of 6 KB and a 90th percentile of 146 KB. The mean is much higher—224 KB for HTTP/1.x and 390 KB for HTTP/2—reflecting a small number of very large transfers. These long-tailed extreme flows can reach tens of gigabytes per connection, while some very lightweight connections carry minimal payloads: the minimum for HTTP/1.X is 115 bytes and for HTTP/2 it is 202 bytes.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2xRYaXYQbte6MszIT92uky/837ebdc842c9784a9c413ad886f7a5d6/image6.png" />
          </figure><p>By making use of the tcpi_bytes_received metric, we can now look at the ratio of bytes sent to bytes received per connection to better understand the balance of data exchange. This ratio captures how asymmetric each connection is — essentially, how much data our servers send compared to what they receive from clients. Across all connections, the median ratio is 3.78, meaning that in half of all cases, servers send nearly four times more data than they receive. The average is far higher at 81.06, showing a strong long tail driven by download-heavy flows. Again we see the heavy long-tailed distribution, a small fraction of extreme cases push the ratio into the millions, with more extreme values of data transfers towards clients.</p>
    <div>
      <h3>Connection duration</h3>
      <a href="#connection-duration">
        
      </a>
    </div>
    <p>While packet and byte counts capture how much data is exchanged, connection duration provides insight into how that exchange unfolds over time.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5noP7Acqu2Ky4hCGtETH1F/92c7bd220d57232fb40440624d227a78/image8.png" />
          </figure><p>The CDF above shows the distribution of connection durations (lifetimes) in seconds. A reminder that the x-axis is log-scale. Across all connections, the median duration is just 4.7 seconds, meaning half of connections complete in under five seconds. The mean is much higher at 96 seconds, reflecting a small number of long-lived connections that skew the average. Most connections fall within a window of 0.1 seconds (10th percentile) to 300 seconds (90th percentile). We also observe some extremely long-lived connections lasting multiple days, possibly maintained via <a href="https://developers.cloudflare.com/fundamentals/reference/tcp-connections/#tcp-connections-and-keep-alives"><u>keep-alives</u></a> for connection reuse without hitting <a href="https://developers.cloudflare.com/fundamentals/reference/connection-limits/"><u>our default idle timeout limits</u></a>. These long-lived connections typically represent persistent sessions or multimedia traffic, while the majority of web traffic remains short, bursty, and transient.</p>
    <div>
      <h3>Request counts</h3>
      <a href="#request-counts">
        
      </a>
    </div>
    <p>A single connection can carry multiple HTTP requests for web traffic. This reveals patterns about connection multiplexing.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4hsoigL4rFtIyRJpdSUXwh/5ef82b3c0cf5b25b8dc13ed38761f895/image7.png" />
          </figure><p>The above shows the number of HTTP requests (in log-scale) that we see on a single connection, broken down by HTTP protocol version. Right away, we can see that for both HTTP/1.X (mean 3 requests) and HTTP/2 (mean 8 requests) connections, the median number of requests is just 1, reinforcing the prevalence of limited connection reuse. However, because HTTP/2 supports multiplexing multiple streams over a single connection, the 90th percentile rises to 10 requests, with occasional extreme cases carrying thousands of requests, which can be amplified due to <a href="https://blog.cloudflare.com/connection-coalescing-experiments/"><u>connection coalescing</u></a>. In contrast, HTTP/1.X connections have much lower request counts. This aligns with protocol design: HTTP/1.0 followed a “one request per connection” philosophy, while HTTP/1.1 introduced persistent connections — even combining both versions, it’s rare to see HTTP/1.X connections carrying more than two requests at the 90th percentile.</p><p>The prevalence of short-lived connections can be partly explained by automated clients or scripts that tend to open new connections rather than maintaining long-lived sessions. To explore this intuition, we split the data between traffic originating from data centers (likely automated) and typical user traffic (user-driven), using client ASNs as a proxy.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1DhUbNv8cjQVGOqKUai7KU/fecc8eaa488ec216bfb14084a518501b/image9.png" />
          </figure><p>The plot above shows that non-DC (user-driven) traffic has slightly higher request counts per connection, consistent with browsers or apps fetching multiple resources over a single persistent connection, with a mean of 5 requests and a 90th percentile of 5 requests per connection. In contrast, DC-originated traffic has a mean of roughly 3 requests and a 90th percentile of 2, validating our expectation. Despite these differences, the median number of requests remains 1 for both groups highlighting that, regardless of origin of connections, most are genuinely brief.</p>
    <div>
      <h2>Inferring path characteristics from connection-level data</h2>
      <a href="#inferring-path-characteristics-from-connection-level-data">
        
      </a>
    </div>
    <p>Connection-level measurements can also provide insights into underlying path characteristics. Let’s examine this in more detail.</p>
    <div>
      <h3>Path MTU</h3>
      <a href="#path-mtu">
        
      </a>
    </div>
    <p>The maximum transmission unit (<a href="https://www.cloudflare.com/learning/network-layer/what-is-mtu/"><u>MTU</u></a>) along the network path is often referred to as the Path MTU (PMTU). PMTU determines the largest packet size that can traverse a connection without fragmentation or packet drop, affecting throughput, efficiency, and latency. The Linux TCP stack on our servers tracks the largest segment size that can be sent without fragmentation along the path for a connection, as part of <a href="https://blog.cloudflare.com/path-mtu-discovery-in-practice/"><u>Path MTU discovery.</u></a></p><p>From that data we saw that the median (and the 90th percentile!) PMTU was 1500 bytes, which aligns with the typical Ethernet MTU and is <a href="https://en.wikipedia.org/wiki/Maximum_transmission_unit"><u>considered standard</u></a> for most Internet paths. Interestingly, the 10th percentile sits at 1,420 bytes, reflecting cases where paths include network links with slightly smaller MTUs—common in some <a href="https://blog.cloudflare.com/migrating-from-vpn-to-access/"><u>VPNs</u></a>, <a href="https://blog.cloudflare.com/increasing-ipv6-mtu/"><u>IPv6tov4 tunnels</u></a>, or older networking equipment that impose stricter limits to avoid fragmentation. At the extreme, we have seen MTU as small as 552 bytes for IPv4 connections which relates to the minimum allowed PMTU value <a href="https://www.kernel.org/doc/html/v6.5/networking/ip-sysctl.html#:~:text=Default%3A%20FALSE-,min_pmtu,-%2D%20INTEGER"><u>by the Linux kernel</u></a>.</p>
    <div>
      <h3>Initial congestion window</h3>
      <a href="#initial-congestion-window">
        
      </a>
    </div>
    <p>A key parameter in transport protocols is the congestion window (CWND), which is the number of packets that can be transmitted without waiting for an acknowledgement from the receiver. We call these packets or bytes “in-flight.” During a connection, the congestion window evolves dynamically throughout a connection.</p><p>However, the initial congestion window (ICWND) at the start of a data transfer can have an outsized impact, especially for short-lived connections, which dominate Internet traffic as we’ve seen above. If the ICWND is set too low, small and medium transfers take additional round-trip times to reach bottleneck bandwidth, slowing delivery. Conversely, if it’s too high, the sender risks overwhelming the network, causing unnecessary packet loss and retransmissions — potentially for all connections that share the bottleneck link.</p><p>A reasonable estimate of the ICWND can be taken as the congestion window size at the instant the TCP sender transitions out of <a href="https://www.rfc-editor.org/rfc/rfc5681#section-3.1"><u>slow start</u></a>. This transition marks the point at which the sender shifts from exponential growth to congestion-avoidance, having inferred that further growth may risk congestion. The figure below shows the distribution of congestion window sizes at the moment slow start exits — as calculated by <a href="https://blog.cloudflare.com/http-2-prioritization-with-nginx/#bbr-congestion-control"><u>BBR</u></a>. The median is roughly 464 KB, which corresponds to about 310 packets per connection with a typical 1,500-byte MTU, while extreme flows carry tens of megabytes in flight. This variance reflects the diversity of TCP connections and the dynamically evolving nature of the networks carrying traffic.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7BzqE6HSQgkriWisqS3Yx3/de4dc12a453d162884e9a015ccb40348/image4.png" />
          </figure><p>It’s important to emphasize that these values reflect a mix of network paths, including not only paths between Cloudflare and end users, but also between Cloudflare and neighboring datacenters, which are typically well provisioned and offer higher bandwidth.</p><p>Our initial inspection of the above distribution left us doubtful, because the values seem very high. We then realized the numbers are an artifact of behaviour specific to BBR, in which it sets the congestion window higher than its estimate of the path’s available capacity, <a href="https://en.wikipedia.org/wiki/Bandwidth-delay_product"><u>bandwidth delay product (BDP)</u></a>. The inflated value is <a href="https://www.ietf.org/archive/id/draft-cardwell-iccrg-bbr-congestion-control-01.html#name-state-machine-operation"><u>by design</u></a>. To prove the hypothesis, we re-plot the distribution from above in the figure below alongside BBR’s estimate of BDP. The difference is clear between BBR’s congestion window of unacknowledged packets and its BDP estimate.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/34YFSv4Zdp82qszNM79XsH/3c147dfd5c5006fe55abb53dab47bef1/image10.png" />
          </figure><p>The above plot adds the computed BDP values in context with connection telemetry. The median BDP comes out to be roughly 77 KB, which is roughly 50 packets. If we compare this to the congestion window distribution taken from above, we see BDP estimations from recently closed connections are much more stable.</p><p>We are using these insights to help identify reasonable initial congestion window sizes and the circumstances for them. Our own experiments internally make clear that ICWND sizes can affect performance by as much as 30-40% for smaller connections. Such insights will potentially help to revisit efforts to find better initial congestion window values, which has been a default of <a href="https://datatracker.ietf.org/doc/html/rfc6928"><u>10 packets</u></a> for more than a decade.</p>
    <div>
      <h3>Deeper understanding, better performance</h3>
      <a href="#deeper-understanding-better-performance">
        
      </a>
    </div>
    <p>We observed that Internet connections are highly heterogeneous, confirming decades-long observations of strong heavy-tail characteristics consistent with “<a href="https://en.wikipedia.org/wiki/Elephant_flow"><u>elephants and mice</u></a>” phenomenon. Ratios of upload to download bytes are unsurprising for larger flows, but surprisingly small for short flows, highlighting the asymmetric nature of Internet traffic. Understanding these connection characteristics continues to inform ways to improve connection performance, reliability, and user experience.</p><p>We will continue to build on this work, and plan to publish connection-level statistics on <a href="https://radar.cloudflare.com/"><u>Cloudflare Radar</u></a> so that others can similarly benefit.</p><p>Our work on improving our network is ongoing, and we welcome researchers, academics, <a href="https://blog.cloudflare.com/cloudflare-1111-intern-program/"><u>interns</u></a>, and anyone interested in this space to reach out at <a><u>ask-research@cloudflare.com</u></a>. By sharing knowledge and working together, we all can continue to make the Internet faster, safer, and more reliable for everyone.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Better Internet]]></category>
            <category><![CDATA[Insights]]></category>
            <category><![CDATA[TCP]]></category>
            <guid isPermaLink="false">5jyi6dhHiLQu3BVMVGKrVG</guid>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Peter Wu</dc:creator>
        </item>
        <item>
            <title><![CDATA[Automatically Secure: how we upgraded 6,000,000 domains by default to get ready for the Quantum Future]]></title>
            <link>https://blog.cloudflare.com/automatically-secure/</link>
            <pubDate>Wed, 24 Sep 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ After a year since we started enabling Automatic SSL/TLS, we want to talk about these results, why they matter, and how we’re preparing for the next leap in Internet security. ]]></description>
            <content:encoded><![CDATA[ <p>The Internet is in constant motion. Sites scale, traffic shifts, and attackers adapt. Security that worked yesterday may not be enough tomorrow. That’s why the technologies that protect the web — such as Transport Layer Security (TLS) and emerging post-quantum cryptography (PQC) — must also continue to evolve. We want to make sure that everyone benefits from this evolution automatically, so we enabled the strongest protections by default.</p><p>During <a href="https://blog.cloudflare.com/introducing-automatic-ssl-tls-securing-and-simplifying-origin-connectivity/"><u>Birthday Week 2024</u></a>, we announced Automatic SSL/TLS: a service that scans origin server configurations of domains behind Cloudflare, and automatically upgrades them to the most secure encryption mode they support. In the past year, <b>this system has quietly strengthened security for more than 6 million domains </b>— ensuring Cloudflare can always connect to origin servers over the safest possible channel, without customers lifting a finger.</p><p>Now, a year after we started enabling Automatic SSL/TLS, we want to talk about these results, why they matter, and how we’re preparing for the next leap in Internet security.</p>
    <div>
      <h2>The Basics: TLS protocol</h2>
      <a href="#the-basics-tls-protocol">
        
      </a>
    </div>
    <p>Before diving in, let’s review the basics of Transport Layer Security (<a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a>). The protocol allows two strangers (like a client and server) to communicate securely.</p><p>Every secure web session begins with a TLS handshake. Before a single byte of your data moves across the Internet, servers and clients need to agree on a shared secret key that will protect the confidentiality and integrity of your data. The key agreement handshake kicks off with a TLS <i>ClientHello</i> message. This message is the browser/client announcing, “Here’s who I want to talk to (via <a href="https://www.cloudflare.com/learning/ssl/what-is-sni/"><u>SNI</u></a>), and here are the key agreement methods I understand.” The server then proves who it is with its own credentials in the form of a certificate, and together they establish a shared secret key that will protect everything that follows. </p><p>TLS 1.3 added a clever shortcut: instead of waiting to be told which method to use for the shared key agreement, the browser can guess what key agreement the server supports, and include one or more <a href="https://blog.cloudflare.com/rfc-8446-aka-tls-1-3/"><u>keyshares</u></a> right away. If the guess is correct, the handshake skips an extra round trip and the secure connection is established more quickly. If the guess is wrong, the server responds with a <i>HelloRetryRequest</i> (HRR), telling the browser which key agreement method to retry with. This speculative guessing is a major reason TLS 1.3 is so much faster than TLS 1.2.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/W2t0sZjiliwZ0FGfFFG6k/113c44b54da1c0355d5bf76fba3080fa/1-2.png" />
          </figure><p>Once both sides agree, the chosen keyshare is used to create a shared secret that encrypts the messages they exchange and allows only the right parties to decrypt them.</p>
    <div>
      <h3>The nitty-gritty details of key agreement</h3>
      <a href="#the-nitty-gritty-details-of-key-agreement">
        
      </a>
    </div>
    <p>Up until recently, most of these handshakes have relied on <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>elliptic curve cryptography</u></a> (ECC) using a curve known as X25519. But looming on the horizon are quantum computers, which could one day break ECC algorithms like X25519 and others. To prepare, the industry is shifting toward post-quantum key agreement with <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf"><u>MLKEM</u></a>, deployed in a hybrid mode (<a href="https://datatracker.ietf.org/doc/draft-ietf-tls-ecdhe-mlkem/"><u>X25519 + MLKEM</u></a>). This ensures that even if quantum machines arrive, <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvested traffic today</u></a> can’t be decrypted tomorrow. X25519 + MLKEM is <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>steadily rising to become the most popular</u></a> key agreement for connections to Cloudflare.</p><p>The TLS handshake model is the foundation for how we encrypt web communications today. The history of TLS is really the story of <i>iteration under pressure</i>. It’s a protocol that had to keep evolving, so trust on the web could keep pace with how Internet traffic has changed. It’s also what makes technologies like <b>Cloudflare’s Automatic SSL/TLS</b> possible, by abstracting decades of protocol battles and crypto engineering into a single click, so customer websites can be secured by default without requiring every operator to be a cryptography expert.</p>
    <div>
      <h2>History Lesson: Stumbles and Standards</h2>
      <a href="#history-lesson-stumbles-and-standards">
        
      </a>
    </div>
    <p>Early versions of TLS (then called SSL) in the 1990s suffered from weak keys, limited protection against attacks like <a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack"><u>man-in-the-middle</u></a>, and low adoption on the Internet. To stabilize things, the <a href="https://www.ietf.org/"><u>IETF</u></a> stepped in and released <a href="https://www.ietf.org/rfc/rfc2246.txt"><u>TLS 1.0</u></a>, followed by TLS <a href="https://datatracker.ietf.org/doc/html/rfc4346"><u>1.1</u></a> and <a href="https://datatracker.ietf.org/doc/html/rfc5246"><u>1.2</u></a> through the 2000s. These versions added stronger ciphers and patched new attack vectors, but years of fixes and extensions left the protocol bloated and hard to evolve.</p><p>The early 2010s marked a turning point. After the <a href="https://iapp.org/news/a/the-snowden-disclosures-10-years-on"><u>Snowden disclosures</u></a>, the Internet doubled down on encryption by default. Initiatives like <a href="https://en.wikipedia.org/wiki/Let%27s_Encrypt"><u>Let’s Encrypt</u></a>, the mass adoption of <a href="https://en.wikipedia.org/wiki/HTTPS"><u>HTTPS</u></a>, and Cloudflare’s own commitment to offer <a href="https://www.cloudflare.com/application-services/products/ssl/"><u>SSL/TLS for free</u></a> turned encryption from optional, expensive, and complex into an easy baseline requirement for a safer Internet.</p><p>All of this momentum led to <a href="https://datatracker.ietf.org/doc/html/rfc8446"><u>TLS 1.3</u></a> (2018), which cut away legacy baggage, locked in modern cipher suites, and made encrypted connections nearly as fast as the underlying transport protocols like TCP—and sometimes even faster with <a href="https://en.wikipedia.org/wiki/QUIC"><u>QUIC</u></a>.</p>
    <div>
      <h2>The CDN Twist</h2>
      <a href="#the-cdn-twist">
        
      </a>
    </div>
    <p>As Content Delivery Networks (CDNs) rose to prominence, they reshaped how TLS was deployed. Instead of a browser talking directly to a distant server hosting content (what Cloudflare calls an origin), it now spoke to the nearest edge data center, which may in-turn speak to an origin server on the client’s behalf.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7CTywdNaDxUXcGHVg5i1MP/975f9b0a74b2b5c5fb59ecb64d3268bb/2.png" />
          </figure><p>This created <b>two distinct TLS layers</b>:</p><ul><li><p><b>Edge ↔ Browser TLS:</b> The front door, built to quickly take on new improvements in security and performance. Edges and browsers adopt modern protocols (TLS 1.3, QUIC, session resumption) to cut down on latency.</p></li><li><p><b>Edge ↔ Origin TLS:</b> The backhaul, which must be more flexible. Origins might be older, more poorly maintained, run legacy TLS stacks, or require custom certificate handling.</p></li></ul><p>In practice, CDNs became <i>translators</i>: modernizing encryption at the edge while still bridging to legacy origins. It’s why you can have a blazing-fast TLS 1.3 session from your phone, even if the origin server behind the CDN hasn’t been upgraded in years. </p><p>This is where Automatic SSL/TLS sits in the story of how we secure Internet communications. </p>
    <div>
      <h2>Automatic SSL/TLS </h2>
      <a href="#automatic-ssl-tls">
        
      </a>
    </div>
    <p>Automatic SSL/TLS grew out of Cloudflare’s mission to ensure the web was as encrypted as possible. While we had initially spent an incredibly long time developing secure connections for the “front door” (from browsers to Cloudflare’s edge) with <a href="https://blog.cloudflare.com/introducing-universal-ssl/"><u>Universal SSL</u></a>, we knew that the “back door” (from Cloudflare’s edge to origin servers) would be slower and harder to upgrade. </p><p>One option we offered was <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>Cloudflare Tunnel</u></a>, where a lightweight agent runs near the origin server and tunnels traffic securely back to Cloudflare. This approach ensures the connection always uses modern encryption, without requiring changes on the origin itself.</p><p>But not every customer uses Tunnel. Many connect origins directly to Cloudflare’s edge, where encryption depends on the origin server’s configuration. Traditionally this meant customers had to either manually select an <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>encryption mode</u></a> that worked for their origin server or rely on the default chosen by Cloudflare. </p><p>To improve the experience of choosing an encryption mode, we introduced our <a href="https://blog.cloudflare.com/ssl-tls-recommender/"><u>SSL/TLS Recommender</u></a> in 2021.</p><p>The Recommender scanned customer origin servers and then provided recommendations for their most secure encryption mode. For example, if the Recommender detected that an origin server was using a certificate signed by a trusted Certificate Authority (CA) such as Let’s Encrypt, rather than a self-signed certificate, it would recommend upgrading from <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full/"><b><u>Full</u></b><u> encryption mode</u></a> to <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict/"><b><u>Full (Strict)</u></b><u> encryption mode</u></a>.</p><p>Based on how the origin responded, Recommender would tell customers if they could improve their SSL/TLS encryption mode to be more secure. The following encryption modes represent what the SSL/TLS Recommender could recommend to customers based on their origin responses: </p><table><tr><td><p><b>SSL/TLS mode</b></p></td><td><p><b>HTTP from visitor</b></p></td><td><p><b>HTTPS from visitor</b></p></td></tr><tr><td><p><a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/off/"><u>Off</u></a></p></td><td><p>HTTP to Origin</p></td><td><p>HTTP to Origin</p></td></tr><tr><td><p><a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/flexible/"><u>Flexible</u></a></p></td><td><p>HTTP to Origin</p></td><td><p>HTTP to Origin</p></td></tr><tr><td><p><a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full/"><u>Full</u></a></p></td><td><p>HTTP to Origin</p></td><td><p>HTTPS to Origin without certification validation check</p></td></tr><tr><td><p><a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict/"><u>Full (strict)</u></a></p></td><td><p>HTTP to Origin</p></td><td><p>HTTPS to Origin with certificate validation check</p></td></tr><tr><td><p><a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/ssl-only-origin-pull/"><u>Strict (SSL-only origin pull)</u></a></p></td><td><p>HTTPS to Origin with certificate validation check</p></td><td><p>HTTPS to Origin with certificate validation check</p></td></tr></table><p>However, in the three years after launching our Recommender we discovered something troubling: of the over two million domains using Recommender, <b>only 30% of the recommendations that the system provided were followed</b>. A significant number of users would not complete the next step of pushing the button to inform Cloudflare that we could communicate with their origin over a more secure setting. </p><p>We were seeing sub-optimal settings that our customers could upgrade from without risk of breaking their site, but for various reasons, our users did not follow through with the recommendations. So we pushed forward by building a system that worked with Recommender and actioned the recommendations by default. </p>
    <div>
      <h2>How does Automatic SSL/TLS work? </h2>
      <a href="#how-does-automatic-ssl-tls-work">
        
      </a>
    </div>
    <p>Automatic SSL/TLS<b> </b>works by crawling websites, looking for content over both HTTP and HTTPS, then comparing the results for compatibility. It also performs checks against the TLS certificate presented by the origin and looks at the type of content that is served to ensure it matches. If the downloaded content matches, Automatic SSL/TLS elevates the encryption level for the domain to the compatible and stronger mode, without risk of breaking the site.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/49AaKdddEOgWXk1Oxlg2Qp/be44b863e2f4c797fa58c8b81f93f51a/3.png" />
          </figure><p>More specifically, these are the steps that Automatic SSL/TLS takes to upgrade domain’s security: </p><ol><li><p>Each domain is scheduled for a scan <b>once per month</b> (or until it reaches the maximum supported encryption mode).</p></li><li><p>The scan evaluates the current <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>encryption mode</u></a> for the domain. If it’s lower than what the Recommender thinks the domain can support based on the <a href="https://blog.cloudflare.com/introducing-automatic-ssl-tls-securing-and-simplifying-origin-connectivity/#:~:text=When%20the%20Recommender,recommendation%20is%20followed."><u>results</u></a> of its probes and content scans, the system begins a gradual upgrade.</p></li><li><p>Automatic SSL/TLS begins to upgrade the domain by connecting with origins over the more secure mode starting with just 1% of its traffic.</p></li><li><p>If connections to the origin succeed, the result is logged as successful.</p><ol><li><p>If they fail, the system records the failure to Cloudflare’s control plane and aborts the upgrade. Traffic is immediately downgraded back to the previous SSL/TLS setting to ensure seamless operation.</p></li></ol></li><li><p>If no issues are found, the new SSL/TLS encryption mode is applied to traffic in 10% increments until 100% of traffic uses the recommended mode.</p></li><li><p>Once 100% of traffic has been successfully upgraded with no TLS-related errors, the domain’s SSL/TLS setting is permanently updated.</p></li><li><p><b>Special handling for Flexible → Full/Strict:</b> These upgrades are more cautious because customers’ <a href="https://developers.cloudflare.com/cache/how-to/cache-keys/"><u>cache keys</u></a> are changed (from <code>http</code> to <code>https</code> origin scheme).</p><ol><li><p>In this situation, traffic ramps up from 1% to 10% in 1% increments, allowing customers’ cache to warm-up.</p></li><li><p>After 10%, the system resumes the standard 10% increments until 100%.</p></li></ol></li></ol><p>We know that transparency and visibility are critical, especially when automated systems make changes. To keep customers informed, Automatic SSL/TLS sends a weekly digest to account <a href="https://developers.cloudflare.com/fundamentals/manage-members/roles/"><u>Super Administrators</u></a> whenever updates are made to domain encryption modes. This way, you always have visibility into what changed and when.  </p><p>In short, Automatic SSL/TLS automates what used to be trial and error: finding the strongest SSL/TLS mode your site can support while keeping everything working smoothly.</p>
    <div>
      <h2>How are we doing so far?  </h2>
      <a href="#how-are-we-doing-so-far">
        
      </a>
    </div>
    <p>So far we have onboarded <b>all Free, Pro, and Business domains to use Automatic SSL/TLS</b>. We also have enabled this for <b>all new domains</b> that will onboard onto Cloudflare regardless of plantype. Soon, we will start onboarding Enterprise customers as well. If you already have an Enterprise domain and want to try out Automatic SSL/TLS we encourage you to <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/#automatic-ssltls-default"><u>enable it in the SSL/TLS section</u></a> of the dashboard or via the API. </p><p>As of the publishing of this blog, we’ve upgraded over<b> 6 million domains</b> to be more secure without the website operators needing to manually configure anything on Cloudflare. </p><table><tr><td><p><b>Previous Encryption Mode</b></p></td><td><p><b>Upgraded Encryption Mode</b></p></td><td><p><b>Number of domains</b></p></td></tr><tr><td><p>Flexible</p></td><td><p>Full</p></td><td><p>~ 2,200,000</p></td></tr><tr><td><p>Flexible</p></td><td><p>Full (strict)</p></td><td><p>~ 2,000,000</p></td></tr><tr><td><p>Full </p></td><td><p>Full (strict)</p></td><td><p>~ 1,800,000</p></td></tr><tr><td><p>Off</p></td><td><p>Full</p></td><td><p>~ 7,000</p></td></tr><tr><td><p>Off</p></td><td><p>Full (strict)</p></td><td><p>~ 5,000</p></td></tr></table><p>We’re most excited about the over 4 million domains that moved from <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/flexible/"><u>Flexible</u></a> or <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/off/"><u>Off</u></a>, which uses HTTP to origin servers, to <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full/"><u>Full</u></a> or <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict/"><u>Strict</u></a>, which uses HTTPS. </p><p>If you have a reason to use a particular encryption mode (e.g., on a test domain that isn’t production ready) you can always disable Automatic SSL/TLS and manually set the encryption mode that works best for your use case.</p><p>Today, SSL/TLS mode works on a domain-wide level, which can feel blunt. This means that one suboptimal subdomain can keep the entire domain in a less secure TLS setting, to ensure availability. Our long-term goal is to make these controls more precise, so that Automatic SSL/TLS and encryption modes can optimize security per origin or subdomain, rather than treating every hostname the same.</p>
    <div>
      <h2>Impact on origin-facing connections</h2>
      <a href="#impact-on-origin-facing-connections">
        
      </a>
    </div>
    <p>Since we began onboarding domains to <b>Automatic SSL/TLS</b> in late 2024 and early 2025, we’ve been able to measure how origin connections across our network are shifting toward stronger security. Looking at the ratios across all origin requests, the trends are clear:</p><ul><li><p><b>Encryption is rising.</b> Plaintext connections are steadily declining, a reflection of Automatic SSL/TLS helping millions of domains move to HTTPS by default. We’ve seen <b>a correlated 7-8% reduction in plaintext origin-bound connections.</b> Still, some origins remain on outdated configurations, and these should be upgraded to keep pace with modern security expectations.</p></li><li><p><b>TLS 1.3 is surging.</b> Since late 2024, TLS 1.3 adoption has climbed sharply, now making up the majority of encrypted origin traffic (almost 60%). While Automatic SSL/TLS doesn’t control which TLS version an origin supports, this shift is an encouraging sign for both performance and security.</p></li><li><p><b>Older versions are fading.</b> Month after month, TLS 1.2 continues to shrink, while TLS 1.0 and 1.1 are now so rare they barely register.</p></li></ul><p>The decline in plaintext connections is encouraging, but it also highlights a long tail of servers still relying on outdated packages or configurations. Sites like <a href="https://www.ssllabs.com/ssltest/"><u>SSL Labs</u></a> can be used, for instance, to check a server’s TLS configuration. However, simply copy-pasting settings to achieve a high rating can be risky, so we encourage customers to review their origin TLS configurations carefully. In addition, <a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/"><u>Cloudflare origin CA</u></a> or <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>Cloudflare Tunnel</u></a> can help provide guidance for upgrading origin security.</p>
    <div>
      <h3>Upgraded domain results</h3>
      <a href="#upgraded-domain-results">
        
      </a>
    </div>
    <p>Instead of focusing on the entire network of origin-facing connections from Cloudflare, we’re now going to drill into specific changes that we’ve seen from domains that have been upgraded by <b>Automatic SSL/TLS</b>. </p><p>By January 2025, most domains had been enrolled in Automatic SSL/TLS, and the results were dramatic: a near 180-degree shift from plaintext to encrypted communication with origins. After that milestone, traffic patterns leveled off into a steady plateau, reflecting a more stable baseline of secure connections across the network. There is some drop in encrypted traffic which may represent some of the originally upgraded domains manually turning off Automatic SSL/TLS.</p><p>But the story doesn’t end there. In the past two months (July and August 2025), we’ve observed another noticeable uptick in encrypted origin traffic. This likely reflects customers upgrading outdated origin packages and enabling stronger TLS support—evidence that Automatic SSL/TLS not only raised the floor on encryption but continues nudging the long tail of domains toward better security.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6nJe12swMSMXBQsgzEhXtq/78debf8e0c3efbaf66bce8cf6e623c80/4.png" />
          </figure><p>To further explore the “encrypted” line above, we wanted to see what the delta was between TLS 1.2 and 1.3. Originally we wanted to include all TLS versions we support but the levels of 1.0 and 1.1 were so small that they skewed the graph and were taken out. We see a noticeable rise in the support for both TLS 1.2 and 1.3 between Cloudflare and origin servers. What is also interesting to note here is the network-wide decrease in TLS 1.2 but for the domains that have been automatically upgraded a generalized increase, potentially also signifying origin TLS stacks that could be updated further.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/BoRlq4irKWuvuXs5E4e8l/3971165f5029a03ae64dac79235a8671/5.png" />
          </figure><p>Finally, for Full (Strict) mode,<b> </b>we wanted to investigate the number of successful certificate validations we performed. This line shows a dramatic, approximately 40%, increase in successful certificate validations performed for customers upgraded by Automatic SSL/TLS. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5nNyiMNQ4xtOubbrhnDuRY/af16c0792a73de71fa0176e6c1cfeb0b/6.png" />
          </figure><p>We’ve seen a largely successful rollout of Automatic SSL/TLS so far, with millions of domains upgraded to stronger encryption by default. We’ve seen help Automatic SSL/TLS improve origin-facing security, safely pushing connections to stronger modes whenever possible, without risking site breakage. Looking ahead, we’ll continue to expand this capability to more customer use cases as we help to build a more encrypted Internet.</p>
    <div>
      <h2>What will we build next for Automatic SSL/TLS? </h2>
      <a href="#what-will-we-build-next-for-automatic-ssl-tls">
        
      </a>
    </div>
    <p>We’re expanding Automatic SSL/TLS with new features that give customers more visibility and control, while keeping the system safe by default. First, we’re building an <b>ad-hoc scan</b> option that lets you rescan your origin earlier than the standard monthly cadence. This means if you’ve just rotated certificates, upgraded your origin’s TLS configuration, or otherwise changed how your server handles encryption, you won’t need to wait for the next scheduled pass—Cloudflare will be able to re-evaluate and move you to a stronger mode right away.</p><p>In addition, we’re working on <b>error surfacing</b> that will highlight origin connection problems directly in the dashboard and provide actionable guidance for remediation. Instead of discovering after the fact that an upgrade failed, or a change on the origin resulted in a less secure setting than what was set previously, customers will be able to see where the issue lies and how to fix it. </p><p>Finally, for <b>newly onboarded domains</b>, we plan to add clearer guidance on when to finish configuring the origin before Cloudflare runs its first scan and sets an encryption mode. Together, these improvements are designed to reduce surprises, give customers more agency, and ensure smoother upgrades. We expect all three features to roll out by June 2026.</p>
    <div>
      <h2>Post Quantum Era</h2>
      <a href="#post-quantum-era">
        
      </a>
    </div>
    <p>Looking ahead, quantum computers introduce a serious risk: data encrypted today can be harvested and decrypted years later once quantum attacks become practical. To counter this <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later"><u>harvest-now, decrypt-later</u></a> threat, the industry is moving towards post-quantum cryptography (PQC)—algorithms designed to withstand quantum attacks. We have extensively written on this subject <a href="https://blog.cloudflare.com/tag/post-quantum/"><u>in our previous blogs</u></a>.</p><p>In August 2024, NIST finalized its PQC standards: <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf"><u>ML-KEM</u></a> for key agreement, and <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.204.pdf"><u>ML-DSA</u></a> and <a href="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.205.pdf"><u>SLH-DSA</u></a> for digital signatures. In collaboration with industry partners, Cloudflare has helped drive the development and deployment of PQC. We have deployed the hybrid key agreement, combining ML-KEM (post-quantum secure) and X25519 (classical), to secure TLS 1.3 traffic to our servers and internal systems. As of mid-September 2025, <a href="https://radar.cloudflare.com/adoption-and-usage#post-quantum-encryption-adoption"><u>around 43%</u></a> of human-generated connections to Cloudflare are already protected with the hybrid post-quantum secure key agreement – a huge milestone in preparing the Internet for the quantum era.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2hgIUNO8TM50kvAOvzQ8rg/cdbe5b3d64390fc4b946036e2f37471d/6.png" />
          </figure><p>But things look different on the other side of the network. When Cloudflare connects to origins, we act as the client, navigating a fragmented landscape of hosting providers, software stacks, and middleboxes. Each origin may support a different set of cryptographic features, and not all are ready for hybrid post-quantum handshakes.</p><p>To manage this diversity without the risk of breaking connections, we relied on <i>HelloRetryRequest</i>. Instead of sending post-quantum keyshare immediately in the <i>ClientHello</i>, we only advertise support for it. If the origin server supports the post-quantum key agreement, it uses <i>HelloRetryRequest</i> to request it from Cloudflare, and creates the post-quantum connection. The downside is this extra round trip (from the retry) cancels out the performance gains of TLS 1.3 and makes the connection feel closer to TLS 1.2 for uncached requests.</p><p>Back in 2023, <a href="https://developers.cloudflare.com/ssl/post-quantum-cryptography/pqc-to-origin/"><u>we launched an API endpoint</u></a>, so customers could manually opt their origins into preferring post-quantum connections. If set, we avoid the extra roundtrip and try to create a post-quantum connection at the start of the TLS session. Similarly, we extended post-quantum protection to <a href="https://blog.cloudflare.com/post-quantum-tunnel/"><u>Cloudflare tunnel</u></a>, making it one of the easiest ways to get origin-facing PQ today.</p><p><b>Starting Q4 2025, we’re taking the next step – making it </b><b><i>automatic</i></b><b>. </b>Just as we’ve done with SSL/TLS upgrades, Automatic SSL/TLS will begin testing, ramping, and enabling post-quantum handshakes with origins—without requiring customers to change a thing, as long as their origins support post-quantum key agreement.</p><p>Behind the scenes, we’re already scanning active origins about every 24 hours to test support and preferences for both classical and post-quantum key agreements. We’ve worked directly with vendors and customers to identify compatibility issues, and this new scanning system will be fully integrated into <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/#automatic-ssltls-default"><u>Automatic SSL/TLS</u></a>.</p><p>And the benefits won't stop at post-quantum. Even for classical handshakes, optimization matters. Today, the X25519 algorithm is used by default, but <b>our scanning data shows that more than 6% of origins currently prefer a different key agreement algorithm, </b>which leads to unnecessary <i>HelloRetryRequests </i>and wasted round trips<b>.</b> By folding this scanning data into Automatic SSL/TLS, we’ll improve connection establishment for classical TLS as well—squeezing out extra speed and reliability across the board.</p><p>As enterprises and hosting providers adopt PQC, our preliminary scanning pipeline has already found that <b>around 4% of origins could benefit from a post-quantum-preferred key agreement even today</b>, as shown below. This is an 8x increase since <a href="https://blog.cloudflare.com/post-quantum-to-origins/"><u>we started our scans in 2023</u></a>. We expect this number to grow at a steady pace as the industry continues to migrate to post-quantum protocols.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3g2Um1vTz6cuCtoYWtMU4C/7551fb50305a8512fa7cc22844024b99/8.png" />
          </figure><p>As part of this change, we will also<b> phase out</b> support for the pre-standard version X25519Kyber768 to support the final ML-KEM standard, again using a hybrid, from edge to origin connections.</p><p>With Automatic SSL/TLS, we will soon by default scan your origins proactively to directly send the most preferred keyshare to your origin removing the need for any extra roundtrip, improving both security and performance of your origin connections collectively.</p><p>At Cloudflare, we’ve always believed security is a right, not a privilege. From Universal SSL to post-quantum cryptography, our mission has been to make the strongest protections free and available to everyone. <b>Automatic SSL/TLS</b> is the next step—upgrading every domain to the best protocols automatically. Check the SSL/TLS section of your dashboard to ensure it’s enabled and join the millions of sites already secured for today and ready for tomorrow.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Encryption]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[CDN]]></category>
            <guid isPermaLink="false">7nO4wFW304Eh2r48934ugz</guid>
            <dc:creator>Alex Krivit</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Yawar Jamal</dc:creator>
        </item>
        <item>
            <title><![CDATA[HTTPS-only for Cloudflare APIs: shutting the door on cleartext traffic]]></title>
            <link>https://blog.cloudflare.com/https-only-for-cloudflare-apis-shutting-the-door-on-cleartext-traffic/</link>
            <pubDate>Thu, 20 Mar 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ We are closing the cleartext HTTP ports entirely for Cloudflare API traffic. This prevents the risk of clients unintentionally leaking their secret API keys in cleartext during the initial request.  ]]></description>
            <content:encoded><![CDATA[ <p>Connections made over cleartext HTTP ports risk exposing sensitive information because the data is transmitted unencrypted and can be intercepted by network intermediaries, such as ISPs, Wi-Fi hotspot providers, or malicious actors on the same network. It’s common for servers to either <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections"><u>redirect</u></a> or return a <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403"><u>403 (Forbidden)</u></a> response to close the HTTP connection and enforce the use of HTTPS by clients. However, by the time this occurs, it may be too late, because sensitive information, such as an API token, may have already been <a href="https://jviide.iki.fi/http-redirects"><u>transmitted in cleartext</u></a> in the initial client request. This data is exposed before the server has a chance to redirect the client or reject the connection.</p><p>A better approach is to refuse the underlying cleartext connection by closing the <a href="https://developers.cloudflare.com/fundamentals/reference/network-ports/"><u>network ports</u></a> used for plaintext HTTP, and that’s exactly what we’re going to do for our customers.</p><p><b>Today we’re announcing that we’re closing all of the </b><a href="https://developers.cloudflare.com/fundamentals/reference/network-ports/#network-ports-compatible-with-cloudflares-proxy:~:text=HTTP%20ports%20supported%20by%20Cloudflare"><b><u>HTTP ports</u></b></a><b> on api.cloudflare.com.</b> We’re also making changes so that api.cloudflare.com can change IP addresses dynamically, in line with on-going efforts to <a href="https://blog.cloudflare.com/addressing-agility/"><u>decouple names from IP addresses</u></a>, and reliably <a href="https://blog.cloudflare.com/topaz-policy-engine-design/"><u>managing</u></a> addresses in our authoritative DNS. This will enhance the agility and flexibility of our API endpoint management. Customers relying on static IP addresses for our API endpoints will be notified in advance to prevent any potential availability issues.</p><p>In addition to taking this first step to secure Cloudflare API traffic, we’ll release the ability for customers to opt-in to safely disabling all HTTP port traffic for their websites on Cloudflare. We expect to make this free security feature available in the last quarter of 2025.</p><p>We have <a href="https://blog.cloudflare.com/introducing-universal-ssl/"><u>consistently</u></a> <a href="https://blog.cloudflare.com/enforce-web-policy-with-hypertext-strict-transport-security-hsts/"><u>advocated</u></a> for <a href="https://blog.cloudflare.com/post-quantum-for-all/"><u>strong encryption standards</u></a> to safeguard users’ data and privacy online. As part of our ongoing commitment to enhancing Internet security, this blog post details our efforts to <i>enforce</i> HTTPS-only connections across our global network. </p>
    <div>
      <h3>Understanding the problem</h3>
      <a href="#understanding-the-problem">
        
      </a>
    </div>
    <p>We already provide an “<a href="https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/"><u>Always Use HTTPS</u></a>” setting that can be used to redirect all visitor traffic on our customers’ domains (and subdomains) from HTTP (plaintext) to HTTPS (encrypted). For instance, when a user clicks on an HTTP version of the URL on the site (http://www.example.com), we issue an HTTP 3XX redirection status code to immediately redirect the request to the corresponding HTTPS version (https://www.example.com) of the page. While this works well for most scenarios, there’s a subtle but important risk factor: What happens if the initial plaintext HTTP request (before the redirection) contains sensitive user information?</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2mXYZL0JRZOb8J6Tqm4mCj/1b24b76335ad9cf3f3b630ef31868f6c/1.png" />
          </figure><p><sup><i>Initial plaintext HTTP request is exposed to the network before the server can redirect to the secure HTTPS connection.</i></sup></p><p>Third parties or intermediaries on shared networks could intercept sensitive data from the first plaintext HTTP request, or even carry out a <a href="https://blog.cloudflare.com/monsters-in-the-middleboxes/"><u>Monster-in-the-Middle (MITM)</u></a> attack by impersonating the web server.</p><p>One may ask if <a href="https://developers.cloudflare.com/ssl/edge-certificates/additional-options/http-strict-transport-security/"><u>HTTP Strict Transport Security (HSTS)</u></a> would partially alleviate this concern by ensuring that, after the first request, visitors can only access the website over HTTPS without needing a redirect. While this does reduce the window of opportunity for an adversary, the first request still remains exposed. Additionally, HSTS is not applicable by default for most non-user-facing use cases, such as API traffic from stateless clients. Many API clients don’t retain browser-like state or remember HSTS headers they've encountered. It is quite <a href="https://jviide.iki.fi/http-redirects"><u>common practice</u></a> for API calls to be redirected from HTTP to HTTPS, and hence have their initial request exposed to the network.</p><p>Therefore, in line with our <a href="https://blog.cloudflare.com/dogfooding-from-home/"><u>culture of dogfooding</u></a>, we evaluated the accessibility of the Cloudflare API (<a href="https://api.cloudflare.com"><u>api.cloudflare.com</u></a>) over <a href="https://developers.cloudflare.com/fundamentals/reference/network-ports/#:~:text=ports%20listed%20below.-,HTTP,-ports%20supported%20by"><u>HTTP ports (80, and others)</u></a>. In that regard, imagine a client making an initial request to our API endpoint that includes their <i>secret API key</i>. While we outright reject all plaintext connections with a 403 Forbidden response instead of redirecting for API traffic — clearly indicating that “<i>Cloudflare API is only accessible over TLS”</i> — this rejection still happens at the <a href="https://www.cloudflare.com/learning/ddos/what-is-layer-7/">application layer</a>. By that point, the API key may have already been exposed over the network before we can even reject the request. We do have a notification mechanism in place to alert customers and rotate their API keys accordingly, but a stronger approach would be to eliminate the exposure entirely. We have an opportunity to improve!</p>
    <div>
      <h3>A better approach to API security</h3>
      <a href="#a-better-approach-to-api-security">
        
      </a>
    </div>
    <p>Any API key or token exposed in plaintext on the public Internet should be considered compromised. We can either address exposure after it occurs or prevent it entirely. The reactive approach involves continuously tracking and revoking compromised credentials, requiring active management to rotate each one. For example, when a plaintext HTTP request is made to our API endpoints, we detect exposed tokens by scanning for 'Authorization' header values.</p><p>In contrast, a preventive approach is stronger and more effective, stopping exposure before it happens. Instead of relying on the API service application to react after receiving potentially sensitive cleartext data, we can preemptively refuse the underlying connection at the <a href="https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/"><u>transport layer</u></a>, before any HTTP or application-layer data is exchanged. The <i>preventative </i>approach can be achieved by closing all plaintext HTTP ports for API traffic on our global network. The added benefit is that this is operationally much simpler: by eliminating cleartext traffic, there's no need for key rotation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1PYo3GMZjQ4LbfUHXNOVpj/2341da1d926e077624563358bd5034ef/2.png" />
          </figure><p><sup><i>The transport layer carries the application layer data on top.</i></sup></p><p>To explain why this works: an application-layer request requires an underlying transport connection, like TCP or QUIC, to be established first. The combination of a port number and an IP address serves as a transport layer identifier for creating the underlying transport channel. Ports direct network traffic to the correct application-layer process — for example, port 80 is designated for plaintext HTTP, while port 443 is used for encrypted HTTPS. By disabling the HTTP cleartext server-side port, we prevent that transport channel from being established during the initial "<a href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/"><u>handshake</u></a>" phase of the connection — before any application data, such as a secret API key, leaves the client’s machine.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/13fKw8cHkHlsLOzlXJYenr/c9156f67ae99cfdc74dc5917ebc1e5bb/3.png" />
          </figure><p><sup><i>Both TCP and QUIC transport layer handshakes are a pre-requisite for HTTPS application data exchange on the web.</i></sup></p><p>Therefore, closing the HTTP interface entirely for API traffic gives a strong and visible <b>fast-failure</b> signal to developers that might be mistakenly accessing <code>http://… </code>instead of <code>https://…</code> with their secret API keys in the first request — a simple one-letter omission, but one with serious implications.</p><p>In theory, this is a simple change, but at Cloudflare’s global scale, implementing it required careful planning and execution. We’d like to share the steps we took to make this transition.</p>
    <div>
      <h3>Understanding the scope</h3>
      <a href="#understanding-the-scope">
        
      </a>
    </div>
    <p>In an ideal scenario, we could simply close all cleartext HTTP ports on our network. However, two key challenges prevent this. First, as shown in the <a href="https://radar.cloudflare.com/adoption-and-usage#http-vs-https"><u>Cloudflare Radar</u></a> figure below, about 2-3% of requests from “likely human” clients to our global network are over plaintext HTTP. While modern browsers prominently warn users about insecure HTTP connections and <a href="https://support.mozilla.org/en-US/kb/https-only-prefs"><u>offer features to silently upgrade to HTTPS</u></a>, this protection doesn't extend to the broader ecosystem of connected devices. IoT devices with limited processing power, automated API clients, or legacy software stacks often lack such safeguards entirely. In fact, when filtering on plaintext HTTP traffic that is “likely automated”, the share <a href="https://radar.cloudflare.com/explorer?dataSet=http&amp;groupBy=http_protocol&amp;filters=botClass%253DLikely_Automated"><u>rises to over 16%</u></a>! We continue to see a wide variety of legacy clients accessing resources over plaintext connections. This trend is not confined to specific networks, but is observable globally.</p><p>Closing HTTP ports, like port 80, across our entire IP address space would block such clients entirely, causing a major disruption in services. While we plan to cautiously start by implementing the change on Cloudflare's API IP addresses, it’s not enough. Therefore, our goal is to ensure all of our customers’ API traffic benefits from this change as well.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1OfUjwkP9iMdjymjtJX7tL/4cd278faf71f610c43239cc41d8f6fba/4.png" />
          </figure><p><sup><i>Breakdown of HTTP and HTTPS for ‘human’ connections</i></sup></p><p>The second challenge relates to limitations posed by the longstanding <a href="https://en.wikipedia.org/wiki/Berkeley_sockets"><u>BSD Sockets API</u></a> at the server-side, which we have addressed using <a href="https://blog.cloudflare.com/tubular-fixing-the-socket-api-with-ebpf/"><u>Tubular</u></a>, a tool that inspects every connection terminated by a server and decides which application should receive it. Operators historically have faced a challenging dilemma: either listen to the same ports across many IP addresses using a single socket (scalable but inflexible), or maintain individual sockets for each IP address (flexible but unscalable). Luckily, Tubular has allowed us to <a href="https://blog.cloudflare.com/its-crowded-in-here/"><u>resolve this using 'bindings'</u></a>, which decouples sockets from specific IP:port pairs. This creates efficient pathways for managing endpoints throughout our systems at scale, enabling us to handle both HTTP and HTTPS traffic intelligently without the traditional limitations of socket architecture.</p><p>Step 0, then, is about provisioning both IPv4 and IPv6 address space on our network that by default has all HTTP ports closed. Tubular enables us to configure and manage these IP addresses differently than others for our endpoints. Additionally, <a href="https://blog.cloudflare.com/addressing-agility/"><u>Addressing Agility</u></a> and <a href="https://blog.cloudflare.com/topaz-policy-engine-design/"><u>Topaz</u></a> enable us to assign these addresses dynamically, and safely, for opted-in domains.</p>
    <div>
      <h3>Moving from strategy to execution</h3>
      <a href="#moving-from-strategy-to-execution">
        
      </a>
    </div>
    <p>In the past, our legacy stack would have made this transition challenging, but today’s Cloudflare possesses the appropriate tools to deliver a scalable solution, rather than addressing it on a domain-by-domain basis.</p><p>Using Tubular, we were able to bind our new set of anycast IP prefixes to our TLS-terminating proxies across the globe. To ensure that no plaintext HTTP traffic is served on these IP addresses, we extended our global <a href="https://en.wikipedia.org/wiki/Iptables"><u>iptables</u></a> firewall configuration to reject any inbound packets on HTTP ports.</p>
            <pre><code>iptables -A INPUT -p tcp -d &lt;IP_ADDRESS_BLOCK&gt; --dport &lt;HTTP_PORT&gt; -j REJECT 
--reject-with tcp-reset

iptables -A INPUT -p udp -d &lt;IP_ADDRESS_BLOCK&gt; --dport &lt;HTTP_PORT&gt; -j REJECT 
--reject-with icmp-port-unreachable</code></pre>
            <p>As a result, any connections to these IP addresses on HTTP ports are filtered and rejected at the transport layer, eliminating the need for state management at the application layer by our web proxies.</p><p>The next logical step is to update the <a href="https://www.cloudflare.com/learning/dns/what-is-dns/"><u>DNS assignments</u></a> so that API traffic is routed over the <i>correct</i> IP addresses. In our case, we encoded a new DNS policy for API traffic for the HTTPS-only interface as a declarative <a href="https://blog.cloudflare.com/topaz-policy-engine-design/"><u>Topaz program</u></a> in our authoritative DNS server:</p>
            <pre><code>- name: https_only
 exclusive: true 
 config: |
    (config
      ([traffic_class "API"]
       [ipv4 (ipv4_address “192.0.2.1”)] # Example IPv4 address
       [ipv6 (ipv6_address “2001:DB8::1:1”)] # Example IPv6 address
       [t (ttl 300]))
  match: |
    (= query_domain_class traffic_class)
  response: |
    (response (list ipv4) (list ipv6) t)</code></pre>
            <p>The above policy encodes that for any DNS query targeting the ‘API traffic’ class, we return the respective HTTPS-only interface IP addresses. Topaz’s safety guarantees ensure <i>exclusivity</i>, preventing other DNS policies from inadvertently matching the same queries and misrouting plaintext HTTP expected domains to HTTPS-only IPs

api.cloudflare.com is the first domain to be added to our HTTPS-only API traffic class, with other applicable endpoints to follow.</p>
    <div>
      <h3>Opting-in your API endpoints</h3>
      <a href="#opting-in-your-api-endpoints">
        
      </a>
    </div>
    <p>As we said above, we've started with api.cloudflare.com and our internal API endpoints to thoroughly monitor any side effects on our own systems before extending this feature to customer domains. We have deployed these changes gradually across all data centers, leveraging Topaz’s flexibility to target subsets of traffic, minimizing disruptions, and ensuring a smooth transition.</p><p>To monitor unencrypted connections for your domains, before blocking access using the feature, you can review the relevant analytics on the Cloudflare dashboard. Log in, select your account and domain, and navigate to the "<a href="https://developers.cloudflare.com/analytics/types-of-analytics/#account-analytics-beta"><u>Analytics &amp; Logs</u></a>" section. There, under the "<i>Traffic Served Over SSL</i>" subsection, you will find a breakdown of encrypted and unencrypted traffic for your site. That data can help provide a baseline for assessing the volume of plaintext HTTP connections for your site that will be blocked when you opt in. After opting in, you would expect no traffic for your site will be served over plaintext HTTP, and therefore that number should go down to zero.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4YjvOU3XQqj1Y2Kfv2jIL3/97178a99d17f8938bc3ec53704bbc4b8/5.png" />
          </figure><p><i>Snapshot of ‘Traffic Served Over SSL’ section on Cloudflare dashboard</i></p><p>Towards the last quarter of 2025, we will provide customers the ability to opt in their domains using the dashboard or API (similar to enabling the Always Use HTTPS feature). Stay tuned!</p>
    <div>
      <h3>Wrapping up</h3>
      <a href="#wrapping-up">
        
      </a>
    </div>
    <p>Starting today, any unencrypted connection to api.cloudflare.com will be completely rejected. Developers should <b>not</b> expect a 403 Forbidden response any longer for HTTP connections, as we will prevent the underlying connection to be established by closing the HTTP interface entirely. Only secure HTTPS connections will be allowed to be established.</p><p>We are also making updates to transition api.cloudflare.com away from its static IP addresses in the future. As part of that change, we will be discontinuing support for <a href="https://developers.cloudflare.com/ssl/reference/browser-compatibility/#non-sni-support"><u>non-SNI</u></a> legacy clients for Cloudflare API specifically — currently, an average of just 0.55% of TLS connections to the Cloudflare API do not include an <a href="https://www.cloudflare.com/learning/ssl/what-is-sni/">SNI</a> value. These non-SNI connections are initiated by a small number of accounts. We are committed to coordinating this transition and will work closely with the affected customers before implementing the change. This initiative aligns with our goal of enhancing the agility and reliability of our API endpoints.</p><p>Beyond the Cloudflare API use case, we're also exploring other areas where it's safe to close plaintext traffic ports. While the long tail of unencrypted traffic may persist for a while, it shouldn’t be forced on every site.

In the meantime, a small step like this can allow us to have a big impact in helping make a better Internet, and we are working hard to reliably bring this feature to your domains. We believe security should be free for all!</p> ]]></content:encoded>
            <category><![CDATA[Security Week]]></category>
            <category><![CDATA[HTTPS]]></category>
            <category><![CDATA[API]]></category>
            <category><![CDATA[Addressing]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">RqjV9vQoPNX8txlmrju6d</guid>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Ash Pallarito</dc:creator>
            <dc:creator>Algin Martin</dc:creator>
        </item>
        <item>
            <title><![CDATA[How we prevent conflicts in authoritative DNS configuration using formal verification]]></title>
            <link>https://blog.cloudflare.com/topaz-policy-engine-design/</link>
            <pubDate>Fri, 08 Nov 2024 14:00:00 GMT</pubDate>
            <description><![CDATA[ We describe how Cloudflare uses a custom Lisp-like programming language and formal verifier (written in Racket and Rosette) to prevent logical contradictions in our authoritative DNS nameserver’s behavior. ]]></description>
            <content:encoded><![CDATA[ <p>Over the last year, Cloudflare has begun formally verifying the correctness of our internal DNS addressing behavior — the logic that determines which IP address a DNS query receives when it hits our authoritative nameserver. This means that for every possible DNS query for a <a href="https://developers.cloudflare.com/dns/manage-dns-records/reference/proxied-dns-records/"><u>proxied</u></a> domain we could receive, we try to mathematically prove properties about our DNS addressing behavior, even when different systems (owned by different teams) at Cloudflare have contradictory views on which IP addresses should be returned.</p><p>To achieve this, we formally verify the programs — written in a custom <a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)"><u>Lisp</u></a>-like programming language — that our nameserver executes when it receives a DNS query. These programs determine which IP addresses to return. Whenever an engineer changes one of these programs, we run all the programs through our custom model checker (written in <a href="https://racket-lang.org/"><u>Racket</u></a> + <a href="https://emina.github.io/rosette/"><u>Rosette</u></a>) to check for certain bugs (e.g., one program overshadowing another) before the programs are deployed.</p><p>Our formal verifier runs in production today, and is part of a larger addressing system called Topaz. In fact, it’s likely you’ve made a DNS query today that triggered a formally verified Topaz program.</p><p>This post is a technical description of how Topaz’s formal verification works. Besides being a valuable tool for Cloudflare engineers, Topaz is a real-world example of <a href="https://en.wikipedia.org/wiki/Formal_verification"><u>formal verification</u></a> applied to networked systems. We hope it inspires other network operators to incorporate formal methods, where appropriate, to help make the Internet more reliable for all.</p><p>Topaz’s full technical details have been peer-reviewed and published in <a href="https://conferences.sigcomm.org/sigcomm/2024/"><u>ACM SIGCOMM 2024</u></a>, with both a <a href="https://research.cloudflare.com/publications/Larisch2024/"><u>paper</u></a> and short <a href="https://www.youtube.com/watch?v=hW7RjXVx7_Q"><u>video</u></a> available online. </p>
    <div>
      <h2>Addressing: how IP addresses are chosen</h2>
      <a href="#addressing-how-ip-addresses-are-chosen">
        
      </a>
    </div>
    <p>When a DNS query for a customer’s proxied domain hits Cloudflare’s nameserver, the nameserver returns an IP address — but how does it decide which address to return?</p><p>Let’s make this more concrete. When a customer, say <code>example.com</code>, signs up for Cloudflare and <a href="https://developers.cloudflare.com/dns/manage-dns-records/reference/proxied-dns-records/"><u>proxies</u></a> their traffic through Cloudflare, it makes Cloudflare’s nameserver <i>authoritative</i> for their domain, which means our nameserver has the <i>authority </i>to respond to DNS queries for <code>example.com</code>. Later, when a client makes a DNS query for <code>example.com</code>, the client’s recursive DNS resolver (for example, <a href="https://www.cloudflare.com/learning/dns/what-is-1.1.1.1/"><u>1.1.1.1</u></a>) queries our nameserver for the authoritative response. Our nameserver returns <b><i>some</i></b><i> </i>Cloudflare IP address (of our choosing) to the resolver, which forwards that address to the client. The client then uses the IP address to connect to Cloudflare’s network, which is a global <a href="https://www.cloudflare.com/en-gb/learning/cdn/glossary/anycast-network/"><u>anycast</u></a> network — every data center advertises all of our addresses.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/72EmlVrMTMBMhxrhZ50YI9/54e08160ea98c55bc8e2703d7c85927b/image3.png" />
          </figure><p><sup>Clients query Cloudflare’s nameserver (via their resolver) for customer domains. The nameserver returns Cloudflare IP addresses, advertised by our entire global network, which the client uses to connect to the customer domain. Cloudflare may then connect to the origin server to fulfill the user’s HTTPS request.</sup></p><p>When the customer has <a href="https://developers.cloudflare.com/byoip/"><u>configured a static IP address</u></a> for their domain, our nameserver’s choice of IP address is simple: it simply returns that static address in response to queries made for that domain.</p><p>But for all other customer domains, our nameserver could respond with virtually any IP address that we own and operate. We may return the <i>same</i> address in response to queries for <i>different</i> domains, or <i>different</i> addresses in response to different queries for the <i>same</i> domain. We do this for resilience, but also because decoupling names and IP addresses <a href="https://blog.cloudflare.com/addressing-agility"><u>improves flexibility</u></a>.</p><p>With all that in mind, let’s return to our initial question: given a query for a proxied domain without a static IP, which IP address should be returned? The answer: <b>Cloudflare chooses IP addresses to meet various business objectives. </b>For instance, we may choose IPs to:</p><ul><li><p>Change the IP address of a domain that is under attack.</p></li><li><p>Direct fractions of traffic to specific IP addresses to test new features or services.</p></li><li><p><a href="https://blog.cloudflare.com/cloudflare-incident-on-september-17-2024/"><u>Remap or “renumber”</u></a> domain names to new IP address space.</p></li></ul>
    <div>
      <h2>Topaz executes DNS objectives</h2>
      <a href="#topaz-executes-dns-objectives">
        
      </a>
    </div>
    <p>To change authoritative nameserver behavior — how we choose IPs —  a Cloudflare engineer encodes their desired DNS business objective as a declarative Topaz program. Our nameserver stores the list of all such programs such that when it receives a DNS query for a proxied domain, it executes the list of programs in sequence until one returns an IP address. It then returns that IP to the resolver.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3gyUw7j0GlTXj0Vm637aCW/9aa353d512151d5878998e199a538973/image1.png" />
          </figure><p><sup>Topaz receives DNS queries (metadata included) for proxied domains from Cloudflare’s nameserver. It executes a list of policies in sequence until a match is found. It returns the resulting IP address to the nameserver, which forwards it to the resolver.</sup></p><p>What do these programs look like?</p><p>Each Topaz program has three primary components:</p><ol><li><p><b>Match function: </b>A program’s match function specifies under which circumstances the program should execute. It takes as input DNS query metadata (e.g., datacenter information, account information) and outputs a boolean. If, given a DNS query, the match function returns <i>true</i>, the program’s response function is executed.</p></li><li><p><b>Response function</b>: A program’s response function specifies <i>which</i> IP addresses should be chosen. It also takes as input all the DNS query metadata, but outputs a 3-tuple (IPv4 addresses, IPv6 addresses, and TTL). When a program’s match function returns true, its corresponding response function is executed. The resulting IP addresses and TTL are returned to the resolver that made the query. </p></li><li><p><b>Configuration</b>: A program’s configuration is a set of variables that parameterize that program’s match and response function. The match and response functions reference variables in the corresponding configuration, thereby separating the macro-level behavior of a program (match/response functions) from its nitty-gritty details (specific IP addresses, names, etc.). This separation makes it easier to understand how a Topaz program behaves at a glance, without getting bogged down by specific function parameters.</p></li></ol><p>Let’s walk through an example Topaz program. The goal of this program is to give all queried domains whose metadata field “tag1” is equal to “orange” a particular IP address. The program looks like this:</p>
            <pre><code>- name: orange
  config: |
    (config
      ([desired_tag1 "orange"]
       [ipv4 (ipv4_address “192.0.2.3”)]
       [ipv6 (ipv6_address “2001:DB8:1:3”)]
       [t (ttl 300]))
  match: |
    (= query_domain_tag1 desired_tag1) 
  response: |
    (response (list ipv4) (list ipv6) t)</code></pre>
            <p>Before we walk through the program, note that the program’s configuration, match, and response function are YAML strings, but more specifically they are topaz-lang expressions. Topaz-lang is the <a href="https://en.wikipedia.org/wiki/Domain-specific_language"><u>domain-specific language (DSL)</u></a> we created specifically for expressing Topaz programs. It is based on <a href="https://www.scheme.org/"><u>Scheme</u></a>, but is much simpler. It is dynamically typed, it is not <a href="https://en.wikipedia.org/wiki/Turing_completeness"><u>Turing complete</u></a>, and every expression evaluates to exactly one value (though functions can throw errors). Operators cannot define functions within topaz-lang, they can only add new DSL functions by writing functions in the host language (Go). The DSL provides basic types (numbers, lists, maps) but also Topaz-specific types, like IPv4/IPv6 addresses and TTLs.</p><p>Let’s now examine this program in detail. </p><ul><li><p>The <code>config</code> is a set of four <i>bindings</i> from name to value. The first binds the string <code>”orange”</code> to the name <code>desired_tag1</code>. The second binds the IPv4 address <code>192.0.2.3</code> to the name <code>ipv4</code>. The third binds the IPv6 address <code>2001:DB8:1:3</code> to the name <code>ipv6</code>. And the fourth binds the TTL (for which we added a topaz-lang type) <code>300</code> (seconds) to the name <code>t</code>.</p></li><li><p>The <code>match</code> function is an expression that <i>must</i> evaluate to a boolean. It can reference configuration values (e.g., <code>desired_tag1</code>), and can also reference DNS query fields. All DNS query fields use the prefix <code>query_</code> and are brought into scope at evaluation time. This program’s match function checks whether <code>desired_tag1</code> is equal to the tag attached to the queried domain, <code>query_domain_tag1</code>. </p></li><li><p>The <code>response</code> function is an expression that evaluates to the special <code>response</code> type, which is really just a 3-tuple consisting of: a list of IPv4 addresses, a list of IPv6 addresses, and a TTL. This program’s response function simply returns the configured IPv4 address, IPv6 address, and TTL (seconds).</p></li></ul><p>Critically, <i>all</i> Topaz programs are encoded as YAML and live in the same version-controlled file. Imagine this program file contained only the <code>orange</code> program above, but now, a new team wants to add a new program, which checks whether the queried domain’s “tag1” field is equal to “orange” AND that the domain’s “tag2” field is equal to true:</p>
            <pre><code>- name: orange_and_true
  config: |
    (config
      ([desired_tag1 "orange"]
       [ipv4 (ipv4_address “192.0.2.2”)]
       [ipv6 (ipv6_address “2001:DB8:1:2”)]
       [t (ttl 300)]))
  match: |
    (and (= query_domain_tag1 desired_tag1)
         query_domain_tag2)
  response: |
    (response (list ipv4) (list ipv6) t)</code></pre>
            <p>This new team must place their new <code>orange_and_true</code> program either below or above the <code>orange</code> program in the file containing the list of Topaz programs. For instance, they could place <code>orange_and_true</code> after <code>orange</code>, like so:</p>
            <pre><code>- name: orange
  config: …
  match: …
  response: …
- name: orange_and_true
  config: …
  match: …
  response: …</code></pre>
            <p>Now let’s add a third, more interesting Topaz program. Say a Cloudflare team wants to test a modified version of our CDN’s HTTP server on a small percentage of domains, and only in a subset of Cloudflare’s data centers. Furthermore, they want to distribute these queries across a specific IP prefix such that queries for the same domain get the same IP. They write the following:</p>
            <pre><code>- name: purple
  config: |
    (config
      ([purple_datacenters (fetch_datacenters “purple”)]
       [percentage 10]
       [ipv4_prefix (ipv4_prefix “203.0.113.0/24”)]
       [ipv6_prefix (ipv6_prefix “2001:DB8:3::/48”)]))
  match: |
    (let ([rand (rand_gen (hash query_domain))])
      (and (member? purple_datacenters query_datacenter)
           (&lt; (random_number (range 0 99) rand) percentage)))
  response: |
    (let ([hashed_domain (hash query_domain)]
          [ipv4_address (select_from ipv4_prefix hashed_domain)]
          [ipv6_address (select_from ipv6_prefix hashed_domain)])
      (response (list ipv4_address) (list ipv6_address) (ttl 1)))</code></pre>
            <p>This Topaz program is significantly more complicated, so let’s walk through it.</p><p>Starting with configuration: </p><ul><li><p>The first configuration value, <code>purple_datacenters</code>, is bound to the expression <code>(fetch_datacenters “purple”)</code>, which is a function that retrieves all Cloudflare data centers tagged “purple” via an internal HTTP API. The result of this function call is a list of data centers. </p></li><li><p>The second configuration value, <code>percentage</code>, is a number representing the fraction of traffic we would like our program to act upon.</p></li><li><p>The third and fourth names are bound to IP prefixes, v4 and v6 respectively (note the <code>built-in ipv4_prefix</code> and <code>ipv6_prefix</code> types).</p></li></ul><p>The match function is also more complicated. First, note the <code>let</code> form — this lets operators define local variables. We define one local variable, a random number generator called <code>rand</code> seeded with the hash of the queried domain name. The match expression itself is a conjunction that checks two things. </p><ul><li><p>First, it checks whether the query landed in a data center tagged “purple”. </p></li><li><p>Second, it checks whether a random number between 0 and 99 (produced by a generator seeded by the domain name) is less than the configured percentage. By seeding the random number generator with the domain, the program ensures that 10% of <i>domains</i> trigger a match. If we had seeded the RNG with, say, the query ID, then queries for the same domain would behave differently.</p></li></ul><p>Together, the conjuncts guarantee that the match expression evaluates to true for 10% of domains queried in “purple” data centers.</p><p>Now let’s look at the response function. We define three local variables. The first is a hash of the domain. The second is an IPv4 address selected from the configured IPv4 prefix. <code>select_from</code> always chooses the same IP address given the same prefix and hash — this ensures that queries for a given domain always receive the same IP address (which makes it easier to correlate queries for a single domain), but that queries for different domains can receive different IP addresses within the configured prefix. The third local variable is an IPv6 address selected similarly. The response function returns these IP addresses and a TTL of value 1 (second).</p>
    <div>
      <h2>Topaz programs are executed on the hot path</h2>
      <a href="#topaz-programs-are-executed-on-the-hot-path">
        
      </a>
    </div>
    <p>Topaz’s control plane validates the list of programs and distributes them to our global nameserver instances. As we’ve seen, the list of programs reside in a single, version-controlled YAML file. When an operator changes this file (i.e., adds a program, removes a program, or modifies an existing program), Topaz’s control plane does the following things in order:</p><ul><li><p>First, it validates the programs, making sure there are no syntax errors. </p></li><li><p>Second, it “finalizes” each program’s configuration by evaluating every configuration binding and storing the result. (For instance, to finalize the <code>purple</code> program, it evaluates <code>fetch_datacenters</code>, storing the resulting list. This way our authoritative nameservers never need to retrieve external data.) </p></li><li><p>Third, it <i>verifies</i> the finalized programs, which we will explain below. </p></li><li><p>Finally, it distributes the finalized programs across our network.</p></li></ul><p>Topaz’s control plane distributes the programs to all servers globally by writing the list of programs to <a href="https://blog.cloudflare.com/introducing-quicksilver-configuration-distribution-at-internet-scale/"><u>QuickSilver</u></a>, our edge key-value store. The Topaz service on each server detects changes in Quicksilver and updates its program list.</p><p>When our nameserver service receives a DNS query, it augments the query with additional metadata (e.g., tags) and then forwards the query to the Topaz service (both services run on every Cloudflare server) via Inter-Process Communication (IPC). Topaz, upon receiving a DNS query from the nameserver, walks through its program list, executing each program’s match function (using the topaz-lang interpreter) with the DNS query in scope (with values prefixed with <code>query_</code>). It walks the list until a match function returns <code>true</code>. It then executes that program’s response function, and returns the resulting IP addresses and TTL to our nameserver. The nameserver packages these addresses and TTL in valid DNS format, and then returns them to the resolver. </p>
    <div>
      <h2>Topaz programs are formally verified</h2>
      <a href="#topaz-programs-are-formally-verified">
        
      </a>
    </div>
    <p>Before programs are distributed to our global network, they are formally verified. Each program is passed through our formal verification tool which throws an error if a program has a bug, or if two programs (e.g., the <code>orange_and_true</code> and <code>orange</code> programs) conflict with one another.</p><p>The Topaz formal verifier (<a href="https://en.wikipedia.org/wiki/Model_checking"><u>model-checker</u></a>) checks three properties.</p><p>First, it checks that each program is <i>satisfiable </i>— that there exists <i>some</i> DNS query that causes each program’s match function to return <code>true</code>. This property is useful for detecting internally-inconsistent programs that will simply never match. For instance, if a program’s match expression was <code>(and true false)</code>, there exists no query that will cause this to evaluate to true, so the verifier throws an error.</p><p>Second, it checks that each program is <i>reachable </i>— that there exists some DNS query that causes each program’s match function to return <code>true</code> <i>given all preceding programs.</i> This property is useful for detecting “dead” programs that are completely overshadowed by higher-priority programs. For instance, recall the ordering of the <code>orange</code> and <code>orange_and_true</code> programs:</p>
            <pre><code>- name: orange
  config: …
  match: (= query_domain_tag1 "orange")  
  response: …
- name: orange_and_true
  config: …
  match: (and (= query_domain_tag1 "orange") query_domain_tag2)
  response: …</code></pre>
            <p>The verifier would throw an error because the <code>orange_and_true</code> program is unreachable. For all DNS queries for which <code>query_domain_tag1</code> is ”orange”, regardless of <code>metadata2</code>, the <code>orange</code> program will <i>always</i> match, which means the <code>orange_and_true</code> program will <i>never</i> match. To resolve this error, we’d need to swap these two programs like we did above.</p><p>Finally, and most importantly, the verifier checks for program <i>conflicts</i>: queries that cause any two programs to both match. If such a query exists, it throws an error (and prints the relevant query), and the operators are forced to resolve the conflict by changing their programs. However, it only checks whether specific programs conflict — those that are explicitly marked <i>exclusive. </i>Operators mark their program as exclusive if they want to be sure that no other exclusive program could match on the same queries.</p><p>To see what conflict detection looks like, consider the corrected ordering of the <code>orange_and_true</code> and <code>orange</code> programs, but note that the two programs have now been marked exclusive:</p>
            <pre><code>- name: orange_and_true
  exclusive: true
  config: ...
  match: (and (= query_domain_tag1 "orange") query_domain_tag2)
  response: ...
- name: orange
  exclusive: true
  config: ...
  match: (= query_domain_tag1 "orange") 
  response: ...</code></pre>
            <p>After marking these two programs exclusive, the verifier will throw an error. Not only will it say that these two programs can contradict one another, but it will provide a sample query as proof:</p>
            <pre><code>Checking: no exclusive programs match the same queries: check FAILED!
Intersecting programs found:
programs "orange_and_true" and "orange" both match any query...
  to any domain...
    with tag1: "orange"
    with tag2: true
</code></pre>
            <p>The teams behind the <code>orange</code> and <code>orange_and_true</code> programs respectively <i>must</i> resolve this conflict before these programs are deployed, and can use the above query to help them do so. To resolve the conflict, the teams have a few options. The simplest option is to remove the exclusive setting from one program, and acknowledge that it is simply not possible for these programs to be <code>exclusive</code>. In that case, the order of the two programs matters (one must have higher priority). This is fine! Topaz allows developers to write certain programs that <i>absolutely cannot </i>overlap with other programs (using <code>exclusive</code>), but sometimes that is just not possible. And when it’s not, at least program priority is <i>explicit.</i></p><p><i>Note: in practice, we place all exclusive programs at the top of the program file. This makes it easier to reason about interactions between exclusive and non-exclusive programs.</i></p><p>In short, verification is powerful not only because it catches bugs (e.g., satisfiability and reachability), but it also highlights the consequences of program changes. It helps operators understand the impact of their changes by providing immediate feedback. If two programs conflict, operators are forced to resolve it before deployment, rather than after an incident.</p><p><b>Bonus: verification-powered diffs. </b>One of the newest features we’ve added to the verifier is one we call <i>semantic diffs</i>. It’s in early stages, but the key insight is that operators often just want to <i>understand</i> the impact of changes, even if these changes are deemed safe. To help operators, the verifier compares the old and new versions of the program file. Specifically, it looks for any query that matched program <i>X</i> in the old version, but matches a different program <i>Y</i> in the new version (or vice versa). For instance, if we changed <code>orange_and_true</code> thus:</p>
            <pre><code>- name: orange_and_true
  config: …
  match: (and (= query_domain_tag1 "orange") (not query_domain_tag2))
  response: …</code></pre>
            <p>Our verifier would emit:</p>
            <pre><code>Generating a report to help you understand your changes...
NOTE: the queries below (if any) are just examples. Other such queries may exist.

* program "orange_and_true" now MATCHES any query...
  to any domain...
    with tag1: "orange"
    with tag2: false</code></pre>
            <p>While not exhaustive, this information helps operators understand whether their changes are doing what they intend or not, <i>before</i> deployment. We look forward to expanding our verifier’s diff capabilities going forward.</p>
    <div>
      <h2>How Topaz’s verifier works, and its tradeoffs</h2>
      <a href="#how-topazs-verifier-works-and-its-tradeoffs">
        
      </a>
    </div>
    <p>How does the verifier work? At a high-level, the verifier checks that, for all possible DNS queries, the three properties outlined above are satisfied. A Satisfiability Modulo Theories (SMT) solver — which we explain below — makes this seemingly impossible operation feasible. (It doesn't literally loop over all DNS queries, but it is equivalent to doing so — it provides exhaustive proof.)</p><p>We implemented our formal verifier in <a href="https://emina.github.io/rosette/"><u>Rosette</u></a>, a solver-enhanced domain-specific language written in the <a href="https://racket-lang.org/"><u>Racket</u></a> programming language. Rosette makes writing a verifier more of an engineering exercise, rather than a formal logic test: if you can express the interpreter for your language in Racket/Rosette, you get verification “for free”, in some sense. We wrote a topaz-lang interpreter in Racket, then crafted our three properties using the Rosette DSL.</p><p>How does Rosette work? Rosette translates our desired properties into formulae in <a href="https://en.wikipedia.org/wiki/First-order_logic"><u>first-order logic</u></a>. At a high level, these formulae are like equations from algebra class in school, with “unknowns” or variables. For instance, when checking whether the orange program is reachable (with the <code>orange_and_true</code> program ordered before it), Rosette produces the formula <code>((NOT orange_and_true.match) AND orange.match)</code>. The “unknowns” here are the DNS query parameters that these match functions operate over, e.g., <code>query_domain_tag1</code>. To solve this formula, Rosette interfaces with an <a href="https://en.wikipedia.org/wiki/Satisfiability_modulo_theories"><u>SMT solver</u></a> (like <a href="https://github.com/Z3Prover/z3"><u>Z3</u></a>), which is specifically designed to solve these types of formulae by efficiently finding values to assign to the DNS query parameters that make the formulae true. Once the SMT solver finds satisfying values, Rosette translates them into a Racket data structure: in our case, a sample DNS query. In this example, once it finds a satisfying DNS query, it would report that the <code>orange</code> program is indeed reachable.</p><p>However, verification is not free. The primary cost is maintenance. The model checker’s interpreter (Racket) must be kept in lockstep with the main interpreter (Go). If they fall out-of-sync, the verifier loses the ability to accurately detect bugs. Furthermore, functions added to topaz-lang must be compatible with formal verification.</p><p>Also, not all functions are easily verifiable, which means we must restrict the kinds of functions that program authors can write. Rosette can only verify functions that operate over integers and bit-vectors. This means we only permit functions whose operations can be converted into operations over integers and bit-vectors. While this seems restrictive, it actually gets us pretty far. The main challenge is strings: Topaz does not support programs that, for example, manipulate or work with substrings of the queried domain name. However, it does support simple operations on closed-set strings. For instance, it supports checking if two domain names are equal, because we can convert all strings to a small set of values representable using integers (which are easily verifiable).</p><p>Fortunately, thanks to our design of Topaz programs, the verifier need not be compatible with all Topaz program code. The verifier only ever examines Topaz <i>match</i> functions, so only the functions specified in match functions need to be verification-compatible. We encountered other challenges when working to make our model accurate, like modeling randomness — if you are interested in the details, we encourage you to read the <a href="https://research.cloudflare.com/publications/Larisch2024/"><u>paper</u></a>.</p><p>Another potential cost is verification speed. We find that the verifier can ensure our existing seven programs satisfy all three properties within about six seconds, which is acceptable because verification happens only at build time. We verify programs centrally, before programs are deployed, and only when programs change. </p><p>We also ran microbenchmarks to determine how fast the verifier can check more programs — we found that, for instance, it would take the verifier about 300 seconds to verify 50 programs. While 300 seconds is still acceptable, we are looking into verifier optimizations that will reduce the time further.</p>
    <div>
      <h2>Bringing formal verification from research to production</h2>
      <a href="#bringing-formal-verification-from-research-to-production">
        
      </a>
    </div>
    <p>Topaz’s verifier began as a <a href="https://research.cloudflare.com/"><u>research</u></a> project, and has since been deployed to production. It formally verifies all changes made to the authoritative DNS behavior specified in Topaz.</p><p>For more in-depth information on Topaz, see both our research <a href="https://research.cloudflare.com/publications/Larisch2024/"><u>paper</u></a> published at SIGCOMM 2024 and the <a href="https://www.youtube.com/watch?v=hW7RjXVx7_Q"><u>recording</u></a> of the talk.</p><p>We thank our former intern, Tim Alberdingk-Thijm, for his invaluable work on Topaz’s verifier.</p> ]]></content:encoded>
            <category><![CDATA[DNS]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Addressing]]></category>
            <category><![CDATA[Formal Methods]]></category>
            <guid isPermaLink="false">5LVsblxj2Git54IRxadpyg</guid>
            <dc:creator>James Larisch</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Marwan Fayed</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing Speed Brain: helping web pages load 45% faster]]></title>
            <link>https://blog.cloudflare.com/introducing-speed-brain/</link>
            <pubDate>Wed, 25 Sep 2024 13:00:00 GMT</pubDate>
            <description><![CDATA[ Speed Brain uses the Speculation Rules API to prefetch content for the user's likely next navigations. The goal is to download a web page to the browser before a user navigates to it. 
 ]]></description>
            <content:encoded><![CDATA[ <p>Each time a user visits your web page, they are initiating a race to receive content as quickly as possible. Performance is a critical <a href="https://www.speedcurve.com/blog/psychology-site-speed/"><u>factor</u></a> that influences how visitors interact with your site. Some might think that moving content across the globe introduces significant latency, but for a while, network transmission speeds have approached their <a href="https://blog.cloudflare.com/fastest-internet/"><u>theoretical limits</u></a>. To put this into perspective, data on Cloudflare can traverse the 11,000 kilometer round trip between New York and London in about 76 milliseconds – faster than the <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4043155/#:~:text=one%20blink%20lasts%20about%201/3%20s"><u>blink of an eye</u></a>.</p><p>However, delays in loading web pages persist due to the complexities of processing requests, responses, and configurations. In addition to pushing advancements in <a href="https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/"><u>connection establishment</u></a>, <a href="https://blog.cloudflare.com/this-is-brotli-from-origin/"><u>compression</u></a>, <a href="https://blog.cloudflare.com/cloudflare-gen-12-server-bigger-better-cooler-in-a-2u1n-form-factor/"><u>hardware</u></a>, and <a href="https://blog.cloudflare.com/pingora-open-source/"><u>software</u></a>, we have built a new way to reduce page load latency by anticipating how visitors will interact with a given web page. </p><p>Today we are very excited to share the latest leap forward in speed: <b>Speed Brain</b>. It relies on the <a href="https://developer.chrome.com/docs/web-platform/prerender-pages"><u>Speculation Rules API </u></a>to <a href="https://developer.mozilla.org/en-US/docs/Glossary/Prefetch"><u>prefetch</u></a> the content of the user's likely next navigations. The main goal of Speed Brain is to download a web page to the browser cache before a user navigates to it, allowing pages to load almost instantly when the actual navigation takes place. </p><p>Our initial approach uses a <a href="https://developer.chrome.com/blog/speculation-rules-improvements#eagerness"><u>conservative</u></a> model that prefetches static content for the next page when a user starts a touch or <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event"><u>click event</u></a>. Through the fourth quarter of 2024 and into 2025, we will offer more aggressive speculation models, such as speculatively <a href="https://developer.mozilla.org/en-US/docs/Glossary/Prerender"><u>prerendering</u></a> (not just fetching the page before the navigation happens but rendering it completely) for an even faster experience. Eventually, Speed Brain will learn how to eliminate latency for your static website, without any configuration, and work with browsers to make sure that it loads as fast as possible.  </p><p>To illustrate, imagine an ecommerce website selling clothing. Using the insights from our global request logs, we can predict with high accuracy that a typical visitor is likely to click on ‘Shirts’ when viewing the parent page ‘Mens &gt; Clothes’. Based on this, we can start delivering static content, like images, before the shopper even clicks the ‘Shirts’ link. As a result, when they inevitably click, the page loads instantly. <b>Recent lab testing of our aggressive loading model implementation has shown up to a 75% reduction in </b><a href="https://developer.mozilla.org/en-US/docs/Glossary/Largest_contentful_paint"><b><u>Largest Contentful Paint (LCP)</u></b></a>, the time it takes for the largest visible element (like an image, video, or text block) to load and render in the browser.</p><p>The best part? We are making Speed Brain available to all plan types immediately and at no cost. Simply toggle on the Speed Brain feature for your website from the <a href="https://dash.cloudflare.com/?to=/:account/:zone/speed/optimization/content"><u>dashboard</u></a> or the <a href="https://developers.cloudflare.com/api/operations/zone-settings-get-speed-brain-setting"><u>API</u></a>. It’ll feel like magic, but behind the scenes it's a lot of clever engineering. </p><p>We have already enabled Speed Brain by default on <u>all</u> free domains and are seeing a <b>reduction in LCP of 45% on successful prefetches.</b> Pro, Business, and Enterprise domains need to enable Speed Brain manually. If you have not done so already, we <b>strongly</b> recommend also <a href="https://developers.cloudflare.com/web-analytics/get-started/#sites-proxied-through-cloudflare"><u>enabling Real User Measurements (RUM)</u></a> via your dashboard so you can see your new and improved web page performance. As a bonus, enabling RUM for your domain will help us provide <b>improved</b> and <b>customized</b> prefetching and prerendering rules for your website in the near future!</p>
    <div>
      <h2>How browsers work at a glance</h2>
      <a href="#how-browsers-work-at-a-glance">
        
      </a>
    </div>
    <p>Before discussing how Speed Brain can help load content exceptionally fast, we need to take a step back to review the complexity of loading content on browsers. Every time a user navigates to your web page, a series of request and response cycles must be completed. </p><p>After the browser <a href="https://www.debugbear.com/blog/http-server-connections"><u>establishes a secure connection</u></a> with a server, it sends an HTTP request to retrieve the base document of the web page. The server processes the request, constructs the necessary HTML document and sends it back to the browser in the response. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6hxlOWcShKyU4y6sqNYQs1/5717e4ebc130887376d629f9926d7a98/BLOG-2422_2.png" />
          </figure><p>When the browser receives an HTML document, it immediately begins <a href="https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work#parsing"><u>parsing</u></a> the content. During this process, it may encounter references to external resources such as CSS files, JavaScript, images, and fonts. These subresources are essential for rendering the page correctly, so the browser issues additional HTTP requests to fetch them. However, if these resources are available in the browser’s cache, the browser can retrieve them locally, significantly reducing <a href="https://www.cloudflare.com/learning/performance/glossary/what-is-latency/"><u>network latency</u></a> and improving page load times.</p><p>As the browser processes HTML, CSS, and JavaScript, the rendering engine begins to display content on the screen. Once the page’s visual elements are displayed, user interactions — like clicking a link — prompt the browser to restart much of this process to fetch new content for the next page. This workflow is typical of every browsing session: as users navigate, the browser continually fetches and renders new or uncached resources, introducing a delay before the new page fully loads.</p><p>Take the example of a user navigating the shopping site described above. As the shopper moves from the homepage to the ‘men's’ section of the site to the ‘clothing’ section to the ‘shirts’ section, the time spent on retrieving each of those subsequent pages can add up and contribute to the shopper leaving the site before they complete the transaction.  </p><p>Ideally, having prefetched and prerendered pages present in the browser at the time each of those links are clicked would eliminate much of the network latency impact, allowing the browser to load content instantly and providing a smoother user experience. </p>
    <div>
      <h2>Wait, I’ve heard this story before (how did we get to Speed Brain?)</h2>
      <a href="#wait-ive-heard-this-story-before-how-did-we-get-to-speed-brain">
        
      </a>
    </div>
    <p>We know what you’re thinking. We’ve had prefetching for years. There have even been several speculative prefetching efforts in the past. You’ve heard this all before. How is this different now?</p><p>You’re right, of course. Over the years, there has been a constant effort by developers and browser vendors to optimize page load times and enhance user experience across the web. Numerous techniques have been developed, spanning various layers of the Internet stack — from optimizing network layer connectivity to preloading application content closer to the client.</p>
    <div>
      <h4>Early prefetching: lack of data and flexibility</h4>
      <a href="#early-prefetching-lack-of-data-and-flexibility">
        
      </a>
    </div>
    <p>Web prefetching has been one such technique that has existed for more than a decade. It is based on the assumption that certain subresources are likely to be needed in the near future, so why not fetch them proactively? This could include anything from HTML pages to images, stylesheets, or scripts that the user might need as they navigate through a website. In fact, the core concept of speculative execution is not new, as it's a general technique that's been employed in various areas of computer science for years, with <a href="https://en.wikipedia.org/wiki/Branch_predictor"><u>branch prediction</u></a> in CPUs as a prime example.</p><p>In the early days of the web, several custom prefetching solutions emerged to enhance performance. For example, in 2005, Google introduced the <a href="https://google.fandom.com/wiki/Google_Web_Accelerator"><u>Google Web Accelerator</u></a>, a client-side application aimed at speeding up browsing for broadband users. Though innovative, the project was short-lived due to privacy and compatibility issues (we will describe how Speed Brain is different below). Predictive prefetching at that time lacked the data insights and API support for capturing user behavior, especially those handling sensitive actions like deletions or purchases.</p>
    <div>
      <h4>Static lists and manual effort</h4>
      <a href="#static-lists-and-manual-effort">
        
      </a>
    </div>
    <p>Traditionally, prefetching has been accomplished through the use of the <code>&lt;link rel="prefetch"&gt;</code> attribute as one of the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/prefetch"><u>Resource Hints</u></a>. Developers had to manually specify the attribute on each page for each resource they wanted the browser to preemptively fetch and cache in memory. This manual effort has not only been laborious but developers often lacked insight into what resources should be prefetched, which reduced the quality of their specified hints.</p><p>In a similar vein, <a href="https://developers.cloudflare.com/speed/optimization/content/prefetch-urls/"><u>Cloudflare has offered a URL prefetching feature since 2015</u></a>. Instead of prefetching in browser cache, Cloudflare allows customers to prefetch a static list of resources into the CDN cache. The feature allows prefetching resources in advance of when they are actually needed, usually during idle time or when network conditions are favorable. However, similar concerns apply for CDN prefetching, since customers have to manually decide on what resources are good candidates for prefetching for each page they own. If misconfigured, static link prefetching can be a <a href="https://en.wiktionary.org/wiki/footgun"><u>footgun</u></a>, causing the web page load time to actually slow down.</p>
    <div>
      <h4>Server Push and its struggles</h4>
      <a href="#server-push-and-its-struggles">
        
      </a>
    </div>
    <p><a href="https://datatracker.ietf.org/doc/html/rfc9113#name-server-push"><u>HTTP/2’s "server push"</u></a> was another attempt to improve web performance by pushing resources to the client before they were requested. In theory, this would reduce latency by eliminating the need for additional round trips for future assets. However, the server-centric dictatorial nature of "pushing" resources to the client raised significant challenges, primarily due to lack of context about what was already cached in the browser. This not only wasted bandwidth but had the potential to slow down the delivery of critical resources, like base HTML and CSS, due to race conditions on browser fetches when rendering the page. The <a href="https://datatracker.ietf.org/doc/html/draft-kazuho-h2-cache-digest-01"><u>proposed solution of cache digests</u></a>, which would have informed servers about client cache contents, never gained widespread implementation, leaving servers to push resources blindly. <a href="https://developer.chrome.com/blog/removing-push"><u>In October 2022, Google Chrome removed Server Push support</u></a>, and in September 2024, <a href="https://groups.google.com/a/mozilla.org/g/dev-platform/c/vU9hJg343U8/m/4cZsHz7TAQAJ"><u>Firefox followed suit</u></a>.</p>
    <div>
      <h4>A step forward with Early Hints</h4>
      <a href="#a-step-forward-with-early-hints">
        
      </a>
    </div>
    <p>As a successor, <a href="https://datatracker.ietf.org/doc/html/rfc8297"><u>Early Hints</u></a> was specified in 2017 but not widely adopted until 2022, when <a href="https://blog.cloudflare.com/early-hints"><u>we partnered with browsers and key customers to deploy it</u></a>. It offers a more efficient alternative by "hinting" to clients which resources to load, allowing better prioritization based on what the browser needs. Specifically, the server sends a 103 Early Hints HTTP status code with a list of key page assets that the browser should start loading while the main response is still being prepared. This gives the browser a head start in fetching essential resources and avoids redundant preloading if assets are already cached. Although Early Hints doesn't adapt to user behaviors or dynamic page conditions (yet), its use is primarily limited to preloading specific assets rather than full web pages — in particular, cases where there is a long server “think time” to produce HTML.</p><p>As the web evolves, tools that can handle complex, dynamic user interactions will become increasingly important to balance the performance gains of speculative execution with its potential drawbacks for end-users. For years Cloudflare has offered performance-based solutions that adapt to user behavior and work to balance the speed and correctness decisions across the Internet like <a href="https://www.cloudflare.com/application-services/products/argo-smart-routing/"><u>Argo Smart Routing</u></a>, <a href="https://blog.cloudflare.com/introducing-smarter-tiered-cache-topology-generation/"><u>Smart Tiered Cache</u></a>, and <a href="https://developers.cloudflare.com/workers/configuration/smart-placement/"><u>Smart Placement</u></a>. Today we take another step forward toward an adaptable framework for serving content lightning-fast. </p>
    <div>
      <h2>Enter Speed Brain: what makes it different?</h2>
      <a href="#enter-speed-brain-what-makes-it-different">
        
      </a>
    </div>
    <p>Speed Brain offers a robust approach for implementing predictive prefetching strategies directly within the browser based on the ruleset returned by our servers. By building on lessons from previous attempts, it shifts the responsibility for resource prediction to the client, enabling more dynamic and personalized optimizations based on user interaction – like hovering over a link, for example – and their device capabilities. Instead of the browser sitting idly waiting for the next web page to be requested by the user, it takes cues from how a user is interacting with a page and begins asking for the next web page before the user finishes clicking on a link.</p><p>Behind the scenes, all of this magic is made possible by the <a href="https://developer.chrome.com/docs/web-platform/prerender-pages#speculation-rules-api"><u>Speculation Rules API</u></a>, which is an emerging standard in the web performance space from Google. When Cloudflare’s Speed Brain feature is enabled, an HTTP header called Speculation-Rules is added to web page responses. The value for this header is a URL that hosts an opinionated Rules configuration. This configuration instructs the browser to initiate prefetch requests for future navigations. Speed Brain does not improve page load time for the first page that is visited on a website, but it can improve it for subsequent web pages that are visited on the same site.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Fu2ADDum0Pp9e5kq94Jd4/3eba0ffc4d94c42af67d4e9c1c708a29/BLOG-2422_3.png" />
          </figure><p>The idea seems simple enough, but <a href="https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API#unsafe_prefetching"><u>prefetching comes with challenges</u></a>, as some prefetched content may never end up being used. With the initial release of Speed Brain, we have designed a solution with guardrails that addresses two important but distinct issues that limited previous speculation efforts — <i>stale prefetch configuration</i> and <i>incorrect prefetching. </i>The Speculation Rules API configuration we have chosen for this initial release has been carefully designed to balance safety of prefetching while still maintaining broad applicability of rules for the entire site.</p>
    <div>
      <h4>Stale prefetch configuration</h4>
      <a href="#stale-prefetch-configuration">
        
      </a>
    </div>
    <p>As websites inevitably change over time, static prefetch configurations often become outdated, leading to <a href="https://www.cloudflare.com/learning/cdn/common-cdn-issues/">inefficient or ineffective prefetching</a>. This has been especially true for techniques like the rel=prefetch attribute or static CDN prefetching URL sets, which have required developers to manually maintain relevant prefetchable URL lists for each page of their website. Most static prefetch lists are based on developer intuition rather than real user navigation data, potentially missing important prefetch opportunities or wasting resources on unnecessary prefetches. </p>
    <div>
      <h4>Incorrect prefetching</h4>
      <a href="#incorrect-prefetching">
        
      </a>
    </div>
    <p>Since prefetch requests are just like normal requests except with a `sec-purpose` HTTP request header, they incur the same overhead on the client, network, and server. However, the crucial difference is that prefetch requests anticipate user behavior and the response might not end up being used, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API#unsafe_prefetching"><u>so all that overhead might be wasted</u></a>. This makes prefetch accuracy extremely important — that is, maximizing the percentage of prefetched pages that end up being viewed by the user. Incorrect prefetching can lead to inefficiencies and unneeded costs, such as caching resources that aren't requested, or wasting bandwidth and network resources, which is especially critical on metered mobile networks or in low-bandwidth environments.</p>
    <div>
      <h3>Guardrails</h3>
      <a href="#guardrails">
        
      </a>
    </div>
    <p>With the initial release of Speed Brain, we have designed a solution with important side effect prevention guardrails that completely removes the chance of <i>stale prefetch configuration</i>, and minimizes the risk of<i> incorrect prefetching</i>. This opinionated configuration is achieved by leveraging the <a href="https://developer.chrome.com/blog/speculation-rules-improvements"><u>document rules</u></a> and <a href="https://developer.chrome.com/blog/speculation-rules-improvements#eagerness"><u>eagerness</u></a> settings from the <a href="https://developer.chrome.com/docs/web-platform/prerender-pages#speculation-rules-api"><u>Speculation Rules API</u></a>. Our chosen configuration looks like the following:</p>
            <pre><code>{
  "prefetch": [{
    "source": "document",
    "where": {
      "and": [
        { "href_matches": "/*", "relative_to": "document" },
      ]
    },
    "eagerness": "conservative"
  }]
}
</code></pre>
            
    <div>
      <h5>
Document Rules</h5>
      <a href="#document-rules">
        
      </a>
    </div>
    <p><a href="https://developer.chrome.com/blog/speculation-rules-improvements"><u>Document Rules</u></a>, indicated by "source": "document" and the "where" key in the configuration, allows prefetching to be applied dynamically over the entire web page. This eliminates the need for a predefined static URL list for prefetching. Hence, we remove the problem of <i>stale prefetch configuration</i> as prefetch candidate links are determined based on the active page structure.</p><p>Our use of "relative_to": "document" in the where clause instructs the browser to limit prefetching to same-site links. This has the added bonus of allowing our implementation to avoid cross-origin prefetches to avoid any privacy implications for users, as it doesn’t follow them around the web. </p>
    <div>
      <h5>Eagerness</h5>
      <a href="#eagerness">
        
      </a>
    </div>
    <p><a href="https://developer.chrome.com/docs/web-platform/prerender-pages#eagerness"><u>Eagerness</u></a> controls how aggressively the browser prefetches content. There are four possible settings:</p><ul><li><p><b><i>immediate</i></b><i>: Used as soon as possible on page load — generally as soon as the rule value is seen by the browser, it starts prefetching the next page.</i></p></li><li><p><b><i>eager</i></b><i>: Identical to immediate setting above, but the prefetch trigger additionally relies on slight user interaction events, such as moving the cursor towards the link (coming soon).</i></p></li><li><p><b><i>moderate</i></b><i>: Prefetches if you hold the pointer over a link for more than 200 milliseconds (or on the </i><a href="https://developer.mozilla.org/docs/Web/API/Element/pointerdown_event"><i><u>pointerdown</u></i></a><i> event if that is sooner, and on mobile where there is no hover event).</i></p></li><li><p><b><i>conservative</i></b><i>: Prefetches on pointer or touch down on the link.</i></p></li></ul><p>Our initial release of Speed Brain makes use of the <b><u>conservative</u></b> eagerness value to minimize the risk of incorrect prefetching, which can lead to unintended resource waste while making your websites noticeably faster. While we lose out on the potential performance improvements that the more aggressive eagerness settings offer, we chose this cautious approach to prioritize safety for our users. Looking ahead, we plan to explore more dynamic eagerness settings for sites that could benefit from a more liberal setting, and we'll also expand our rules to include <a href="https://developer.mozilla.org/en-US/docs/Glossary/Prerender"><u>prerendering</u></a>.</p><p>Another important safeguard we implement is to only accept prefetch requests for static content that is already stored in our CDN cache. If the content isn't in the cache, we reject the prefetch request. Retrieving content directly from our CDN cache for prefetching requests lets us bypass concerns about their cache eligibility. The rationale for this is straightforward: if a page is not eligible for caching, we don't want it to be prefetched in the browser cache, as it could lead to unintended consequences and increased origin load. For instance, prefetching a logout page might log the user out prematurely before the user actually finishes their action. Stateful prefetching or prerendering requests can have unpredictable effects, potentially altering the server's state for actions the client has not confirmed. By only allowing prefetching for pages already in our CDN cache, we have confidence those pages will not negatively impact the user experience.</p><p>These guardrails were implemented to work in performance-sensitive environments. We measured the impact of our baseline conservative deployment model on all pages across <a href="https://developers.cloudflare.com/"><u>Cloudflare’s developer documentation</u></a> in early July 2024. We found that we were able to prefetch the correct content, content that would in fact be navigated to by the users, <b>94</b>% of the time. We did this while improving the performance of the navigation by reducing LCP at p75 quantile by <b>40</b>% without inducing any unintended side effects. The results were amazing!</p>
    <div>
      <h2>Explaining Cloudflare’s implementation </h2>
      <a href="#explaining-cloudflares-implementation">
        
      </a>
    </div>
    <p>Our global <a href="https://www.cloudflare.com/network"><u>network</u></a> spans over 330 cities and operates within 50 milliseconds of 95% of the Internet-connected population. This extensive reach allows us to significantly improve the performance of cacheable assets for our customers. By leveraging this network for smart prefetching with Speed Brain, Cloudflare can serve prefetched content directly from the CDN cache, reducing network latency to practically instant.</p><p>Our unique position on the network provides us the leverage to automatically enable Speed Brain without requiring any changes from our customers to their origin server configurations. It's as simple as flipping a switch! Our first version of Speed Brain is now live.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/O3RwzUlOj1GlJuMSrq5TW/55d9ef31a2de21034eb036b8c029d5b6/BLOG-2422_4.png" />
          </figure><ul><li><p>Upon receiving a request for a web page with Speed Brain enabled, the Cloudflare server returns an additional "Speculation-Rules" HTTP response header. The value for this header is a URL that hosts an opinionated Rules configuration (as mentioned above).</p></li><li><p>When the browser begins parsing the response header, it fetches our Speculation-Rules configuration, and loads it as part of the web page.</p></li><li><p>The configuration guides the browser on when to prefetch the next likely page from Cloudflare that the visitor may navigate to, based on how the visitor is engaging with the page.</p></li><li><p>When a user action (such as mouse down event on the next page link) triggers the Rules application, the browser sends a prefetch request for that page with the "sec-purpose: prefetch" HTTP request header.</p></li><li><p>Our server parses the request header to identify the prefetch request. If the requested content is present in our cache, we return it; otherwise,<b> we return a 503 HTTP status </b>code and deny the prefetch request. This removes the risk of unsafe side-effects of sending requests to origins or Cloudflare Workers that are unaware of prefetching. Only content present exclusively in the cache is returned.</p></li><li><p>On a success response, the browser successfully prefetches the content in memory, and when the visitor navigates to that page, the browser directly loads the web page from the browser cache for immediate rendering.</p></li></ul>
    <div>
      <h2>Common troubleshooting patterns </h2>
      <a href="#common-troubleshooting-patterns">
        
      </a>
    </div>
    <p>Support for Speed Brain relies on the <a href="https://developer.chrome.com/docs/web-platform/prerender-pages"><u>Speculation Rules API</u></a>, an emerging web standard. As of September 2024, <a href="https://caniuse.com/mdn-http_headers_speculation-rules"><u>support for this emerging standard</u></a> is limited to <b>Chromium-based browsers (version 121 or later)</b>, such as Google Chrome and Microsoft Edge. As the web community reaches consensus on API standardization, we hope to see wider adoption across other browser vendors.</p><p>Prefetching by nature does not apply to dynamic content, as the state of such content can change, potentially leading to stale or outdated data being delivered to the end user as well as increased origin load. Therefore, Speed Brain will only work for non-dynamic pages of your website that are cached on our network. It has no impact on the loading of dynamic pages. To get the most benefit out of Speed Brain, we suggest making use of <a href="https://developers.cloudflare.com/cache/how-to/cache-rules/"><u>cache rules</u></a> to ensure that all static content (<b>especially HTML content</b>) on your site is eligible for caching.</p><p>When the browser receives a 503 HTTP status code in response to a speculative prefetch request (marked by the sec-purpose: prefetch header), it cancels the prefetch attempt. Although a 503 error appearing in the browser's console may seem alarming, it is completely harmless for prefetch request cancellation. In our early tests, the 503 response code has caused some site owners concern. We are working with our partners to iterate on this to improve the client experience, but for now follow the specification guidance, <a href="https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API#:~:text=Using%20a%20non%2Dsuccess%20code%20(for%20example%20a%20503)%20is%20the%20easiest%20way%20to%20prevent%20speculative%20loading"><u>which suggests a 503 response</u></a> for the browser to safely discard the speculative request. We're in active discussions with Chrome, based on feedback from early beta testers, and believe a new non-error dedicated response code would be more appropriate, and cause less confusion. In the meantime, 503 response logs for prefetch requests related to Speed Brain are harmless. If your tooling makes ignoring these requests difficult, you can temporarily disable Speed Brain until we work out something better with the Chrome Team.</p><p>Additionally, when a website uses both its own custom Speculation Rules and Cloudflare's Speed Brain feature, both rule sets can operate simultaneously. Cloudflare’s guardrails will limit speculation rules to cacheable pages, which may be an unexpected limitation for those with existing implementations. If you observe such behavior, consider disabling one of the implementations for your site to ensure consistency in behavior. Note that if your origin server responses include the Speculation-Rules header, it will not be overridden. Therefore, the potential for ruleset conflicts primarily applies to predefined in-line speculation rules.</p>
    <div>
      <h2>How can I see the impact of Speed Brain?</h2>
      <a href="#how-can-i-see-the-impact-of-speed-brain">
        
      </a>
    </div>
    <p>In general, we suggest that you use Speed Brain and most other Cloudflare performance <a href="https://developers.cloudflare.com/speed/"><u>features</u></a> with our <a href="https://developers.cloudflare.com/web-analytics/get-started/#sites-proxied-through-cloudflare"><u>RUM performance measurement tool</u></a> enabled. Our RUM feature helps developers and website operators understand how their end users are experiencing the performance of their application, providing visibility into:</p><ul><li><p><b>Loading</b>: How long did it take for content to become available?</p></li><li><p><b>Interactivity</b>: How responsive is the website when users interact with it?</p></li><li><p><b>Visual stability</b>: How much does the page move around while loading?</p></li></ul><p>With RUM enabled, you can navigate to the Web Analytics section in the dashboard to see important information about how Speed Brain is helping reduce latency in your <a href="https://www.cloudflare.com/learning/performance/what-are-core-web-vitals/"><u>core web vitals</u></a> metrics like Largest Contentful Paint (LCP) and load time. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6zv2kRvsot12PSNwwaWCad/25e9e56d6f3769b04a8752f99c656f3b/BLOG-2422_5.png" />
          </figure><p><sub><i>Example RUM dashboard for a website with a high amount of prefetchable content that enabled Speed Brain around September 16.</i></sub></p>
    <div>
      <h2>What have we seen in our rollout so far? </h2>
      <a href="#what-have-we-seen-in-our-rollout-so-far">
        
      </a>
    </div>
    <p>We have enabled this feature by default on all free plans and have observed the following:</p>
    <div>
      <h3>Domains</h3>
      <a href="#domains">
        
      </a>
    </div>
    <p>Cloudflare currently has tens of millions of domains using Speed Brain. We have measured the LCP at the 75th quantile (p75) for these sites and found an improvement for these sites between 40% and 50% (average around 45%). </p><p>We found this improvement by comparing navigational prefetches to normal (non-prefetched) page loads for the same set of domains. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/fNrRh84I3iZpHiEieNPg8/a789d9d9a736a8eb76fa6120a84cdf10/BLOG-2422_6.png" />
          </figure>
    <div>
      <h3>Requests</h3>
      <a href="#requests">
        
      </a>
    </div>
    <p>Before Speed Brain is enabled, the p75 of free websites on Cloudflare experience an LCP around 2.2 seconds. With Speed Brain enabled, these sites see significant latency savings on LCP. In aggregate, Speed Brain saves about 0.88 seconds on the low end and up to 1.1 seconds on each successful prefetch! </p>
    <div>
      <h3>Applicable browsers</h3>
      <a href="#applicable-browsers">
        
      </a>
    </div>
    <p>Currently, the Speculation Rules API is only available in Chromium browsers. From Cloudflare Radar, we can see that approximately <a href="https://radar.cloudflare.com/adoption-and-usage"><u>70% of requests</u></a> from visitors are from <a href="https://en.wikipedia.org/wiki/Chromium_(web_browser)"><u>Chromium</u></a> (Chrome, Edge, etc) browsers.</p>
    <div>
      <h3>Across the network</h3>
      <a href="#across-the-network">
        
      </a>
    </div>
    <p>Cloudflare sees hundreds of billions of requests for HTML content each day. Of these requests, about half are cached (make sure your HTML is cacheable!). Around 1% of those requests are for navigational prefetching made by the visitors. This represents significant savings every day for visitors to websites with Speed Brain enabled. Every 24 hours, <b>Speed Brain can save more than 82 years worth of latency!</b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5CIpcdPC17LY2EGjNxCjNo/cf1a915d16384e32d88951a48febed47/BLOG-2422_7.png" />
          </figure>
    <div>
      <h2>What’s next? </h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>What we’re offering today for Speed Brain is only the beginning. Heading into 2025, we have a number of exciting additions to explore and ship. </p>
    <div>
      <h3>Leveraging Machine Learning</h3>
      <a href="#leveraging-machine-learning">
        
      </a>
    </div>
    <p>Our unique position on the Internet provides us valuable insights into web browsing patterns, which we can leverage for improving web performance while maintaining individual user privacy. By employing a generalized data-driven machine learning approach, we can define more accurate and site-specific prefetch predictors for users’ pages. </p><p>We are in the process of developing an adaptive speculative model that significantly improves upon our current conservative offering. This model uses a privacy-preserving method to generate a user traversal graph for each site based on same-site Referrer headers. For any two pages connected by a navigational hop, our model predicts the likelihood of a typical user moving between them, using insights extracted from our aggregated traffic data.</p><p>This model enables us to tailor rule sets with custom eagerness values to each relevant next page link on your site. For pages where the model predicts high confidence in user navigation, the system will aggressively prefetch or prerender them. If the model does not provide a rule for a page, it defaults to our existing conservative approach, maintaining the benefits of baseline Speed Brain model. These signals guide browsers in prefetching and prerendering the appropriate pages, which helps speed up navigation for users, while maintaining our current safety guardrails.</p><p>In lab tests, our ML model improved LCP latency by 75% and predicted visitor navigation with ~98% accuracy, ensuring the correct pages were being prefetched to prevent resource waste for users. As we move toward scaling this solution, we are focused on periodic training of the model to adapt to varying user behaviors and evolving websites. Using an online machine learning approach will drastically reduce the need for any manual update, and content drifts, while maintaining high accuracy — the Speed Brain load solution that gets smarter over time!</p>
    <div>
      <h3>Finer observability via RUM</h3>
      <a href="#finer-observability-via-rum">
        
      </a>
    </div>
    <p>As we’ve mentioned, we believe that our RUM tools offer the best insights for how Speed Brain is helping the performance of your website. In the future, we plan on offering the ability to filter RUM tooling by navigation type so that you can compare the browser rendering of prefetched content versus non-prefetched content. </p>
    <div>
      <h3>Prerendering</h3>
      <a href="#prerendering">
        
      </a>
    </div>
    <p>We are currently offering the ability for prefetching on cacheable content. Prefetching downloads the main document resource of the page before the user’s navigation, but it does not instruct the browser to prerender the page or download any additional subresources.</p><p>In the future, Cloudflare’s Speed Brain offering will prefetch content into our CDN cache and then work with browsers to know what are the best prospects for prerendering. This will help get static content even closer to instant rendering. </p>
    <div>
      <h3>Argo Smart Browsing: Speed Brain &amp; Smart Routing</h3>
      <a href="#argo-smart-browsing-speed-brain-smart-routing">
        
      </a>
    </div>
    <p>Speed Brain, in its initial implementation, provides an incredible performance boost whilst still remaining conservative in its implementation; both from an eagerness, and a resource consumption perspective.</p><p>As was outlined earlier in the post, lab testing of a more aggressive model, powered by machine-learning and a higher eagerness, yielded a <b>75% reduction in LCP.</b> We are investigating bundling this more aggressive, additional implementation of Speed Brain with Argo Smart Routing into a product called <b>“Argo Smart Browsing”. </b></p><p>Cloudflare customers will be free to continue using Speed Brain, however those who want even more performance improvement will be able to enable Argo Smart Browsing with a single button click.  With Argo Smart Browsing, not only will cacheable static content load up to 75% faster in the browser, thanks to the more aggressive models, however in times when content can’t be cached, and the request must go forward to an origin server, it will be sent over the most performant network path resulting in an average <b>33% performance increase.</b> Performance optimizations are being applied to almost every segment of the request lifecycle regardless if the content is static or dynamic, cached or not. </p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>To get started with Speed Brain, navigate to <a href="https://dash.cloudflare.com/?to=/:account/:zone/speed/optimization/content"><b><u>Speed</u></b><u> &gt; Optimization &gt; Content Optimization &gt; </u><b><u>Speed Brain</u></b></a> in the Cloudflare Dashboard and enable it. That's all! The feature can also be enabled via <a href="https://developers.cloudflare.com/api/operations/zone-settings-get-speed-brain-setting"><u>API</u></a>.  Free plan domains have had Speed Brain enabled by default.</p><p>We strongly recommend that customers also <a href="https://developers.cloudflare.com/web-analytics/get-started/#sites-proxied-through-cloudflare"><b><u>enable RUM</u></b></a>, found in the same section of the dashboard, to give visibility into the performance improvements provided by Speed Brain and other Cloudflare features and products. </p><p>We’re excited to continue to build products and features that make web performance reliably fast. If you’re an engineer interested in improving the performance of the web for all, <a href="http://cloudflare.com/jobs">come join us</a>!</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/OaN8mrrAKAatOUCqGAsqu/15ac363626180a0f0ed1a0cdb8146e5f/BLOG-2422_8.png" />
          </figure>
    <div>
      <h3>Watch on Cloudflare TV</h3>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div>
  
</div><p></p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cache]]></category>
            <category><![CDATA[Speed Brain]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">sC3G9YR2M9IIoRMg8slDl</guid>
            <dc:creator>Alex Krivit</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>William Woodhead</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing Automatic SSL/TLS: securing and simplifying origin connectivity]]></title>
            <link>https://blog.cloudflare.com/introducing-automatic-ssl-tls-securing-and-simplifying-origin-connectivity/</link>
            <pubDate>Thu, 08 Aug 2024 14:05:00 GMT</pubDate>
            <description><![CDATA[ This new Automatic SSL/TLS setting will maximize and simplify the encryption modes Cloudflare uses to communicate with origin servers by using the SSL/TLS Recommender. ]]></description>
            <content:encoded><![CDATA[ 
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4YIQCIdM9Td1RJfdCkg3o5/6fc5cd824f819658e00007c61f69ce71/1885-1-Hero.png" />
          </figure><p>During Birthday Week 2022, we <a href="https://blog.cloudflare.com/securing-origin-connectivity"><u>pledged</u></a> to provide our customers with the most secure connection possible from Cloudflare to their origin servers automatically. I’m thrilled to announce we will begin rolling this experience out to customers who have the <a href="https://blog.cloudflare.com/ssl-tls-recommender"><u>SSL/TLS Recommender</u></a> enabled on <b>August 8, 2024. </b>Following this, remaining Free and Pro customers can use this feature beginning <b>September 16, 2024</b> with Business and Enterprise customers to follow<b>.</b></p><p>Although it took longer than anticipated to roll out, our priority was to achieve an automatic configuration both transparently and without risking any site downtime. Taking this additional time allowed us to balance enhanced security with seamless site functionality, especially since origin server security configuration and capabilities are beyond Cloudflare's direct control. The new Automatic SSL/TLS setting will maximize and simplify the <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>encryption modes</u></a> Cloudflare uses to communicate with origin servers by using the <a href="https://blog.cloudflare.com/ssl-tls-recommender"><u>SSL/TLS Recommender</u></a>. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/53WNT2fwr0HuN2L0M5PKnJ/c005f100b455fd699d32d2f602ebf447/1885-2.png" />
          </figure><p>We first talked about this process in <a href="https://blog.cloudflare.com/introducing-universal-ssl"><u>2014</u></a>: at that time, securing connections was hard to configure, prohibitively expensive, and required specialized knowledge to set up correctly. To help alleviate these pains, Cloudflare introduced Universal SSL, which allowed web properties to obtain a <a href="https://www.cloudflare.com/application-services/products/ssl/"><u>free SSL/TLS certificate</u></a> to enhance the security of connections between browsers and Cloudflare. </p><p>This worked well and was easy because Cloudflare could manage the certificates and connection security from incoming browsers. As a result of that work, the number of encrypted HTTPS connections on the entire Internet <a href="https://blog.cloudflare.com/introducing-universal-ssl#:~:text=we%27ll%20have%20doubled%20that"><u>doubled</u></a> at that time. However, the connections made from Cloudflare to origin servers still required <i>manual</i> configuration of the encryption <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>modes</u></a> to let Cloudflare know the capabilities of the origin. </p><p>Today we’re excited to begin the sequel to Universal SSL and make security between Cloudflare and origins automatic and easy for everyone.</p>
    <div>
      <h2>History of securing origin-facing connections</h2>
      <a href="#history-of-securing-origin-facing-connections">
        
      </a>
    </div>
    <p>Ensuring that more bytes flowing across the Internet are automatically encrypted strengthens the barrier against interception, throttling, and censorship of Internet traffic by third parties. </p><p>Generally, two communicating parties (often a client and server) establish a secure connection using the <a href="https://www.cloudflare.com/learning/ssl/what-happens-in-a-tls-handshake/"><u>TLS</u></a> protocol. For a simplified breakdown: </p><ul><li><p>The client advertises the list of encryption parameters it supports (along with some metadata) to the server.</p></li><li><p>The server responds back with its own preference of the chosen encryption parameters. It also sends a digital certificate so that the client can authenticate its identity.</p></li><li><p>The client validates the server identity, confirming that the server is who it says it is.</p></li><li><p>Both sides agree on a <a href="https://www.cloudflare.com/learning/ssl/what-is-asymmetric-encryption/#:~:text=What%20is-,symmetric,-encryption%3F"><u>symmetric</u></a> secret key for the session that is used to encrypt and decrypt all transmitted content over the connection.</p></li></ul><p>Because Cloudflare acts as an intermediary between the client and our customer’s origin server, two separate TLS connections are established. One between the user’s browser and our network, and the other from our network to the origin server. This allows us to manage and optimize the security and performance of both connections independently.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6s0NxfVR5tCXuAzhI8pYdw/f1f48be437de48bf1b60495647016fbb/1885-3.png" />
          </figure><p>Unlike securing connections between clients and Cloudflare, the security capabilities of origin servers are not under our direct control. For example, we can manage the <a href="https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/"><u>certificate</u></a> (the file used to verify identity and provide context on establishing encrypted connections) between clients and Cloudflare because it’s our job in that connection to provide it to clients, but when talking to origin servers, Cloudflare <i>is</i> the client.</p><p>Customers need to <a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/"><u>acquire and provision</u></a> an origin certificate on their host. They then have to configure Cloudflare to expect the new certificate from the origin when opening a connection. Needing to manually configure connection security across multiple different places requires effort and is prone to human error. </p><p>This issue was discussed in the original <a href="https://blog.cloudflare.com/introducing-universal-ssl"><u>Universal SSL blog</u></a>:</p><blockquote><p><i>For a site that did not have SSL before, we will default to our </i><a href="https://support.cloudflare.com/hc/en-us/articles/200170416-What-do-the-SSL-options-Off-Flexible-SSL-Full-SSL-Full-SSL-Strict-mean-"><i><u>Flexible SSL mode</u></i></a><i>, which means traffic from browsers to Cloudflare will be encrypted, but traffic from Cloudflare to a site's origin server will not. We strongly recommend site owners install a certificate on their web servers so we can encrypt traffic to the origin … Once you've installed a certificate on your web server, you can enable the </i><a href="https://support.cloudflare.com/hc/en-us/articles/200170416-What-do-the-SSL-options-Off-Flexible-SSL-Full-SSL-Full-SSL-Strict-mean-"><i><u>Full or Strict SSL modes</u></i></a><i> which encrypt origin traffic and provide a higher level of security.</i></p></blockquote><p>Over the years Cloudflare has introduced numerous products to help customers configure how Cloudflare should talk to their origin. These products include a <a href="https://blog.cloudflare.com/universal-ssl-encryption-all-the-way-to-the-origin-for-free/"><u>certificate authority</u></a> to help customers obtain a certificate to verify their origin server’s identity and encryption capabilities, <a href="https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull/"><u>Authenticated Origin Pulls</u></a> that ensures only HTTPS (encrypted) requests from Cloudflare will receive a response from the origin server, and <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/"><u>Cloudflare Tunnels</u></a> that can be configured to proactively establish secure and private tunnels to the nearest Cloudflare data center. Additionally, the <a href="https://datatracker.ietf.org/doc/html/rfc8555/"><u>ACME</u></a> protocol and its corresponding <a href="https://certbot.eff.org/"><u>Certbot</u></a> tooling make it easier than ever to obtain and manage publicly-trusted certificates on customer origins. While these technologies help customers configure how Cloudflare should communicate with their origin server, they still require manual configuration changes on the origin and to Cloudflare settings. </p><p>Ensuring certificates are configured appropriately on origin servers and informing Cloudflare about how we should communicate with origins can be anxiety-inducing because misconfiguration can lead to downtime if something isn’t deployed or configured correctly. </p><p>To simplify this process and help identify the most secure options that customers could be using without any misconfiguration risk, <b>Cloudflare introduced the </b><a href="https://blog.cloudflare.com/ssl-tls-recommender"><b><u>SSL/TLS Recommender</u></b></a><b> in 2021.</b> The Recommender works by probing customer origins with different SSL/TLS settings to provide a recommendation whether the SSL/TLS <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>encryption mode</u></a> for the web property can be improved. The Recommender has been in production for three years and has consistently managed to provide high quality origin-security recommendations for Cloudflare’s customers. </p><p>The SSL/TLS Recommender system serves as the brain of the automatic origin connection service that we are announcing today. </p>
    <div>
      <h2>How does SSL/TLS Recommendation work?</h2>
      <a href="#how-does-ssl-tls-recommendation-work">
        
      </a>
    </div>
    <p>The Recommender works by actively comparing content on web pages that have been downloaded using different SSL/TLS modes to see if it is safe and risk-free to update the <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>mode</u></a> Cloudflare uses to connect to origin servers.</p><p>Cloudflare currently offers five SSL/TLS modes:</p><ol><li><p><b>Off</b>: No encryption is used for traffic between browsers and Cloudflare or between Cloudflare and origins. Everything is cleartext HTTP.</p></li><li><p><b>Flexible</b>: Traffic from browsers to Cloudflare can be encrypted via HTTPS, but traffic from Cloudflare to the origin server is not. This mode is common for origins that do not support TLS, though upgrading the origin configuration is recommended whenever possible. A guide for upgrading is available <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full/#required-setup"><u>here</u></a>.</p></li><li><p><b>Full</b>: Cloudflare matches the browser request protocol when connecting to the origin. If the browser uses HTTP, Cloudflare connects to the origin via HTTP; if HTTPS, Cloudflare uses HTTPS without validating the origin’s certificate. This mode is common for origins that use self-signed or otherwise invalid certificates.</p></li><li><p><b>Full (Strict)</b>: Similar to Full Mode, but with added validation of the origin server’s certificate, which can be issued by a public CA like Let’s Encrypt or by Cloudflare Origin CA.</p></li><li><p><b>Strict (SSL-only origin pull)</b>: Regardless of whether the browser-to-Cloudflare connection uses HTTP or HTTPS, Cloudflare always connects to the origin over HTTPS with certificate validation.</p></li></ol><table><tr><th><p>
</p></th><th><p><b>HTTP from visitor</b></p></th><th><p><b>HTTPS from visitor</b></p></th></tr><tr><td><p><b>Off</b></p></td><td><p>HTTP to origin</p></td><td><p>HTTP to origin</p></td></tr><tr><td><p><b>Flexible</b></p></td><td><p>HTTP to origin</p></td><td><p>HTTP to origin</p></td></tr><tr><td><p><b>Full</b></p></td><td><p>HTTP to origin</p></td><td><p>HTTPS without cert validation to origin</p></td></tr><tr><td><p><b>Full (strict)</b></p></td><td><p>HTTP to origin</p></td><td><p>HTTPS with cert validation to origin</p></td></tr><tr><td><p><b>Strict (SSL-only origin pull)</b></p></td><td><p>HTTPS with cert validation to origin</p></td><td><p>HTTPS with cert validation to origin</p></td></tr></table><p>
The SSL/TLS Recommender works by crawling customer sites and collecting links on the page (like any web crawler). The Recommender downloads content over both HTTP and HTTPS, making GET requests to avoid modifying server resources. It then uses a content similarity algorithm, adapted from the research paper "<a href="https://www.cs.umd.edu/~dml/papers/https_tma20.pdf"><u>A Deeper Look at Web Content Availability and Consistency over HTTP/S"</u></a> (TMA Conference 2020), to determine if content matches. If the content does match, the Recommender makes a determination for whether the <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/"><u>SSL/TLS mode</u></a> can be increased without misconfiguration risk. </p><p>The recommendations are currently delivered to customers via email. </p><p>When the Recommender is making security recommendations, it errs on the side of maintaining current site functionality to avoid breakage and usability issues. If a website is non-functional, blocks all bots, or has SSL/TLS-specific Page Rules or Configuration Rules, the Recommender may not complete its scans and provide a recommendation. It was designed to maximize <a href="https://www.cloudflare.com/application-services/solutions/domain-protection-services/">domain security</a>, but will not help resolve website or domain functionality issues.</p><p>The crawler uses the user agent "<code>Cloudflare-SSLDetector</code>" and is included in Cloudflare’s list of known <a href="https://bots-directory.cfdata.org/bot/cloudflare-ssl-detector"><u>good bots</u></a>. It ignores <code>robots.txt</code> (except for rules specifically targeting its user agent) to ensure accurate recommendations.</p><p>When downloading content from your origin server over both HTTP and HTTPS and comparing the content, the Recommender understands the current SSL/TLS encryption mode that your website uses and what risk there might be to the site functionality if the recommendation is followed.</p>
    <div>
      <h2>Using SSL/TLS Recommender to automatically manage SSL/TLS settings </h2>
      <a href="#using-ssl-tls-recommender-to-automatically-manage-ssl-tls-settings">
        
      </a>
    </div>
    <p>Previously, signing up for the SSL/TLS Recommender provided a good experience for customers, but only resulted in an email recommendation in the event that a zone’s current SSL/TLS modes could be updated. To Cloudflare, this was a positive signal that customers wanted their websites to have more secure connections to their origin servers – over 2 million domains have enabled the SSL/TLS Recommender. However, we found that a significant number of users would not complete the next step of pushing the button to inform Cloudflare that we could communicate over the upgraded settings. <b>Only 30% of the recommendations that the system provided were followed. </b></p><p>With the system designed to increase security while avoiding any breaking changes, we wanted to provide an option for customers to allow the Recommender to help upgrade their site security, without requiring further manual action from the customer. <b>Therefore, we are introducing a new option for managing SSL/TLS configuration on Cloudflare: Automatic SSL/TLS. </b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/21q0D6rvhXHQxRe2ko4ITA/d5ca2f9a7139a2f55a16ca8bcf783ee0/1885-4.png" />
          </figure><p></p><p>Automatic SSL/TLS uses the SSL/TLS Recommender to make the determination as to what encryption mode is the most secure and safest for a website to be set to. If there is a <b>more secure</b> option for your website (based on your origin certification or capabilities), Automatic SSL/TLS will find it and apply it for your domain. The other option, <b>Custom SSL/TLS,</b> will work exactly like the setting the encryption mode does today. If you know what setting you want, just select it using Custom SSL/TLS, and we’ll use it. </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/jFTSsmxG2WH0FqTklAJwb/eff9f692cdec3d199d32996bb0111441/1885-5.png" />
          </figure><p></p><p>Automatic SSL/TLS is currently meant to service an entire website, which typically works well for those with a single origin. For those concerned that they have more complex setups which use multiple origin servers with different security capabilities, don’t worry. Automatic SSL/TLS will still avoid breaking site functionality by looking for the best setting that works for all origins serving a part of the site’s traffic. </p><p>If customers want to segment the SSL/TLS mode used to communicate with the numerous origins that service their domain, they can achieve this by using <a href="https://developers.cloudflare.com/rules/configuration-rules/"><u>Configuration Rules</u></a>. These rules allow you to set more precise modes that Cloudflare should respect (based on path or subdomain or even IP address) to maximize the security of the domain based on your desired Rules criteria. If your site uses SSL/TLS-specific settings in a Configuration Rule or Page rule, those settings will <b>override the zone-wide Automatic and Custom settings.</b></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6PCXOjFBtEucRUOP3BoMGQ/6ba2700c18cf4c49782bdf2d0ee33435/1885-6.png" />
          </figure><p></p><p>The goal of Automatic SSL/TLS<b> </b>is to simplify and maximize the origin-facing security for customers on Cloudflare. We want this to be the new default for all websites on Cloudflare, but we understand that not everyone wants this new default, and we will respect your decision for how Cloudflare should communicate with your origin server. If you block the Recommender from completing its crawls, the origin server is non-functional or can’t be crawled, or if you want to opt out of this default and just continue using the same encryption mode you are using today, we will make it easy for you to tell us what you prefer. </p>
    <div>
      <h2>How to onboard to Automatic SSL/TLS</h2>
      <a href="#how-to-onboard-to-automatic-ssl-tls">
        
      </a>
    </div>
    <p>To improve the security settings for everyone by default, we are making the following default changes to how Cloudflare configures the SSL/TLS level for all zones: </p><p>Starting on <b>August 8, 2024</b> websites with the <b>SSL/TLS Recommender currently enabled</b> will have the Automatic SSL/TLS setting enabled by default. Enabling does not mean that the Recommender will begin scanning and applying new settings immediately though. There will be a <b><u>one-month grace period</u></b> before the first scans begin and the recommended settings are applied. Enterprise (ENT) customers will get a <b><u>six-week grace period</u></b>. Origin scans will start getting scheduled by <b>September 9, 2024, for non-Enterprise </b>customers<b> </b>and<b> September 23rd for ENT customers with the SSL Recommender enabled</b>. This will give customers the ability to opt out by removing Automatic SSL/TLS and selecting the Custom mode that they want to use instead.</p><p>Further, during the second week of September <b>all new zones signing up for Cloudflare</b> will start seeing the Automatic SSL/TLS setting enabled by default.</p><p>Beginning <b>September 16, 2024, </b>remaining <b>Free and Pro</b> customers will start to see the new Automatic SSL/TLS setting. They will also have a one-month grace period to opt out before the scans start taking effect. </p><p>Customers in the cohort having the new Automatic SSL/TLS setting applied will receive an email communication regarding the date that they are slated for this migration as well as a banner on the dashboard that mentions this transition as well. If they do not wish for Cloudflare to change anything in their configurations, the process for opt-out of this migration is outlined below. </p><p>Following the successful migration of Free and Pro customers, we will proceed to Business and Enterprise customers with a similar cadence. These customers will get email notifications and information in the dashboard when they are in the migration cohort.</p><p>The Automatic SSL/TLS setting will not impact users that are already in Strict or Full (strict) mode nor will it impact websites that have opted-out. </p>
    <div>
      <h2>Opting out</h2>
      <a href="#opting-out">
        
      </a>
    </div>
    <p>There are a number of reasons why someone might want to configure a lower-than-optimal security setting for their website. Some may want to set a lower security setting for testing purposes or to debug some behavior. Whatever the reason, the options to opt-out of the Automatic SSL/TLS setting during the migration process are available in the dashboard and API.</p><p>To opt-out, simply select <b>Custom SSL/TLS</b> in the dashboard (instead of the enabled Automatic SSL/TLS) and we will continue to use the previously set encryption mode that you were using prior to the migration. Automatic and Custom SSL/TLS modes can be found in the <b>Overview</b> tab of the SSL/TLS section of the dashboard. To enable your preferred mode, select <b>configure</b>.  </p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4meNmREGaXd1FJfxUKr5NN/bdbe1e07a2121d2f9ec2a11e64c77b7f/1885-7.png" />
          </figure><p></p><p>If you want to opt-out via the API you can make this API call on or before the grace period expiration date. </p>
            <pre><code>    curl --request PATCH \
        --url https://api.cloudflare.com/client/v4/zones/&lt;insert_zone_tag_here&gt;/settings/ssl_automatic_mode \
        --header 'Authorization: Bearer &lt;insert_api_token_here&gt;' \
        --header 'Content-Type: application/json' \
        --data '{"value":"custom"}'
</code></pre>
            <p></p><p>If an opt-out is triggered, there will not be a change to the currently configured SSL/TLS setting. You are also able to change the security level at any time by going to the SSL/TLS section of the dashboard and choosing the Custom setting you want (similar to how this is accomplished today). </p><p>If at a later point you’d like to opt-in to Automatic SSL/TLS, that option is available by changing your setting from Custom to Automatic.</p>
    <div>
      <h2>What if I want to be more secure now?</h2>
      <a href="#what-if-i-want-to-be-more-secure-now">
        
      </a>
    </div>
    <p>We will begin to roll out this change to customers with the SSL/TLS Recommender enabled on <b>August 8, 2024</b>. If you want to enroll in that group, we recommend enabling the Recommender as soon as possible. </p><p>If you read this and want to make sure you’re at the highest level of backend security already, we recommend <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict/"><u>Full (strict)</u></a> or <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/ssl-only-origin-pull/"><u>Strict mode</u></a>. Directions on how to make sure you’re correctly configured in either of those settings are available <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict/#required-setup"><u>here</u></a> and <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/ssl-only-origin-pull/#required-setup"><u>here</u></a>. </p><p>If you prefer to wait for us to automatically upgrade your connection to the maximum encryption mode your origin supports, please watch your inbox for the date we will begin rolling out this change for you.</p> ]]></content:encoded>
            <category><![CDATA[SSL]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Network Services]]></category>
            <category><![CDATA[Encryption]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">2lhAhlWMei6M2NkhzAuULC</guid>
            <dc:creator>Alex Krivit</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>J Evans</dc:creator>
            <dc:creator>Yawar Jamal</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare now uses post-quantum cryptography to talk to your origin server]]></title>
            <link>https://blog.cloudflare.com/post-quantum-to-origins/</link>
            <pubDate>Fri, 29 Sep 2023 13:00:45 GMT</pubDate>
            <description><![CDATA[ Starting today, you can secure the connection between Cloudflare and your origin server with post-quantum cryptography ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Quantum computers pose a <a href="/the-quantum-menace/">serious threat</a> to security and privacy of the Internet: encrypted communication intercepted today can be decrypted <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later">in the future</a> by a sufficiently advanced quantum computer. To counter this <a href="https://en.wikipedia.org/wiki/Harvest_now,_decrypt_later">store-now/decrypt-later</a> threat, cryptographers have been hard at work over the last decades proposing and vetting <a href="https://www.cloudflare.com/learning/ssl/quantum/what-is-post-quantum-cryptography/">post-quantum cryptography (PQC)</a>, cryptography that’s designed to withstand attacks of quantum computers. After a six-year public competition, in July 2022, the US National Institute of Standards and Technology (NIST), known for standardizing AES and SHA, announced <a href="https://pq-crystals.org/kyber/index.shtml">Kyber</a> as <a href="/nist-post-quantum-surprise/">their pick</a> for post-quantum key agreement. Now the baton has been handed to Industry to deploy post-quantum key agreement to protect today’s communications from the threat of future decryption by a quantum computer.</p><p>Cloudflare operates as a reverse proxy between clients (“visitors”) and customers’ web servers (“origins”), so that we can protect origin sites from attacks and improve site performance. In this post we explain how we secure the connection from Cloudflare to <i>origin servers</i>. To put that in context, let’s have a look at the connection involved when visiting an uncached page on a website served through Cloudflare.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2WZQZByAjMmuu53BzxjNik/170ebefe3aec6f8277f4c2e4e34b76f1/Connections-involved-when-user-visits-an-uncached-page-on-a-website-served-through-Cloudflare.png" />
            
            </figure><p>The first connection is from the visitor’s browser to Cloudflare. In October 2022, <a href="/post-quantum-for-all/">we enabled <i>X25519+Kyber</i> as a beta for all websites and APIs</a> served through Cloudflare. However, it takes two to tango: the connection is only secured if the browser also supports post-quantum cryptography. As of August 2023, <a href="https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html">Chrome</a> is slowly enabling <i>X25519+Kyber</i> by default.</p><p>The visitor’s request is routed through Cloudflare’s network (2). We have <a href="/post-quantum-cryptography-ga">upgraded</a> many of these internal connections to use post-quantum cryptography, and expect to be done upgrading all of our internal connections by the end of 2024. That leaves as the final link the connection (3) between us and the <i>origin server</i>.</p><p>We are happy to announce that <b>we are rolling out support for X25519+Kyber for most outbound connections</b>, including <i>origin servers</i> and <a href="https://workers.cloudflare.com/">Cloudflare Workers</a> <code>fetch()</code> calls.</p>
<table>
<thead>
  <tr>
    <th><span>Plan</span></th>
    <th><span>Support for post-quantum outbound connections</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>Free</span></td>
    <td><span>Started roll-out. Aiming for 100% by the end of the October.</span></td>
  </tr>
  <tr>
    <td><span>Pro and Business</span></td>
    <td><span>Started roll-out. Aiming for 100% by the end of year.</span></td>
  </tr>
  <tr>
    <td><span>Enterprise</span></td>
    <td><span>Start roll-out February 2024. 100% by March 2024.</span></td>
  </tr>
</tbody>
</table><p>You can skip the roll-out and opt-in your zone today, or opt-out ahead of time, using an API described below. Before rolling out this support for enterprise customers in February 2024, we will add a toggle on the dashboard to opt out.</p><p>In this post we will dive into the nitty-gritty of what we enabled; how we have to be a bit subtle to prevent breaking connections to origins that are not ready yet, and how you can add support to your (origin) server.</p><p>But before we dive in, for the impatient:</p>
    <div>
      <h3>Quick start</h3>
      <a href="#quick-start">
        
      </a>
    </div>
    <p>To enable a post-quantum connection between Cloudflare and your origin server today, opt-in your zone to skip the gradual roll-out:</p>
            <pre><code>curl --request PUT \
  --url https://api.cloudflare.com/client/v4/zones/(zone_id)/cache/origin_post_quantum_encryption \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer (API token)' \
  --data '{"value": "preferred"}'</code></pre>
            <p>Replace <a href="https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/"><code>(zone_id)</code></a> and <a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/"><code>(API token)</code></a> appropriately. Then, make sure your server supports TLS 1.3; enable and prefer the key agreement <code>X25519Kyber768Draft00;</code> and ensure it’s configured with <i>server cipher preference</i>. For example, to configure <a href="https://www.nginx.com/">nginx</a> (compiled with a recent <a href="https://boringssl.googlesource.com/boringssl">BoringSSL</a>) like this, use</p>
            <pre><code>	http {
		# [...]
		ssl_ecdh_curve X25519Kyber768Draft00:X25519;
		ssl_prefer_server_ciphers on;
		ssl_protocols TLSv1.3;
	}</code></pre>
            <p>To check your server is properly configured, you can use the <code>bssl</code> tool of <a href="https://github.com/google/boringssl">BoringSSL</a>:</p>
            <pre><code>	$ bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]</code></pre>
            <p>We’re looking for <code>X25519Kyber768Draft00</code> for a post-quantum connection as shown above instead of merely <code>X25519</code>.For more client and server support, check out <a href="https://pq.cloudflareresearch.com/">pq.cloudflareresearch.com</a>. Now, let’s dive in.</p>
    <div>
      <h2>Overview of a TLS 1.3 handshake</h2>
      <a href="#overview-of-a-tls-1-3-handshake">
        
      </a>
    </div>
    <p>To understand how a smooth upgrade is possible, and where it might go wrong, we need to understand a few basics of the TLS 1.3 protocol, which is used to protect traffic on the Internet. A TLS connection starts with a <b>handshake</b> which is used to authenticate the server and derive a shared key. The browser (client) starts by sending a <i>ClientHello</i> message that contains among other things, the hostname (SNI) and the list of key agreement methods it supports.</p><p>To remove a round trip, the client is allowed to make a guess of what the server supports and start the key agreement by sending one or more <i>client keyshares</i>. That guess might be correct (on the left in the diagram below) or the client has to retry (on the right). By the way, this guessing of keyshares is a <a href="/rfc-8446-aka-tls-1-3/">new feature of TLS 1.3</a>, and it is the main reason why it’s faster than TLS 1.2.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/QbpgdMdMdt9aW2nmrBSnT/97fee7c97d8c726e29fbf7b72666bfb6/image2-30.png" />
            
            </figure><p><i>Protocol flow for server-authenticated TLS 1.3 with a supported client keyshare on the left and a</i> HelloRetryRequest <i>on the right.</i></p><p>In both cases the client sends a <i>client keyshare</i> to the server. From this client keyshare the server generates the <i>shared key</i>. The server then returns a <i>server keyshare</i> with which the client can also compute the shared key. This shared key is used to protect the rest of the connection using symmetric cryptography, such as AES.</p><p>Today <a href="https://cr.yp.to/ecdh.html">X25519</a> is used as the key agreement in the vast majority of connections. To secure the connection against store-now/decrypt-later in the post-quantum world, a client can simply send a <a href="https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/">X25519+Kyber</a> keyshare.</p>
    <div>
      <h3>Hello! Retry Request? (HRR)</h3>
      <a href="#hello-retry-request-hrr">
        
      </a>
    </div>
    <p>What we just described is the happy flow, where the client guessed correctly which key agreement the server supports. If the server does not support the keyshare that the client sent, then the server picks one of the supported key agreements that the client advertised, and asks for it in a <i>HelloRetryRequest</i> message.</p><p>This is not the only case where a server can use a HelloRetryRequest: even if the client sent keyshares that the server supports, the server is allowed to prefer a different key agreement the client advertised, and ask for it with a HelloRetryRequest. This will turn out to be very useful.</p><p>_HelloRetryRequest_s are mostly undesirable: they add an extra round trip, and bring us back to the performance of TLS 1.2. We already had a transition of key agreement methods: back in the day P-256 was the de facto standard. When browsers couldn’t assume support for the newer X25519, some would send two keyshares, both X25519 and P-256 to prevent a <i>HelloRetryRequest</i>.</p><p>Also today, when enabling <a href="https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html">Kyber in Chrome</a>, Chrome will send two keyshares: X25519 and X25519+Kyber to prevent a <i>HelloRetryRequest</i>. Sending two keyshares is not ideal: it requires the client to compute more, and it takes more space on the wire. This becomes more problematic when we want to send two post-quantum keyshares, as post-quantum keyshares are much larger. Talking about post-quantum keyshares, let’s have a look at X25519+Kyber.</p>
    <div>
      <h2>The nitty-gritty of X25519+Kyber</h2>
      <a href="#the-nitty-gritty-of-x25519-kyber">
        
      </a>
    </div>
    <p>The full name of the post-quantum key agreement we have enabled is <a href="https://datatracker.ietf.org/doc/draft-tls-westerbaan-xyber768d00/">X25519Kyber768Draft00</a>, which has become the industry standard for early deployment. It is the combination (a so-called <i>hybrid</i>, more about that later) of two key agreements: <a href="https://cr.yp.to/ecdh.html">X25519</a> and a <a href="https://datatracker.ietf.org/doc/draft-cfrg-schwabe-kyber/">preliminary version</a> of NIST’s pick Kyber. Preliminary, because standardization of Kyber is not complete: NIST has released a <a href="https://csrc.nist.gov/pubs/fips/203/ipd">draft standard</a> for which it has requested public input. The final standard might change a little, but we do not expect any radical changes in security or performance. One notable change is the name: the NIST standard is set to be called <a href="https://csrc.nist.gov/pubs/fips/203/ipd"><i>ML-KEM</i></a>. Once ML-KEM is released in 2024, we will promptly adopt support for the corresponding hybrid, and deprecate support for X25519Kyber768Draft00. We will announce deprecation on this blog and <a href="https://pq.cloudflareresearch.com/">pq.cloudflareresearch.com</a>.</p>
    <div>
      <h3>Picking security level: 512 vs 768</h3>
      <a href="#picking-security-level-512-vs-768">
        
      </a>
    </div>
    <p>Back in 2022, for incoming connections, <a href="/post-quantum-for-all/">we enabled</a> hybrids with both Kyber512 and Kyber768. The difference is target security level: Kyber512 aims for the same security as AES-128, whereas Kyber768 matches up with AES-192. Contrary to popular belief, AES-128 is <a href="/nist-post-quantum-surprise/#grover-s-algorithm">not broken</a> in practice by quantum computers.</p><p>So why go with Kyber768? After years of analysis, there is no indication that Kyber512 fails to live up to its target security level. The designers of Kyber feel more comfortable, though, with the wider security margin of Kyber768, and we follow their advice.</p>
    <div>
      <h3>Hybrid</h3>
      <a href="#hybrid">
        
      </a>
    </div>
    <p>It is not inconceivable though, that an unexpected improvement in cryptanalysis will completely break Kyber768. Notably <a href="https://eprint.iacr.org/2022/214.pdf">Rainbow</a>, GeMMS and <a href="https://eprint.iacr.org/2022/975">SIDH</a> survived several rounds of public review before being broken. We do have to add nuance here. For a big break you need some mathematical trick, and compared to other schemes, SIDH had a lot of <i>mathematical attack surface</i>. Secondly, even though a scheme participated in many rounds of review doesn’t mean it saw a lot of attention. Because of their performance characteristics, these three schemes have more niche applications, and therefore received much less scrutiny from cryptanalysts. In contrast, Kyber is the big prize: breaking it will ensure fame.</p><p>Notwithstanding, for the moment, we feel it’s wiser to stick with hybrid key agreement. We combine Kyber together with X25519, which is currently the de facto standard key agreement, so that if Kyber turns out to be broken, we retain the non-post quantum security of X25519.</p>
    <div>
      <h3>Performance</h3>
      <a href="#performance">
        
      </a>
    </div>
    <p>Kyber is fast. Very fast. It easily beats X25519, which is already known for its speed:</p><table>
	<thead>
		<tr>
			<th> </th>
			<th> </th>
			<th><span>Size keyshares(in bytes)</span></th>
			<th><span>Ops/sec (higher is better)</span></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><span>Algorithm</span></td>
			<td><span>PQ</span></td>
			<td><strong>Client</strong></td>
			<td><strong>Server</strong></td>
			<td><strong>Client</strong></td>
			<td><strong>Server</strong></td>
		</tr>
		<tr>
			<td><strong>X25519</strong></td>
			<td><span>❌</span></td>
			<td><span>32</span></td>
			<td><span>32</span></td>
			<td><span>17,000</span></td>
			<td><span>17,000</span></td>
		</tr>
		<tr>
			<td><strong>Kyber768</strong></td>
			<td><span>✅</span></td>
			<td><span>1,184</span></td>
			<td><span>1,088</span></td>
			<td><span>31,000</span></td>
			<td><span>70,000</span></td>
		</tr>
		<tr>
			<td><strong>X25519Kyber768Draft00</strong></td>
			<td><span>✅</span></td>
			<td><span>1,216</span></td>
			<td><span>1,120</span></td>
			<td><span>11,000</span></td>
			<td><span>14,000</span></td>
		</tr>
	</tbody>
</table><p>Combined X25519Kyber768Draft00 is slower than X25519, but not by much. The big difference is its size: when connecting the client has to send 1,184 extra bytes for Kyber in the first message. That brings us to the next topic.</p>
    <div>
      <h2>When things break, and how to move forward</h2>
      <a href="#when-things-break-and-how-to-move-forward">
        
      </a>
    </div>
    
    <div>
      <h3>Split ClientHello</h3>
      <a href="#split-clienthello">
        
      </a>
    </div>
    <p>As we saw, the <i>ClientHello</i> is the first message that is sent by the client when setting up a TLS connection. With X25519, the ClientHello almost always fits within one network packet. With Kyber, the ClientHello doesn’t fit anymore with typical packet sizes and needs to be split over two network packets.</p><p>The TLS standard allows for the ClientHello to be split in this way. However, it used to be so exceedingly rare to see a split ClientHello that there is plenty of software and hardware out there that falsely assumes it never happens.</p><p>This so-called <b>protocol ossification</b> is the major challenge rolling out post-quantum key agreement. Back in 2019, during <a href="/the-tls-post-quantum-experiment/">earlier post-quantum experiments</a>, middleboxes of a particular vendor dropped connections with a split ClientHello. Chrome is currently <a href="https://blog.chromium.org/2023/08/protecting-chrome-traffic-with-hybrid.html">slowly ramping up</a> the number of post-quantum connections to catch these issues early. Several reports are listed <a href="https://twitter.com/davidcadrian/status/1692572405368078816">here</a>, and luckily most vendors seem to fix issues promptly.</p><p>Over time, with the slow ramp up of browsers, many of these implementation bugs will be found and corrected. However, we cannot completely rely on this for our outbound connections since in many cases Cloudflare is the sole client to connect directly to the origin server. Thus, we must exercise caution when deploying post-quantum cryptography to ensure that we are still able to reach origin servers even in the presence of buggy implementations.</p>
    <div>
      <h3>HelloRetryRequest to the rescue</h3>
      <a href="#helloretryrequest-to-the-rescue">
        
      </a>
    </div>
    <p>To enable support for post-quantum key agreement on all outbound connections, without risking issues with split ClientHello for those servers that are not ready yet, we make clever use of HelloRetryRequest. Instead of sending a X25519+Kyber keyshare, we will only advertise support for it, and send a non-post quantum secure X25519 keyshare in the first ClientHello.</p><p>If the origin does not support X25519+Kyber, then nothing changes. One might wonder: could merely advertising support for it trip up any origins? This used to be a real concern in the past, but luckily browsers have adopted a clever mechanism called <a href="https://datatracker.ietf.org/doc/html/rfc8701">GREASE</a>: they will send codepoints selected from unpredictable regions to make it hard to implement any software that could trip up on unknown codepoints.</p><p>If the origin does support X25519+Kyber, then it can use the HelloRetryRequest to request a post-quantum key agreement from us.</p><p>Things might still break then: for instance a malfunctioning middlebox, load-balancer, or the server software itself might still trip over the large ClientHello with X25519+Kyber sent in response to the HelloRetryRequest.</p><p>If we’re frank, the HRR trick kicks the can down the road: we as an industry will need to fix broken hardware and software before we can enable post-quantum on every last connection. The important thing though is that those past mistakes will not hold us back from securing the majority of connections. Luckily, from our experience, breakage will not be common.</p><p>So, when you have flipped the switch on your origin server, and things do break against expectation, what could be the root cause?</p>
    <div>
      <h3>Debugging and examples</h3>
      <a href="#debugging-and-examples">
        
      </a>
    </div>
    <p>It’s impossible to exhaustively list all bugs that could interfere with the post-quantum connection, but we like to share a few we’ve seen.</p><p>The first step is to figure out what pieces of hardware and software are involved in the connection. Rarely it’s just the server: there could be a load-balancer, and even a humble router could be at fault.</p><p>One straightforward mistake is to conveniently assume the ClientHello is small by reserving only a small, say 1000 byte, buffer.</p><p>A variation of this is where a server uses a single call to <a href="https://man7.org/linux/man-pages/man2/recv.2.html"><code>recv()</code></a> to read the ClientHello from the TCP connection. This works perfectly fine if it fits within one packet, but when split over multiple, it might require more calls.</p><p>Not all issues that we encountered relate directly to split ClientHello. For instance, servers using the Rust TLS library <a href="https://github.com/rustls/rustls">rustls</a> did <a href="https://github.com/rustls/rustls/issues/1373">not implement HelloRetryRequest correctly</a> before 0.21.7.</p><p>If you turned on post-quantum support for your origin, and hit issues, please do reach out: email <a>ask-research@cloudflare.com</a>.</p>
    <div>
      <h2>Opting in and opting out</h2>
      <a href="#opting-in-and-opting-out">
        
      </a>
    </div>
    <p>Now that you know what might lie in wait for you, let’s cover how to configure the outbound connections of your zone. There are three settings. The setting affects all outbound connections for your zone: to the origin server, but also for <code>fetch()</code> requests made by Workers on your zone.</p><table>
	<thead>
		<tr>
			<th><strong>Setting</strong></th>
			<th><strong>Meaning</strong></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><span><span>supported</span></span></td>
			<td><span>Advertise support for post-quantum key agreement, but send a classical keyshare in the first </span><em>ClientHello</em><span>.When the origin supports and prefers X25519+Kyber, a post-quantum connection will be established, but it incurs an extra roundtrip.This is the most compatible way to enable post-quantum.</span></td>
		</tr>
		<tr>
			<td><span><span>preferred</span></span></td>
			<td><span>Send a post-quantum keyshare in the first </span><em>ClientHello</em><span>.When the origin supports X25519+Kyber, a post-quantum connection will be established without an extra roundtrip. We continue advertising support for classical keyshares as well, so that origins that do not support X25519+Kyber will continue to function.
This is the most performant way to enable post-quantum.</span></td>
		</tr>
		<tr>
			<td><span><span>off</span></span></td>
			<td><span>Do not send or advertise support for post-quantum key agreement to the origin.</span></td>
		</tr>
		<tr>
			<td><span>(default)</span></td>
			<td><span>Allow us to determine the best behavior for your zone. (More about that later.)</span></td>
		</tr>
	</tbody>
</table><p>The setting can be adjusted using the following API call:</p>
            <pre><code>curl --request PUT \
  --url https://api.cloudflare.com/client/v4/zones/(zone_id)/cache/origin_post_quantum_encryption \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer (API token)' \
  --data '{"value": "(setting)"}'</code></pre>
            <p>Here, the parameters are as follows.</p><table>
	<thead>
		<tr>
			<th><strong>Parameter</strong></th>
			<th><strong>Value</strong></th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><span>setting</span></td>
			<td><span><span>supported</span>, <span>preferred</span>, or <span>off</span>, with meaning as described above</span></td>
		</tr>
		<tr>
			<td><span>zone_id</span></td>
			<td><span>Identifier of the zone to control. You can </span><a href="https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/"><u>look up the zone_id</u></a><span> in the dashboard.</span></td>
		</tr>
		<tr>
			<td><span>API token</span></td>
			<td><span>Token used to authenticate you. You can </span><a href="https://developers.cloudflare.com/fundamentals/api/get-started/create-token/"><u>create one in the dashboard</u></a><span>. Use </span><em>create custom token</em><span> and under permissions select </span><em>zone → zone settings → edit</em><span>.</span></td>
		</tr>
	</tbody>
</table>
    <div>
      <h3>Testing whether your origin server is configured correctly</h3>
      <a href="#testing-whether-your-origin-server-is-configured-correctly">
        
      </a>
    </div>
    <p>If you set your zone to <code>preferred</code> mode, you only need to check support for the proper post-quantum key agreement with your origin server. This can be done with the <code>bssl</code> tool of <a href="https://github.com/google/boringssl">BoringSSL</a>:</p>
            <pre><code>	$ bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]</code></pre>
            <p>If you set your zone to <code>supported</code> mode, or if you wait for the gradual roll-out, you will need to make sure that your origin server prefers post-quantum key agreement even if we sent a classical keyshare in the initial <i>ClientHello</i>. This can be done with <a href="https://github.com/cloudflare/boringssl-pq">our fork of BoringSSL</a>:</p>
            <pre><code>	$ git clone https://github.com/cloudflare/boringssl-pq
	[...]
	$ cd boringssl-pq &amp;&amp; cmake -B build &amp;&amp; make -C build
$ build/bssl client -connect (your server):443 -curves X25519:X25519Kyber768Draft00 -disable-second-keyshare
[...]
	  ECDHE curve: X25519Kyber768Draft00
[...]</code></pre>
            
    <div>
      <h2>Scanning ahead to remove the extra roundtrip</h2>
      <a href="#scanning-ahead-to-remove-the-extra-roundtrip">
        
      </a>
    </div>
    <p>With the <i>HelloRetryRequest</i> trick today, we can safely advertise support for post-quantum key agreement to all origins. The downside is that for those origins that do support post-quantum key agreement, we’re incurring an extra roundtrip for the <i>HelloRetryRequest</i>, which hurts performance.</p><p>You can remove the roundtrip by configuring your zone as <code>preferred</code>, but we can do better: the best setting is the one you shouldn’t have to touch.</p><p>We have started scanning all active origins for support of post-quantum key agreement. Roughly every 24 hours, we will attempt a series of about ten TLS connections to your origin, to test support and preferences for the various key agreements.</p><p>Our preliminary results show that 0.5% of origins support a post-quantum connection. As expected, we found that a small fraction (&lt;0.34%) of all origins do not properly establish a connection, when we send a post-quantum keyshare in the first ClientHello, which corresponds to the <code>preferred</code> setting. Unexpectedly the vast majority of these origins do return a <i>HelloRetryRequest</i>, but fail after receiving the second ClientHello with a classical keyshare. We are investigating the exact causes of these failures, and will reach out to vendors to help resolve them.</p><p>Later this year, we will start using these scan results to determine the best setting for zones that haven’t been configured yet. That means that for those zones whose origins support it reliably, we will send a post-quantum keyshare directly without extra roundtrip.</p>
    <div>
      <h3>Also speeding up non post-quantum origins</h3>
      <a href="#also-speeding-up-non-post-quantum-origins">
        
      </a>
    </div>
    <p>The scanner pipeline we built will not just benefit post-quantum origins. By default we send X25519, but not every origin supports or prefers X25519. We find that 4% of origin servers will send us a HelloRetryRequest for other key agreements such as P-384.</p>
<table>
<thead>
  <tr>
    <th><span>Key agreement</span></th>
    <th><span>Fraction supported</span></th>
    <th><span>Fraction preferred</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>X25519</span></td>
    <td><span>96%</span></td>
    <td><span>96%</span></td>
  </tr>
  <tr>
    <td><span>P-256</span></td>
    <td><span>97%</span></td>
    <td><span>0.6%</span></td>
  </tr>
  <tr>
    <td><span>P-384</span></td>
    <td><span>89%</span></td>
    <td><span>2.3%</span></td>
  </tr>
  <tr>
    <td><span>P-521</span></td>
    <td><span>82%</span></td>
    <td><span>0.1%</span></td>
  </tr>
  <tr>
    <td><span>X25519Kyber768Draft00</span></td>
    <td><span>0.5%</span></td>
    <td><span>0.5%</span></td>
  </tr>
</tbody>
</table><p>Also, later this year, we will use these scan results to directly send the most preferred keyshare to your origin removing the need for an extra roundtrip caused by HRR.</p>
    <div>
      <h2>Wrapping up</h2>
      <a href="#wrapping-up">
        
      </a>
    </div>
    <p>To mitigate the <i>store-now/decrypt-later</i> threat, and ensure the Internet stays encrypted, the IT industry needs to work together to roll out post-quantum cryptography. We’re excited that today we’re rolling out support for post-quantum secure outbound connections: connections between Cloudflare and the origins.</p><p>We would love it if you would try and enable post-quantum key agreement on your origin. Please, do share your experiences, or reach out for any questions: <a>ask-research@cloudflare.com</a>.</p><p>To follow the latest developments of our deployment of post-quantum cryptography, and client/server support, check out <a href="https://pq.cloudflareresearch.com/">pq.cloudflareresearch.com</a> and keep an eye on this blog.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">7D9GZLWGiSDKHz84NFp54d</guid>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Luke Valenta</dc:creator>
            <dc:creator>Bas Westerbaan</dc:creator>
        </item>
        <item>
            <title><![CDATA[Connection coalescing with ORIGIN Frames: fewer DNS queries, fewer connections]]></title>
            <link>https://blog.cloudflare.com/connection-coalescing-with-origin-frames-fewer-dns-queries-fewer-connections/</link>
            <pubDate>Mon, 04 Sep 2023 13:00:51 GMT</pubDate>
            <description><![CDATA[ In this blog we’re going to take a closer look at “connection coalescing”, with specific focus on manage it at a large scale ]]></description>
            <content:encoded><![CDATA[ <p><i>This blog reports and summarizes the contents of a Cloudflare </i><a href="https://research.cloudflare.com/publications/Singanamalla2022/"><i>research paper</i></a><i> which appeared at the ACM </i><a href="https://conferences.sigcomm.org/imc/2022/program/"><i>Internet Measurement Conference</i></a><i>, that measures and prototypes connection coalescing with ORIGIN Frames.</i></p><p>Some readers might be surprised to hear that a single visit to a web page can cause a browser to make tens, sometimes even hundreds, of web connections. Take this very blog as an example. If it is your first visit to the Cloudflare blog, or it has been a while since your last visit, your browser will make multiple connections to render the page. The browser will make DNS queries to find IP addresses corresponding to blog.cloudflare.com and then subsequent requests to retrieve any necessary subresources on the web page needed to successfully render the complete page. How many? Looking below, at the time of writing, there are 32 different hostnames used to load the Cloudflare Blog. That means 32 DNS queries and <i>at least</i> 32 TCP (or QUIC) connections, unless the client is able to reuse (or coalesce) some of those connections.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5iVEUq8ZQ8HsPbg1FAP5jq/de5899ea338a7628e732558caf2f8710/Screenshot-2023-09-03-at-18.34.41.png" />
            
            </figure><p>Each new web connection not only introduces additional load on a server's processing capabilities – potentially leading to scalability challenges during peak usage hours – but also exposes client metadata to the network, such as the plaintext hostnames being accessed by an individual. Such meta information can potentially reveal a user’s online activities and browsing behaviors to on-path network adversaries and eavesdroppers!</p><p>In this blog we’re going to take a closer look at “connection coalescing”. Since our initial look at <a href="/connection-coalescing-experiments/">IP-based coalescing in 2021</a>, we have done further large-scale measurements and modeling across the Internet, to understand and predict if and where coalescing would work best. Since IP coalescing is difficult to manage at large scale, last year we implemented and experimented with a promising standard called the <a href="https://datatracker.ietf.org/doc/rfc8336/">HTTP/2 ORIGIN Frame extension</a> that we leveraged to coalesce connections to our edge without worrying about managing IP addresses.</p><p>All told, there are opportunities being missed by many large providers. We hope that this blog (and our <a href="https://research.cloudflare.com/publications/Singanamalla2022/">publication</a> at ACM IMC 2022 with full details) offers a first step that helps servers and clients take advantage of the ORIGIN Frame standard.</p>
    <div>
      <h3>Setting the stage</h3>
      <a href="#setting-the-stage">
        
      </a>
    </div>
    <p>At a high level, as a user navigates the web, the browser renders web pages by retrieving dependent subresources to construct the complete web page. This process bears a striking resemblance to the way physical products are assembled in a factory. In this sense, a modern web page can be considered like an assembly plant. It relies on a ‘supply chain’ of resources that are needed to produce the final product.</p><p>An assembly plant in the physical world can place a single order for different parts and get a single shipment from the supplier (similar to the <a href="https://www.sciencedirect.com/science/article/abs/pii/092552739290109K">kitting process</a> for maximizing value and minimizing response time); no matter the manufacturer of those parts or where they are made -- one ‘connection’ to the supplier is all that is needed. Any single truck from a supplier to an assembly plant can be filled with parts from multiple manufacturers.</p><p>The design of the web causes browsers to typically do the opposite in nature. To retrieve the images, JavaScript, and other resources on a web page (the parts), web clients (assembly plants) have to make <i>at least</i> one connection to every hostname (the manufacturers) defined in the HTML that is returned by the server (the supplier). It makes no difference if the connections to those hostnames go to the same server or not, for example they could go to a <a href="https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/">reverse proxy</a> like Cloudflare. For each manufacturer a ‘new’ truck would be needed to transfer the materials to the assembly plant from the same supplier, or more formally, a new connection would need to be made to request a subresource from a hostname on the same web page.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3jdJ2PTbkKJKMFxbWD6RgD/40b366c9315d9c55e2409e1654bc0a3d/pasted-image-0--4-.png" />
            
            </figure><p>Without connection coalescing</p><p>The number of connections used to load a web page can be surprisingly high. It is also common for the subresources to need yet other sub-subresources, and so new connections emerge as a result of earlier ones. Remember, too, that HTTP connections to hostnames are often preceded by DNS queries! Connection coalescing allows us to use fewer connections_, or ‘reuse’ the same set of trucks to carry parts from multiple manufacturers from a single supplier._</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/jJx6aGfQCngN6w6D4jpeE/1dcfe2b5e3f8128d8837512ec1a959c9/pasted-image-0--5-.png" />
            
            </figure><p>With connection coalescing </p>
    <div>
      <h3>Connection coalescing in principle</h3>
      <a href="#connection-coalescing-in-principle">
        
      </a>
    </div>
    <p>Connection coalescing was <a href="https://datatracker.ietf.org/doc/html/rfc7540">introduced in HTTP/2</a>, and carried over into <a href="https://www.rfc-editor.org/rfc/rfc9114.html#name-connection-reuse">HTTP/3</a>. We’ve blogged about connection coalescing <a href="/connection-coalescing-experiments/">previously</a> (for a detailed primer we encourage going over that blog). While the idea is simple, implementing it can present a number of engineering challenges. For example, recall from above that there are 32 hostnames (at the time of writing) to load the web page you are reading right now. Among the 32 hostnames are 16 unique domains (defined as “Effective <a href="https://www.cloudflare.com/learning/dns/top-level-domain/">TLD+1</a>”). Can we create fewer connections or ‘coalesce’ existing connections for each unique domain? The answer is ‘<i>Yes, but it depends</i>’.</p><p>The exact number of connections to load the blog page is not at all obvious, and hard to know. There may be 32 hostnames attached to 16 domains but, counter-intuitively, this does not mean the answer to “how many unique connections?” is 16. The true answer could be as few as <i>one</i> connection if all the hostnames are reachable at a single server; or as many as 32 independent connections if a different and distinct server is needed to access each individual hostname.</p><p>Connection reuse comes in many forms, so it’s important to define “connection coalescing” in the HTTP space. For example, the reuse of an existing <a href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/">TCP</a> or TLS connection to a hostname to make multiple requests for subresources from that <b><i>same</i></b> hostname is connection reuse, but not coalescing.</p><p>Coalescing occurs when an existing TLS channel for some hostname can be repurposed or used for connecting to a <b><i>different</i></b> hostname. For example, upon visiting blog.cloudflare.com, the HTML points to subresources at cdnjs.cloudflare.com. To reuse the same TLS connection for the subresources, it is necessary for both hostnames to appear together in the TLS certificate's <a href="https://en.wikipedia.org/wiki/Subject_Alternative_Name">“Server Alternative Name (SAN)</a>” list, but this step alone is not sufficient to convince browsers to coalesce. After all, the cdnjs.cloudflare.com service may or may not be reachable at the same server as blog.cloudflare.com, despite being on the same certificate. So how can the browser know? Coalescing only works if servers set up the right conditions, but clients have to decide whether to coalesce or not – thus, browsers require a signal to coalesce beyond the SANs list on the certificate. Revisiting our analogy, the assembly plant may order a part from a manufacturer directly, not knowing that the supplier already has the same part in its warehouse.</p><p>There are two explicit signals a browser can use to decide whether connections can be coalesced: one is IP-based, the other ORIGIN Frame-based. The former requires the server operators to tightly bind DNS records to the HTTP resources available on the server. This is difficult to manage and deploy, and actually creates a risky dependency, because you have to place all the resources behind a specific set or a single IP address. The way IP addresses influence coalescing decisions <a href="https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/">varies among browsers</a>, with some choosing to be more conservative and others more permissive. Alternatively, the HTTP ORIGIN Frame is an easier signal for the servers to orchestrate; it’s also flexible and has graceful failure with no interruption to service (for a specification compliant implementation).</p><p>A foundational difference between both these coalescing signals is: IP-based coalescing signals are implicit, even accidental, and force clients to infer coalescing possibilities that may exist, or not. None of this is surprising since IP addresses are designed to <a href="/addressing-agility/">have no real relationship with names!</a> In contrast, ORIGIN Frame is an explicit signal from servers to clients that coalescing is available no matter what DNS says for any particular hostname.</p><p>We have experimented with <a href="/connection-coalescing-experiments/">IP-based coalescing previously</a>; for the purpose of this blog we will take a deeper look at ORIGIN Frame-based coalescing.</p>
    <div>
      <h3>What is the ORIGIN Frame standard?</h3>
      <a href="#what-is-the-origin-frame-standard">
        
      </a>
    </div>
    <p>The ORIGIN Frame is an extension to the <a href="https://www.rfc-editor.org/rfc/rfc8336">HTTP/2</a> and <a href="https://www.rfc-editor.org/rfc/rfc9412">HTTP/3</a> specification, a special Frame sent on stream 0 or the control stream of the connection respectively. The Frame allows the servers to send an ‘origin-set’ to the clients on an <i>existing</i> established TLS connection, which includes hostnames that it is authorized for and will not incur any <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/421">HTTP 421 errors</a>. Hostnames in the origin-set MUST also appear in the certificate SAN list for the server, even if those hostnames are announced on different IP addresses via DNS.</p><p>Specifically, two different steps are required:</p><ol><li><p>Web servers must send a list enumerating the Origin Set (the hostnames that a given connection might be used for) in the ORIGIN Frame extension.</p></li><li><p>The TLS certificate returned by the web server must cover the additional hostnames being returned in the ORIGIN Frame in the DNS names SAN entries.</p></li></ol><p>At a high-level ORIGIN Frames are a supplement to the TLS certificate that operators can attach to say, “Psst! Hey, client, here are the names in the SANs that are available on this connection -- you can coalesce!” Since the ORIGIN Frame is not part of the certificate itself, its contents can be made to change independently. No new certificate is required. There is also no dependency on IP addresses. For a coalesceable hostname, existing TCP/QUIC+TLS connections can be reused without requiring new connections or DNS queries.</p><p><a href="https://w3techs.com/technologies/overview/proxy">Many websites today</a> rely on content which is served by CDNs, like Cloudflare CDN service. The practice of using external CDN services offers websites the advantages of speed, reliability, and reduces the load of content served by their <a href="https://www.cloudflare.com/learning/cdn/glossary/origin-server/">origin servers</a>. When both the website, and the resources are served by the same CDN, despite being different hostnames, owned by different entities, it opens up some very interesting opportunities for CDN operators to allow connections to be reused and coalesced since they can control both the certificate management and connection requests for sending ORIGIN frames on behalf of the real origin server.</p><p>Unfortunately, there has been no way to turn the possibilities enabled by ORIGIN Frame into practice. To the best of our knowledge, until today, there has been no server implementation that supports ORIGIN Frames. Among browsers, only Firefox supports ORIGIN Frames. Since IP coalescing is challenging and ORIGIN Frame has no deployed support, is the engineering time and energy to better support coalescing worth the investment? We decided to find out with a large-scale Internet-wide measurement to understand the opportunities and predict the possibilities, and then implemented the ORIGIN Frame to experiment on production traffic.</p>
    <div>
      <h3>Experiment #1: What is the scale of required changes?</h3>
      <a href="#experiment-1-what-is-the-scale-of-required-changes">
        
      </a>
    </div>
    <p>In February 2021, <a href="/connection-coalescing-experiments/">we collected data</a> for 500K of the <a href="https://radar.cloudflare.com/domains">most popular websites</a> on the Internet, using a modified <a href="https://github.com/WPO-Foundation/webpagetest">Web Page Test</a> on 100 virtual machines. An automated Chrome (v88) browser instance was launched for every visit to a web page to eliminate caching effects (because we wanted to understand coalescing, not caching). On successful completion of each session, Chrome developer tools were used to retrieve and write the page load data as an HTTP Archive format (HAR) file with a full timeline of events, as well as additional information about certificates and their validation. Additionally, we parsed the certificate chains for the root web page and new TLS connections triggered by subresource requests to (i) identify certificate issuers for the hostnames, (ii) inspect the presence of the Subject Alternative Name (SAN) extension, and (iii) validate that DNS names resolve to the IP address used. Further details about our methodology and results can be found in the technical <a href="https://research.cloudflare.com/publications/Singanamalla2022/">paper</a>.</p><p>The first step was to understand what resources are requested by web pages to successfully render the page contents, and where these resources were present on the Internet. Connection coalescing becomes possible when subresource domains are ideally co-located. We approximated the location of a domain by finding its corresponding autonomous system (AS). For example, the domain attached to <a href="https://cdnjs.cloudflare.com/https://cdnjs.cloudflare.com/">cdnjs</a> is reachable via AS 13335 in the BGP routing table, and that AS number belongs to Cloudflare. The figure below describes the percentage of web pages and the number of unique ASes needed to fully load a web page.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3H188I6GyYxiqZEYxBPMPp/4bde6b40a523d0e66207c87cee40755c/Screenshot-2023-08-31-at-1.39.16-PM.png" />
            
            </figure><p>Around 14% of the web pages need two ASes to fully load i.e. pages that have a dependency on one additional AS for subresources. More than 50% of the web pages need to contact no more than six ASes to obtain all the necessary subresources. This finding as shown in the plot above implies that a relatively small number of operators serve the sub-resource content necessary for a majority (~50%) of the websites, and any usage of ORIGIN Frames would need only a few changes to have its intended impact. The potential for connection coalescing can therefore be optimistically approximated to the number of unique ASes needed to retrieve all subresources in a web page. In practice however, this may be superseded by operational factors such as SLAs or helped by flexible mappings between sockets, names, and IP addresses which we worked on <a href="https://research.cloudflare.com/publications/Fayed2021/">previously at Cloudflare</a>.</p><p>We then tried to understand the impact of coalescing on connection metrics. The measured and ideal number of DNS queries and TLS connections needed to load a web page are summarized by their CDFs in the figure below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7aCaLsYdjNqeuQAuVSfQ6c/beae2aeaf3e96830f9562c09aeb0a2cd/Screenshot-2023-08-31-at-1.39.02-PM.png" />
            
            </figure><p>Through modeling and extensive analysis, we identify that connection coalescing through ORIGIN Frames could reduce the number of DNS and TLS connections made by browsers by over 60% at the median. We performed this modeling by identifying the number of times the clients requested DNS records, and combined them with the ideal ORIGIN Frames to serve.</p><p>Many multi-origin servers such as those operated by <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/">CDNs</a> tend to reuse certificates and serve the same certificate with multiple DNS SAN entries. This allows the operators to manage fewer certificates through their creation and renewal cycles. While theoretically one can have millions of names in the certificate, creating such certificates is unreasonable and a challenge to manage effectively. By continuing to rely on existing certificates, our modeling measurements bring to light the volume of changes required to enable perfect coalescing, while presenting information about the scale of changes needed, as highlighted in the figure below.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5rIcRVeD6UEGNCW9dj3MYM/187f0bc53e9afedf3baca072410eb4db/Screenshot-2023-08-31-at-1.38.35-PM.png" />
            
            </figure><p>We identify that over 60% of the certificates served by websites do not need any modifications and could benefit from ORIGIN Frames, while with no more than 10 additions to the DNS SAN names in certificates we’re able to successfully coalesce connections to over 92% of the websites in our measurement. The most effective changes could be made by CDN providers by adding three or four of their most popular requested hostnames into each certificate.</p>
    <div>
      <h3>Experiment #2: ORIGIN Frames in action</h3>
      <a href="#experiment-2-origin-frames-in-action">
        
      </a>
    </div>
    <p>In order to validate our modeling expectations, we then took a more active approach in early 2022. Our next experiment focused on 5,000 websites that make extensive use of <i>cdnjs.cloudflare.com</i> as a subresource. By modifying our experimental TLS termination endpoint we deployed HTTP/2 ORIGIN Frame support as defined in the <a href="https://datatracker.ietf.org/doc/rfc8336/">RFC standard</a>. This involved changing the internal fork of <i>net</i> and <i>http</i> dependency modules of Golang which we have open sourced (<a href="https://github.com/cloudflare/go-originframe">see here</a>, and <a href="https://github.com/cloudflare/net-originframe">here</a>).</p><p>During the experiments, connecting to a website in the experiment set would return <i>cdnjs.cloudflare.com</i> in the ORIGIN frame, while the control set returned an arbitrary (unused) hostname. All existing edge certificates for the 5000 websites were also modified. For the experimental group, the corresponding certificates were renewed with <i>cdnjs.cloudflare.com</i> added to the SAN. To ensure integrity between control and experimental sets, control group domains certificates were also renewed with a valid and identical size third party domain used by none of the control domains. This is done to ensure that the relative size changes to the certificates is kept constant avoiding potential biases due to different certificate sizes. Our results were striking!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2jGJXHliykd9CGh3lNujpq/bc1b9faf871d7d4c6ecf7041966078cb/Screenshot-2023-08-31-at-1.38.47-PM.png" />
            
            </figure><p>Sampling 1% of the requests we received from Firefox to the websites in the experiment, we identified over <b>50% reduction in new TLS connections per second</b> indicating a lesser number of cryptographic verification operations done by both the client and reduced server compute overheads. As expected there were no differences in the control set indicating the effectiveness of connection re-use as seen by the CDN or server operators.</p>
    <div>
      <h3>Discussion and insights</h3>
      <a href="#discussion-and-insights">
        
      </a>
    </div>
    <p>While our modeling measurements indicated that we could anticipate some performance improvements, in practice it was not significantly better suggesting that ‘no-worse’ is the appropriate mental model regarding performance. The subtle interplay between resource object sizes, competing connections, and congestion control is subject to network conditions. Bottleneck-share capacity, for example, diminishes as fewer connections compete for bottleneck resources on network links. It would be interesting to revisit these measurements as more operators deploy support on their servers for ORIGIN Frames.</p><p>Apart from performance, one major benefit of ORIGIN frames is in terms of privacy. How? Well, each coalesced connection hides client metadata that is otherwise leaked from non-coalesced connections. Certain resources on a web page are loaded depending on how one is interacting with the website. This means for every new connection for retrieving some resource from the server, TLS plaintext metadata like <a href="https://www.cloudflare.com/learning/ssl/what-is-sni/">SNI</a> (in the absence of <a href="/encrypted-client-hello/">Encrypted Client Hello</a>) and at least one plaintext DNS query, if transmitted over UDP or TCP on port 53, is exposed to the network. Coalescing connections helps remove the need for browsers to open new TLS connections, and the need to do extra DNS queries. This prevents metadata leakage from anyone listening on the network. ORIGIN Frames help minimize those signals from the network path, improving privacy by reducing the amount of cleartext information leaked on path to network eavesdroppers.</p><p>While the browsers benefit from reduced cryptographic computations needed to verify multiple certificates, a major advantage comes from the fact that it opens up very interesting future opportunities for resource scheduling at the endpoints (the browsers, and the origin servers) such as <a href="/better-http-3-prioritization-for-a-faster-web/">prioritization</a>, or recent proposals like <a href="/early-hints/">HTTP early hints</a> to provide clients experiences where connections are not overloaded or competing for those resources. When coupled with <a href="https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-http2-secondary-certs-06#section-3.4">CERTIFICATE Frames</a> IETF draft, we can further eliminate the need for manual certificate modifications as a server can prove its authority of hostnames after connection establishment without any additional SAN entries on the website’s TLS certificate.</p>
    <div>
      <h3>Conclusion and call to action</h3>
      <a href="#conclusion-and-call-to-action">
        
      </a>
    </div>
    <p>In summary, the current Internet ecosystem has a lot of opportunities for connection coalescing with only a few changes to certificates and their server infrastructure. Servers can significantly reduce the number of TLS handshakes by roughly 50%, while reducing the number of render blocking DNS queries by over 60%. Clients additionally reap these benefits in privacy by reducing cleartext DNS exposure to network on-lookers.</p><p>To help make this a reality we are currently planning to add support for both HTTP/2 and HTTP/3 ORIGIN Frames for our customers. We also encourage other operators that manage third party resources to adopt support of ORIGIN Frame to improve the Internet ecosystem.Our paper submission was accepted to the ACM Internet Measurement Conference 2022 and is <a href="https://research.cloudflare.com/publications/Singanamalla2022/">available for download</a>. If you’d like to work on projects like this, where you get to see the rubber meet the road for new standards, visit our <a href="https://www.cloudflare.com/careers/">careers page</a>!</p> ]]></content:encoded>
            <category><![CDATA[DNS]]></category>
            <category><![CDATA[Internship Experience]]></category>
            <category><![CDATA[Speed & Reliability]]></category>
            <category><![CDATA[HTTP2]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Research]]></category>
            <guid isPermaLink="false">QjYiQB1Bf6uRL71yURBMi</guid>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Jonathan Hoyland</dc:creator>
            <dc:creator>Sudheesh Singanamalla</dc:creator>
        </item>
        <item>
            <title><![CDATA[Automatic (secure) transmission: taking the pain out of origin connection security]]></title>
            <link>https://blog.cloudflare.com/securing-origin-connectivity/</link>
            <pubDate>Mon, 03 Oct 2022 13:00:00 GMT</pubDate>
            <description><![CDATA[ Today we’re excited to announce that we will soon be offering a zero-configuration option for security on Cloudflare. If we find that we can automatically upgrade the security connection between Cloudflare and a user’s origin, we will ]]></description>
            <content:encoded><![CDATA[ <p><i></i></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/629MTo8freJ9xGG3KoHyvO/ac03192ec0ce5eb78c1396361a95d73b/image1-4.png" />
            
            </figure><p>In 2014, Cloudflare set out to encrypt the Internet by introducing <a href="/introducing-universal-ssl/">Universal SSL</a>. It made <a href="https://www.cloudflare.com/application-services/products/ssl/">getting an SSL/TLS certificate free and easy</a> at a time when doing so was neither free, nor easy. Overnight millions of websites had a secure connection between the user’s browser and Cloudflare.</p><p>But getting the connection encrypted from Cloudflare to the customer’s origin server was more complex. Since Cloudflare and all browsers supported SSL/TLS, the connection between the browser and Cloudflare could be instantly secured. But back in 2014 configuring an origin server with an SSL/TLS certificate was complex, expensive, and sometimes not even possible.</p><p>And so we relied on users to configure the best security level for their origin server. Later we added a service that detects and <a href="/ssl-tls-recommender/">recommends the highest level of security</a> for the connection between Cloudflare and the origin server. We also introduced free <a href="/cloudflare-ca-encryption-origin/">origin server certificates</a> for customers who didn’t want to get a certificate elsewhere.</p><p>Today, we’re going even further. Cloudflare will shortly find the most secure connection possible to our customers’ origin servers and use it, automatically. Doing this correctly, at scale, while not breaking a customer’s service is very complicated. This blog post explains how we are automatically achieving that highest level of security possible for those customers who don’t want to spend time configuring their SSL/TLS set up manually.</p>
    <div>
      <h3>Why configuring origin SSL automatically is so hard</h3>
      <a href="#why-configuring-origin-ssl-automatically-is-so-hard">
        
      </a>
    </div>
    <p>When we announced Universal SSL, we knew the <a href="/universal-ssl-encryption-all-the-way-to-the-origin-for-free/">backend security of the connection</a> between Cloudflare and the origin was a different and harder problem to solve.</p><p>In order to <a href="https://www.cloudflare.com/learning/security/glossary/website-security-checklist/">configure the tightest security</a>, customers had to procure a certificate from a third party and upload it to their origin. Then they had to indicate to Cloudflare that we should use this certificate to verify the identity of the server while also indicating the connection security capabilities of their origin. This could be an expensive and tedious process. To help alleviate this high set up cost, in 2015 Cloudflare <a href="/universal-ssl-encryption-all-the-way-to-the-origin-for-free/">launched a beta Origin CA service</a> in which we provided free limited-function certificates to customer origin servers. We also provided guidance on how to correctly configure and upload the certificates, so that secure connections between Cloudflare and a customer’s origin could be established quickly and easily.</p><p>What we discovered though, is that while this service was useful to customers, it still required a lot of configuration. We didn’t see the change we did with Universal SSL because customers still had to fight with their origins in order to upload certificates and test to make sure that they had configured everything correctly. And when you throw things like load balancers into the mix or servers mapped to different subdomains, handling server-side SSL/TLS gets even more complicated.</p><p>Around the same time as that announcement, <a href="https://letsencrypt.org/how-it-works/">Let’s Encrypt</a> and other services began offering certificates as a public CA for free, making TLS easier and paving the way for widespread adoption. Let’s Encrypt and Cloudflare had come to the same conclusion: by offering certificates for free, simplifying server configuration for the user, and working to streamline certificate renewal, they could make a tangible impact on the overall security of the web.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4ZURjaGV7W20VQb5GDkM0T/489e9677c3fb842e40273c8ad4563c52/image3-1.png" />
            
            </figure><p>The announcements of free and easy to configure certificates correlated with an increase in attention on origin-facing security. Cloudflare customers began requesting more documentation to configure origin-facing certificates and SSL/TLS communication that were performant and intuitive. In response, in 2016 we <a href="/cloudflare-ca-encryption-origin/">announced the GA of origin certificate authority</a> to provide cheap and easy origin certificates along with <a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca/">guidance on how to best configure backend security</a> for any website.</p><p>The increased customer demand and attention helped pave the way for additional features that focused on backend security on Cloudflare. For example, <a href="https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull">authenticated origin pull</a> ensures that only HTTPS requests from Cloudflare will receive a response from your origin, preventing an origin response from requests outside of Cloudflare. Another option, <a href="/tunnel-for-everyone/">Cloudflare Tunnel</a> can be set up to run on the origin servers, proactively establishing secure and private tunnels to the nearest Cloudflare data center. This configuration allows customers to completely lock down their origin servers to only receive requests routed through our network. For customers unable to lock down their origins using this method, we still encourage adopting the strongest possible security when configuring how Cloudflare should connect to an origin server.</p><p>Cloudflare currently offers five options for SSL/TLS configurability that we use when communicating with origins:</p><ul><li><p>In <b>Off</b> mode, as you might expect, traffic from browsers to Cloudflare and from Cloudflare to origins are not encrypted and will use plain text HTTP.</p></li><li><p>In <b>Flexible</b> mode, traffic from browsers to Cloudflare can be encrypted via HTTPS, but traffic from Cloudflare to the site's origin server is not. This is a common selection for origins that cannot support TLS, even though we recommend upgrading this origin configuration wherever possible. A guide for upgrading can be found <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full/#required-setup">here</a>.</p></li><li><p>In <b>Full</b> mode, Cloudflare follows whatever is happening with the browser request and uses that same option to connect to the origin. For example, if the browser uses HTTP to connect to Cloudflare, we’ll establish a connection with the origin over HTTP. If the browser uses HTTPS, we’ll use HTTPS to communicate with the origin; however we will not validate the certificate on the origin to prove the identity and trustworthiness of the server.</p></li><li><p>In <b>Full (strict)</b> mode, traffic between Cloudflare follows the same pattern as in Full mode, however Full (strict) mode adds validation of the origin server’s certificate. The origin certificate can either be issued by a public CA like Let’s Encrypt or by <a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca">Cloudflare Origin CA.</a></p></li><li><p>In <b>Strict</b> mode, traffic from the browser to Cloudflare that is HTTP or HTTPS will always be connected to the origin over HTTPS with a validation of the origin server’s certificate.</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4WSh4V7JAEnrGqsw6z6y89/ddabb274f5ceb7c55930b8429d17f5dd/image2-3.png" />
            
            </figure><p>What we have found in a lot of cases is that when customers initially signed up for Cloudflare, the origin they were using could not support the most advanced versions of encryption, resulting in origin-facing communication using unencrypted HTTP. These default values persisted over time, even though the origin has become more capable. We think the time is ripe to re-evaluate the entire concept of default SSL/TLS levels.</p><p>That’s why we will reduce the configuration burden for origin-facing security by <b>automatically</b> managing this on behalf of our customers. Cloudflare will provide a zero configuration option for how we will communicate with origins: we will simply look at an origin and use the most-secure option available to communicate with it.</p><p>Re-evaluating default SSL/TLS modes is only the beginning. Not only will we automatically upgrade sites to their best security setting, <b>we will also open up all SSL/TLS modes to all plan levels</b>. Historically, Strict mode was reserved for enterprise customers only. This was because we released this mode in 2014 when few people had origins that were able to communicate over SSL/TLS, and we were nervous about customers breaking their configurations. But this is 2022, and we think that Strict mode should be available to anyone who wants to use it. So we will be opening it up to everyone with the launch of the automatic upgrades.</p>
    <div>
      <h3>How will automatic upgrading work?</h3>
      <a href="#how-will-automatic-upgrading-work">
        
      </a>
    </div>
    <p>To upgrade the origin-facing security of websites, we first need to determine the highest security level the origin can use. To make this determination, we will use the <a href="/ssl-tls-recommender/">SSL/TLS Recommender</a> tool that we released a year ago.</p><p>The recommender performs a series of requests from Cloudflare to the customer’s origin(s) to determine if the backend communication can be upgraded beyond what is currently configured. The recommender accomplishes this by:</p><ul><li><p>Crawling the website to collect links on different pages of the site. For websites with large numbers of links, the recommender will only examine a subset. Similarly, for sites where the crawl turns up an insufficient number of links, we augment our results with a sample of links from recent visitors requests to the zone. All of this is to get a representative sample to where requests are going in order to know how responses are served from the origin.</p></li><li><p>The crawler uses the user agent <code>Cloudflare-SSLDetector</code> and has been added to Cloudflare’s list of <a href="https://developers.cloudflare.com/firewall/known-issues-and-faq#bots-currently-detected">known “good bots</a>”.</p></li><li><p>Next, the recommender downloads the content of each link over both HTTP and HTTPS. The recommender makes only idempotent GET requests when scanning origin servers to avoid modifying server resource state.</p></li><li><p>Following this, the recommender runs a content similarity algorithm to determine if the content collected over HTTP and HTTPS matches.</p></li><li><p>If the content that is downloaded over HTTP matches the content downloaded over HTTPS, then it’s known that we can upgrade the security of the website without negative consequences.</p></li><li><p>If the website is already configured to Full mode, we will perform a certificate validation (without the additional need for crawling the site) to determine whether it can be updated to Full (strict) mode or higher.</p></li></ul><p>If it can be determined that the customer’s origin is able to be upgraded without breaking, we will upgrade the origin-facing security automatically.</p><p>But that’s not all. Not only are we removing the configuration burden for services on Cloudflare, but we’re also <b>providing more precise security settings by moving from per-zone SSL/TLS settings to per-origin SSL/TLS settings</b>.</p><p>The current implementation of the backend SSL/TLS service is related to an entire website, which works well for those with a single origin. For those that have more complex setups however, this can mean that origin-facing security is defined by the lowest capable origin serving a part of the traffic for that service. For example, if a website uses img.example.com and api.example.com, and these subdomains are served by different origins that have different security capabilities, we would not want to limit the SSL/TLS capabilities of both subdomains to the least secure origin. By using our new service, we will be able to set per-origin security more precisely to allow us to maximize the security posture of each origin.</p><p>The goal of this is to maximize the origin-facing security of everything on Cloudflare. However, if any origin that we attempt to scan blocks the SSL recommender, has a non-functional origin, or opts-out of this service, we will not complete the scans and will not be able to upgrade security. Details on how to opt-out will be provided via email announcements soon.</p>
    <div>
      <h3>Opting out</h3>
      <a href="#opting-out">
        
      </a>
    </div>
    <p>There are a number of reasons why someone might want to configure a lower-than-optimal security setting for their website. One common reason customers provide is a fear that having higher security settings will negatively impact the performance of their site. Others may want to set a suboptimal security setting for testing purposes or to debug some behavior. Whatever the reason, we will provide the tools needed to continue to configure the SSL/TLS mode you want, even if that’s different from what we think is the best.</p>
    <div>
      <h3>When is this going to happen?</h3>
      <a href="#when-is-this-going-to-happen">
        
      </a>
    </div>
    <p>We will begin to roll this change out before the end of the year. If you read this and want to make sure you’re at the highest level of backend security already, we recommend <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/full-strict/">Full (strict)</a> or <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/ssl-only-origin-pull/">Strict mode</a>. If you prefer to wait for us to automatically upgrade your origin security for you, please keep your eyes peeled to your inbox for the date we will begin rolling out this change for your group.</p><p>At Cloudflare, we believe that the Internet needs to be secure and private. If you’d like to help us achieve that, we’re hiring across the <a href="https://www.cloudflare.com/careers/jobs/?department=Engineering">engineering organization</a>.</p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[CDN]]></category>
            <category><![CDATA[Universal SSL]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">74aHWDdU28HyUkx2We1M02</guid>
            <dc:creator>Alex Krivit</dc:creator>
            <dc:creator>Mikey Sleevi</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
        </item>
        <item>
            <title><![CDATA[Coalescing Connections to Improve Network Privacy and Performance]]></title>
            <link>https://blog.cloudflare.com/connection-coalescing-experiments/</link>
            <pubDate>Wed, 13 Oct 2021 12:59:25 GMT</pubDate>
            <description><![CDATA[ Real world experiments for evaluating connection coalescing effects. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Web pages typically have <a href="https://discuss.httparchive.org/t/whats-the-distribution-of-requests-per-page/21/10?u=patmeenan">a large number</a> of embedded subresources (e.g., JavaScript, CSS, image files, ads, beacons) that are fetched by a browser on page loads. Requests for these subresources can prompt browsers to perform further DNS lookups, TCP connections, and TLS handshakes, which can have a significant impact on how long it takes for the user to see the content and interact with the page. Further, each additional request exposes metadata (such as plaintext DNS queries, or unencrypted SNI in TLS handshake) which can have potential privacy implications for the user. With these factors in mind, we carried out a measurement study to understand how we can leverage <a href="https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/">Connection Coalescing</a> (aka <a href="https://datatracker.ietf.org/doc/html/rfc7540#section-9.1.1">Connection Reuse</a>) to address such concerns, and study its feasibility.</p>
    <div>
      <h3>Background</h3>
      <a href="#background">
        
      </a>
    </div>
    <p>The <a href="/http-3-from-root-to-tip/">web has come a long way</a> and initially consisted of very simple protocols. One of them was HTTP/1.0, which required browsers to make a separate connection for every subresource on the page. This design was quickly recognized as having significant performance bottlenecks and was extended with HTTP pipelining and persistent connections in <a href="https://datatracker.ietf.org/doc/html/rfc2616">HTTP/1.1 revision</a>, which allowed HTTP requests to reuse the same TCP connection. But, yet again, this was no silver bullet: while multiple requests could share the same connection, they still had to be serialized one after the other, so a client and server could only execute a single request/response exchange at any given time for each connection. As time passed, websites became more complex in structure and dynamic in nature, and HTTP/1.1 was identified as a major bottleneck. The only way to gain concurrency at the network layer was to use multiple TCP connections to the same origin in parallel, but this meant losing most benefits of persistent connections and ended up overloading the origin servers which were unable to meet the concurrency demand.</p><p>To address these performance limitations, the SPDY protocol was introduced over a decade later. SPDY supported stream multiplexing, where requests to and responses from the server used a single interleaved TCP connection, and allowed browsers to prioritize requests for critical subresources first — that were blocking page rendering. A modified variant of SPDY was standardized by the IETF as HTTP/2 in 2012 and published as <a href="https://datatracker.ietf.org/doc/html/rfc7540">RFC 7540</a> in 2015.</p><p>HTTP/2 and onwards retained this new standard for connection reuse. More specifically, all subresources on the same domain were able to reuse the same TCP/TLS (or UDP/QUIC) connection without any <a href="https://en.wikipedia.org/wiki/Head-of-line_blocking">head-of-line blocking</a> (at least on the application layer). This resulted in a single connection for all the subresources — reducing extraneous requests on page loads — potentially speeding up some websites and applications.</p><p>Interestingly, the protocol has a lesser-known feature to also enable subresources at <b><i>different</i></b><i> </i><b><i>hostnames</i></b> to be fetched over the <b><i>same</i></b> <b><i>connection</i></b>. We studied the real-world feasibility and benefits of this technique as an effort to improve users' experience for websites across our network.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3tmFcDGsMhGlSKQ3XxEzHs/a10aa68acabb9004a4a25bf82ba9ddc9/image16-1.png" />
            
            </figure><p>Connection Coalescing allows reusing a TLS connection across different domains</p>
    <div>
      <h3>Connection Coalescing</h3>
      <a href="#connection-coalescing">
        
      </a>
    </div>
    <p>The <i>technique</i> is often referred to as <a href="https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/">Connection Coalescing</a> and, to put it simply, is a way to access resources from <i>different hostnames that are accessible from the same web server</i>.</p><p>There are several reasons for why a single server could handle requests for different hosts, ranging from low-cost virtual hosting to the usage of <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/">CDNs</a> and cloud providers (including Cloudflare, that acts as a reverse proxy for approximately <a href="https://www.cloudflare.com/learning/what-is-cloudflare/">25 million Internet properties</a>). Before going into the technical conditions required to enable connection coalescing, we should take a look at some benefits such a strategy can provide.</p><ul><li><p><b>Privacy</b>. When resources at different hostnames are loaded via separate TLS connections, those connections expose metadata to ISPs and other observers via the Server Name Indicator (SNI) field about the destinations that are being contacted (i.e., in the absence of <a href="/esni/">encrypted SNI</a>). This set of exposed SNI’s can allow an on-path adversary to fingerprint traffic and possibly determine user interactions on the webpage. On the other hand, coalesced requests for more than one hostname on a single connection exposes only <b>one</b> destination, and helps avoid such threats.</p></li><li><p><b>Performance</b>. Additional TLS handshakes and TCP connections can incur significant <a href="/how-expensive-is-crypto-anyway/">costs in terms of cpu, memory and other resources</a>. Thus, coalescing requests to use the same connection can optimize resource utilization.</p></li><li><p><b>Resource Prioritization.</b> Multiplexing requests on a single connection means that applications have better visibility and more direct control over how related <a href="/better-http-2-prioritization-for-a-faster-web/">resources are prioritized and scheduled</a>. In the absence of coalescing, the network properties (for example, route congestion) can interfere with the intended order of delivery for resources. This reliability gained through connection coalescing opens up new optimization opportunities to improve web page load times, among other things.</p></li></ul><p>However, along with all these potential benefits, connection coalescing also has some associated risk factors that need to be considered in practice. First, TCP incorporates “fair” congestion control mechanisms — if there are ten connections on the same route, each gets approximately 1/10th of the total bandwidth. So with a route congested and bandwidth restricted, a client relying on <i>multiple connections</i> might be better off (for example, if they have five of the ten connections, their total share of bandwidth would be half). Second, browsers will use different parallelization routines for scheduling requests on multiple connections versus the same connection — it is not immediately clear whether the former or latter would perform better. Third, multiple connections exhibit an inherent form of load balancing for TLS-termination processes. That’s because multiple requests on the same connection must be answered by the same TLS-termination process that holds the session keys (often on the same physical server). So, it is important to study connection coalescing carefully before rolling it out widely.</p><p>With this context in mind, we studied the feasibility of connection coalescing on real-world traffic. More specifically, the two questions we wanted to answer were(a) can we empirically demonstrate and quantify the theoretical benefits of connection coalescing?, and (b) could coalescing cause unintended side effects, such as performance degradation, due to the risks highlighted above?</p><p>In order to answer these questions, we first made the observation that a large number of Cloudflare customers request subresources from <a href="/an-update-on-cdnjs/">cdnjs</a> — which is also powered by Cloudflare. For context, <a href="https://cdnjs.cloudflare.com/">cdnjs</a> has public JavaScript and CSS libraries (like <a href="https://jquery.com/">jQuery</a>), and is used by <a href="https://w3techs.com/technologies/details/cd-cdnjs"><i>more than 12%</i></a> <i>of all websites on the Internet</i>. One popular way these websites include resources from cdnjs is by using <code>&lt;script src="https://cdnjs.cloudflare.com/..." &gt;&lt;/script&gt;</code> HTML tags. But there are other ways as well, such as the usage of <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch</a> APIs. Regardless of the way these resources are included, browsers will need to fetch them for completely loading a website.</p><p>We then identified a list of approximately four thousand websites using Cloudflare (on the <a href="https://www.cloudflare.com/plans/free/">Free plan</a>) that likely used cdnjs. We divided this list of sites into evenly-sized and randomly-picked <i>control</i> and <i>experiment</i> groups. Our plan was to enable coalescing only for the <i>experiment</i> group, so that subresource requests generated from their web pages for cdnjs could reuse existing connections. In this way, we were able to compare results obtained on the <i>experiment</i> group, with the ones for the <i>control</i> group, and attribute any differences observed to connection coalescing.</p><p>In order to signal browsers that the requests can be coalesced, we served cdnjs and the sites from the same IP address in a few regions around the world. This meant the same DNS responses for all the zones that were part of the study — eventually load balanced by our Anycast network. These sites also had TLS certificates that included cdnjs.</p><p>The above two conditions (same IP and compatible certificate) are required to achieve coalescing as per the <a href="https://datatracker.ietf.org/doc/html/rfc7540#section-9.1.1">HTTP/2 spec</a>. However, the <a href="https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-29#section-3.4">QUIC spec</a> allows coalescing even if only the second condition is met. Major web browsers are <a href="https://mailarchive.ietf.org/arch/msg/quic/0nqKySdzmXK6CwZ9dKfD5GsQgqE/">yet to adopt the QUIC coalescing mechanism</a>, and currently use only the HTTP/2 coalescing logic for both protocols.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6qIQMnxndHLQGdhdmswsxg/da3ba47675985dd6ada032432a9de12e/image14-1.png" />
            
            </figure><p>Requests to Experiment Group Zones and cdnjs being coalesced on the same TLS connection</p>
    <div>
      <h3>Results</h3>
      <a href="#results">
        
      </a>
    </div>
    <p>We started noticing evidence of real-world coalescing from the day our experiment was launched. The following graph shows that approximately 50% of requests to cdnjs from our experiment group sites are coalesced (i.e., their TLS SNI does not equal cdnjs) as compared to 0% of requests from the control group sites.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/A3Z2xGpVTKtXr05t6Vzkd/4f259113d184d2d3b71786e65f805bb3/image2-21.png" />
            
            </figure><p>Coalesced Requests to cdnjs from Control and Experimental Group Zones</p><p>In addition, we conducted active measurements using our private <a href="https://webpagetest.org/">WebPageTest</a> instances at the landing pages of <i>experiment</i> and <i>control</i> sites — using the two well-supported browsers: Google Chrome and Firefox. From our results, Chrome created about 78% fewer TLS connections to cdnjs for our <i>experiment</i> group sites, as compared to the <i>control</i> group. But surprisingly, Firefox created just roughly 22% fewer connections. As TLS handshakes are computationally expensive because they involve cryptographic signatures and key exchange algorithms, fewer handshakes meant less CPU cycles spent by both the client and the server.</p><p>Upon further analysis, we were able to make two observations from the data:</p><ul><li><p>A fraction of sites that never coalesced connections with either browser appeared to load subresources with <a href="https://www.google.com/search?q=CORS&amp;rlz=1C5AVSZ_enUS817US817&amp;oq=CORS&amp;aqs=chrome..69i57j0i433i512j46i199i433i465i512j46i433i512j0i131i433i512j0i433i512j0i512j0i131i433i457j46i433i512j0i433i512.151j0j7&amp;sourceid=chrome&amp;ie=UTF-8">CORS</a> enabled (i.e., <code>&lt;script src="https://cdnjs.cloudflare.com/..." integrity="sha512-894Y..." **crossorigin="anonymous"**&gt;</code>). This is the default way cdnjs recommends inclusion of subresources, as CORS is needed for <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity">integrity checks</a> that provide substantial mitigations against script-manipulation attacks. We do not recommend removing this attribute. Our testing also revealed that using <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">Fetch</a> APIs to load subresources disabled coalescing as well. It is unclear why browsers choose to not coalesce such connections, and we are in contact with the vendors to find out.</p></li><li><p>Although both Firefox and Chrome coalesced requests for cdnjs on existing connections, the reason for the discrepancy in the number of TLS connections to cdnjs (approximately 78% vs roughly 22%) is because Firefox appears to open new connections even if it does not end up using them.</p></li></ul><p>After evaluating the potential benefits of coalescing, we wanted to understand if coalescing caused any unintended side effects. Hence, the final measurement we conducted was to check whether our experiments were detrimental to a website’s performance. We tracked <a href="/start-measuring-web-vitals-with-browser-insights/">Page Load Times (PLT) and Largest Contentful Paint (LCP)</a> across a variety of stimulated network conditions using both Chrome and Firefox and found the results for experiment vs control group to <i>not</i> be statistically significant.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3mqWfurrAFY6NrvUrO067u/1c55d30632a9bfff09d3592508d7f8e2/image3-19.png" />
            
            </figure><p>Page load times for control and experiment group sites. Each site was loaded once, and the “<i>fullyLoaded</i>” metric from WebPageTest is reported</p>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We consider our experimentation successful in determining the feasibility of connection coalescing and highlighting its potential benefits in terms of privacy and performance. More specifically, we observed the privacy benefits of coalescing in more than 50% of requests to cdnjs from real-world traffic. In addition, our active testing demonstrated that browsers create fewer TLS connections with coalescing enabled. Interestingly, our results also revealed that the benefits might not always occur (i.e., CORS-enabled requests, Firefox creating additional TLS connections despite coalescing). Finally, we did not find any evidence that coalescing can cause harm to real-world users’ experience on the Internet.</p><p>Some future directions we would like to explore include:</p><ul><li><p>More aggressive connection reuse with multiple hostnames, while identifying conditions most suitable for coalescing.</p></li><li><p>Understanding how different connection reuse methods compare, e.g., IP-based coalescing vs. use of <a href="https://datatracker.ietf.org/doc/html/rfc8336">Origin Frames</a>, and what effects do they have on user experience over the Internet.</p></li><li><p>Evaluating coalescing support among different browser vendors, and encouraging adoption of HTTP/3 QUIC based coalescing.</p></li><li><p>Reaping the full benefits of connection coalescing by experimenting with custom priority schemes for requests within the same connection.</p></li></ul><p>Please send questions and feedback to <a>ask-research@cloudflare.com</a>. We’re excited to continue this line of work in our effort to help build a better Internet! For those interested in joining our team please visit our <a href="https://www.cloudflare.com/careers/jobs/?department=Technology%20Research&amp;location=default">Careers Page</a>.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Browser Insights]]></category>
            <category><![CDATA[Better Internet]]></category>
            <category><![CDATA[CDNJS]]></category>
            <guid isPermaLink="false">3oUA8RgBt2s0bO1exBJegm</guid>
            <dc:creator>Talha Paracha</dc:creator>
            <dc:creator>Suleman Ahmad</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing SSL/TLS Recommender]]></title>
            <link>https://blog.cloudflare.com/ssl-tls-recommender/</link>
            <pubDate>Tue, 12 Oct 2021 13:01:00 GMT</pubDate>
            <description><![CDATA[ Introducing customized recommendations to improve the security of your website. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Seven years ago, Cloudflare made HTTPS availability for any Internet property easy and free with <a href="/introducing-universal-ssl/">Universal SSL</a>. At the time, few websites — other than those that processed sensitive data like passwords and credit card information — were using HTTPS because of how difficult it was to set up.</p><p>However, as we all started using the Internet for more and more private purposes (communication with loved ones, financial transactions, shopping, healthcare, etc.) the need for encryption became apparent. Tools like <a href="https://en.wikipedia.org/wiki/Firesheep">Firesheep</a> demonstrated how easily attackers could snoop on people using public Wi-Fi networks at coffee shops and airports. The <a href="https://blog.cryptographyengineering.com/2019/09/24/looking-back-at-the-snowden-revelations/">Snowden revelations</a> showed the ease with which governments could listen in on unencrypted communications at scale. We have seen attempts by browser vendors to increase HTTPS adoption such as the <a href="https://blog.chromium.org/2021/07/increasing-https-adoption.html">recent announcement by Chromium</a> for loading websites on HTTPS by default. Encryption has become a vital part of the modern Internet, not just to keep your information safe, but to keep you safe.</p><p>When it was launched, Universal SSL <a href="/introducing-universal-ssl/">doubled</a> the number of sites on the Internet using HTTPS. We are building on that with <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-tls-recommender">SSL/TLS Recommender</a>, a tool that guides you to stronger configurations for the backend connection from Cloudflare to origin servers. Recommender has been available in the SSL/TLS tab of the Cloudflare dashboard since August 2020 for self-serve customers. Over 500,000 zones are currently signed up. <b>As of today, it is available for all customers!</b></p>
    <div>
      <h2>How Cloudflare connects to origin servers</h2>
      <a href="#how-cloudflare-connects-to-origin-servers">
        
      </a>
    </div>
    <p>Cloudflare operates as a reverse proxy between clients (“visitors”) and customers’ web servers (“origins”), so that Cloudflare can protect origin sites from attacks and improve site performance. This happens, in part, because visitor requests to websites proxied by Cloudflare are processed by an “edge” server located in a data center close to the client. The edge server either responds directly back to the visitor, if the requested content is cached, or creates a new request to the origin server to retrieve the content.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/oClT8gZN3TtQjhYiJr464/642f9cba63b4f5489ed8d60274238e3c/image6-12.png" />
            
            </figure><p>The backend connection to the origin can be made with an unencrypted HTTP connection or with an HTTPS connection where requests and responses are encrypted using the <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/">TLS</a> protocol (historically known as <a href="https://www.cloudflare.com/learning/ssl/what-is-ssl/">SSL</a>). HTTPS is the secured form of HTTP and should be used <a href="https://www.cloudflare.com/learning/ssl/why-is-http-not-secure/">whenever possible</a> to avoid leaking information or allowing content tampering by third-party entities. The origin server can further authenticate itself by presenting a valid <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a> to prevent active <a href="/monsters-in-the-middleboxes/">monster-in-the-middle</a> attacks. Such a certificate can be obtained from a certificate authority such as <a href="https://letsencrypt.org/">Let’s Encrypt</a> or <a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca">Cloudflare’s Origin CA</a>. Origins can also set up <a href="https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull">authenticated origin pull</a>, which ensures that any HTTPS requests outside of Cloudflare will not receive a response from your origin.</p><p><a href="/tunnel-for-everyone/">Cloudflare Tunnel</a> provides an even more secure option for the connection between Cloudflare and origins. With Tunnel, users run a lightweight daemon on their origin servers that proactively establishes secure and private tunnels to the nearest Cloudflare data centers. With this configuration, users can completely lock down their origin servers to only receive requests routed through Cloudflare. While we encourage customers to set up tunnels if feasible, it's important to encourage origins with more traditional configurations to adopt the strongest possible security posture.</p>
    <div>
      <h3>Detecting HTTPS support</h3>
      <a href="#detecting-https-support">
        
      </a>
    </div>
    <p>You might wonder, why doesn’t Cloudflare always connect to origin servers with a secure TLS connection? To start, some origin servers have no TLS support at all (for example, certain <a href="https://community.letsencrypt.org/t/web-hosting-who-support-lets-encrypt/6920">shared hosting providers</a> and even <a href="https://kurti.sh/pubs/IMC_2020___Long_Tail_of_the_Internet.pdf">government sites</a> have been slow adopters) and rely on Cloudflare to ensure that the client request is at least encrypted over the Internet from the browser to Cloudflare’s edge.</p><p>Then why don’t we simply probe the origin to determine if TLS is supported? It turns out that many sites only <i>partially</i> support HTTPS, making the problem non-trivial. A single customer site can be served from multiple separate origin servers with differing levels of TLS support. For instance, some sites support HTTPS on their landing page but serve certain resources only over unencrypted HTTP. Further, site content can differ when accessed over HTTP versus HTTPS (for example, <a href="http://example.com">http://example.com</a> and <a href="https://example.com">https://example.com</a> can return different results).</p><p>Such content differences can arise due to misconfiguration on the origin server, accidental mistakes by developers when migrating their servers to HTTPS, or can even be intentional depending on the use case.</p><p>A <a href="https://www.cs.umd.edu/~dml/papers/https_tma20.pdf">study</a> by researchers at Northeastern University, the Max Planck Institute for Informatics, and the University of Maryland highlights reasons for some of these inconsistencies. They found that 1.5% of surveyed sites had at least one page that was unavailable over HTTPS — despite the protocol being supported on other pages — and 3.7% of sites served different content over HTTP versus HTTPS for at least one page. Thus, always using the most secure TLS setting detected on a particular resource could result in unforeseen side effects and usability issues for the entire site.</p><p>We wanted to tackle all such issues and maximize the number of TLS connections to origin servers, but without compromising a website’s functionality and performance.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/J0sdbGlU6cKVkaWJaR6nC/d98d243ee7d890676ba86a41a85d4d74/Screenshot-2021-10-11-at-16.17.39.png" />
            
            </figure><p>Content differences on sites when loaded over HTTPS vs HTTP; images taken from <a href="https://www.cs.umd.edu/~dml/papers/https_tma20.pdf">https://www.cs.umd.edu/~dml/papers/https_tma20.pdf</a> with author permission</p>
    <div>
      <h3>Configuring the SSL/TLS encryption mode</h3>
      <a href="#configuring-the-ssl-tls-encryption-mode">
        
      </a>
    </div>
    <p>Cloudflare relies on customers to indicate the level of TLS support at their origins via the zone’s <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes">SSL/TLS encryption mode</a>. The following SSL/TLS encryption modes can be configured from the Cloudflare dashboard:</p><ul><li><p><b>Off</b> indicates that client requests reaching Cloudflare as well as Cloudflare’s requests to the origin server should only use unencrypted HTTP. This option is never recommended, but is still in use by a handful of customers for legacy reasons or testing.</p></li><li><p><b>Flexible</b> allows clients to connect to Cloudflare’s edge via HTTPS, but requests to the origin are over HTTP only. This is the most common option for origins that do not support TLS. However, we encourage customers to upgrade their origins to support TLS whenever possible and only use <b>Flexible</b> as a <b>last resort</b>.</p></li><li><p><b>Full</b> enables encryption for requests to the origin when clients connect via HTTPS, but Cloudflare <i>does not attempt to validate the certificate</i>. This is useful for origins that have a self-signed or otherwise invalid certificate at the origin, but leaves open the possibility for an active attacker to impersonate the origin server with a fake certificate. Client HTTP requests result in HTTP requests to the origin.</p></li><li><p><b>Full (strict)</b> indicates that Cloudflare should validate the origin certificate to fully secure the connection. The origin certificate can either be issued by a public CA or by <a href="https://developers.cloudflare.com/ssl/origin-configuration/origin-ca">Cloudflare Origin CA</a>. HTTP requests from clients result in HTTP requests to the origin, exactly the same as in <b>Full</b> mode. We <b>strongly</b> recommend <b>Full (strict)</b> over weaker options if supported by the origin.</p></li><li><p><b>Strict (SSL-Only Origin Pull)</b> causes all traffic to the origin to go over HTTPS, even if the client request was HTTP. This differs from <b>Full (strict)</b> in that HTTP client requests will result in an <i>HTTPS</i> request to the origin, not HTTP. Most customers do not need to use this option, and it is available only to Enterprise customers. The preferred way to ensure that no HTTP requests reach your origin is to enable <a href="/how-to-make-your-site-https-only/">Always Use HTTPS</a> in conjunction with <b>Full</b> or <b>Full (strict)</b> to redirect visitor HTTP requests to the HTTPS version of the content.</p></li></ul>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6aX0Vn2QoaVooEamreEEha/0d8e29a895c9409b2ba7a3fd7bfb950f/image3-17.png" />
            
            </figure><p>SSL/TLS encryption modes determine how Cloudflare connects to origins</p><p>The SSL/TLS encryption mode is a zone-wide setting, meaning that Cloudflare applies the same policy to all subdomains and resources. If required, you can configure this setting more granularly via <a href="https://support.cloudflare.com/hc/en-us/articles/218411427-Understanding-and-Configuring-Cloudflare-Page-Rules-Page-Rules-Tutorial-">Page Rules</a>. Misconfiguring this setting can make site resources unavailable. For instance, suppose your website loads certain assets from an HTTP-only subdomain. If you set your zone to <b>Full</b> or <b>Full (strict)</b>, you might make these assets unavailable for visitors that request the content over HTTPS, since the HTTP-only subdomain lacks HTTPS support.</p>
    <div>
      <h3>Importance of secure origin connections</h3>
      <a href="#importance-of-secure-origin-connections">
        
      </a>
    </div>
    <p>When an end-user visits a site proxied by Cloudflare, there are two connections to consider: the front-end connection between the visitor and Cloudflare and the back-end connection between Cloudflare and the customer origin server. The front-end connection typically presents the largest attack surface (for example, think of the classic example of an attacker snooping on a coffee shop’s Wi-Fi network), but securing the back-end connection is equally important. While all SSL/TLS encryption modes (except <b>Off</b>) secure the front-end connection, less secure modes leave open the possibility of malicious activity on the backend.</p><p>Consider a zone set to <b>Flexible</b> where the origin is connected to the Internet via an untrustworthy ISP. In this case, spyware deployed by the customer’s ISP in an on-path middlebox could inspect the plaintext traffic from Cloudflare to the origin server, potentially resulting in privacy violations or leaks of confidential information. Upgrading the zone to <b>Full</b> or a stronger mode to encrypt traffic to the ISP would help prevent this basic form of snooping.</p><p>Similarly, consider a zone set to <b>Full</b> where the origin server is hosted in a shared hosting provider facility. An attacker colocated in the same facility could generate a fake certificate for the origin (since the certificate isn’t validated for <b>Full</b>) and deploy an attack technique such as <a href="https://en.wikipedia.org/wiki/ARP_spoofing">ARP spoofing</a> to direct traffic intended for the origin server to an attacker-owned machine instead. The attacker could then leverage this setup to inspect and filter traffic intended for the origin, resulting in site breakage or content unavailability. The attacker could even inject malicious JavaScript into the response served to the visitor to carry out other nefarious goals. Deploying a valid Cloudflare-trusted certificate on the origin and configuring the zone to use <b>Full (strict)</b> would prevent Cloudflare from trusting the attacker’s fake certificate in this scenario, preventing the <a href="https://www.cloudflare.com/learning/dns/what-is-domain-hijacking/">hijack</a>.</p><p>Since a secure backend only improves your <a href="https://www.cloudflare.com/learning/security/how-to-secure-a-website/">website security</a>, we strongly encourage setting your zone to the highest possible SSL/TLS encryption mode whenever possible.</p>
    <div>
      <h3>Balancing functionality and security</h3>
      <a href="#balancing-functionality-and-security">
        
      </a>
    </div>
    <p>When Universal SSL was launched, Cloudflare’s goal was to get as many sites away from the status quo of HTTP as possible. To accomplish this, Cloudflare provisioned TLS certificates for all customer domains to secure the connection between the browser and the edge. Customer sites that did not already have TLS support were defaulted to <b>Flexible,</b> to preserve existing site functionality. Although <b>Flexible</b> is <b>not recommended</b> for most zones, we continue to support this option as some Cloudflare customers still rely on it for origins that do not yet support TLS. Disabling this option would make these sites unavailable. Currently, the default option for newly onboarded zones is <b>Full</b> if we detect a TLS certificate on the origin zone, and <b>Flexible</b> otherwise.</p><p>Further, the SSL/TLS encryption mode configured at the time of zone sign-up can become suboptimal as a site evolves. For example, a zone might switch to a hosting provider that supports origin certificate installation. An origin server that is able to serve all content over TLS should at least be on <b>Full</b>. An origin server that has a valid TLS certificate installed should use <b>Full (strict)</b> to ensure that communication between Cloudflare and the origin server is not susceptible to monster-in-the-middle attacks.</p><p>The Research team combined lessons from academia and our engineering efforts to make encryption easy, while ensuring the highest level of security possible for our customers. Because of that goal, we’re proud to introduce SSL/TLS Recommender.</p>
    <div>
      <h2>SSL/TLS Recommender</h2>
      <a href="#ssl-tls-recommender">
        
      </a>
    </div>
    <p>Cloudflare’s mission is to help build a better Internet, and that includes ensuring that requests from visitors to our customers’ sites are as secure as possible. To that end, we began by asking ourselves the following question: how can we detect when a customer is able to use a more secure SSL/TLS encryption mode without impacting site functionality?</p><p>To answer this question, we built the <a href="https://developers.cloudflare.com/ssl/origin-configuration/ssl-tls-recommender">SSL/TLS Recommender</a>. Customers can enable Recommender for a zone via the SSL/TLS tab of the Cloudflare dashboard. Using a zone’s currently configured SSL/TLS option as the baseline for expected site functionality, the Recommender performs a series of checks to determine if an upgrade is possible. If so, we email the zone owner with the recommendation. If a zone is currently misconfigured — for example, an HTTP-only origin configured on <b>Full</b> — Recommender will not recommend a downgrade.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3nc5iSzjUtxNTAjNF0g8Kz/619643b0edcc9019e001a551206efcc5/image9-8.png" />
            
            </figure><p>The checks that Recommender runs are determined by the site’s currently configured SSL/TLS option.</p><p>The simplest check is to determine if a customer can upgrade from <b>Full</b> to <b>Full (strict)</b>. In this case, all site resources are already served over HTTPS, so the check comprises a few simple tests of the validity of the TLS certificate for the domain and all subdomains (which can be on separate origin servers).</p><p>The check to determine if a customer can upgrade from <b>Off</b> or <b>Flexible</b> to <b>Full</b> is more complex. A site can be upgraded if all resources on the site are available over HTTPS and the content <i>matches</i> when served over HTTP versus HTTPS. Recommender carries out this check as follows:</p><ul><li><p>Crawl customer sites to collect links. For large sites where it is impractical to scan every link, Recommender tests only a subset of links (up to some threshold), leading to a trade-off between performance and potential false positives. Similarly, for sites where the crawl turns up an insufficient number of links, we augment our results with a sample of links from recent visitors requests to the zone to provide a high-confidence recommendation. The crawler uses the user agent <i>Cloudflare-SSLDetector</i> and has been added to Cloudflare’s list of <a href="https://developers.cloudflare.com/firewall/known-issues-and-faq#bots-currently-detected">known good bots</a>. Similar to <a href="https://developers.cloudflare.com/cache/about/always-online">other Cloudflare crawlers</a>, Recommender ignores robots.txt (except for rules explicitly targeting the crawler’s user agent) to avoid negatively impacting the accuracy of the recommendation.</p></li><li><p>Download the content of each link over both HTTP and HTTPS. Recommender makes only idempotent GET requests when scanning origin servers to avoid modifying server resource state.</p></li><li><p>Run a content similarity algorithm to determine if the content matches. The algorithm is adapted from a research paper called "<a href="https://www.cs.umd.edu/~dml/papers/https_tma20.pdf">A Deeper Look at Web Content Availability and Consistency over HTTP/S</a>" (TMA Conference 2020) and is designed to provide an accurate similarity score even for sites with dynamic content.</p></li></ul><p>Recommender is conservative with recommendations, erring on the side of maintaining current site functionality rather than risking breakage and usability issues. If a zone is non-functional, the zone owner blocks all types of bots, or if misconfigured SSL-specific Page Rules are applied to the zone, then Recommender will not be able to complete its scans and provide a recommendation. Therefore, it is not intended to resolve issues with website or domain functionality, but rather maximize your zone’s security when possible.</p><p>Please send questions and feedback to <a>ask-research@cloudflare.com</a>. We’re excited to continue this line of work to improve the security of customer origins!</p>
    <div>
      <h2>Mentions</h2>
      <a href="#mentions">
        
      </a>
    </div>
    <p>While this work is led by the Research team, we have been extremely privileged to get support from all across the company!</p><p>Special thanks to the incredible team of interns that contributed to SSL/TLS Recommender. Suleman Ahmad (now full-time), Talha Paracha, and Ananya Ghose built the current iteration of the project and Matthew Bernhard helped to lay the groundwork in a previous iteration of the project.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[SSL]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">6WBTTN7lG2fbQfdx6Z4eq8</guid>
            <dc:creator>Suleman Ahmad</dc:creator>
            <dc:creator>Talha Paracha</dc:creator>
            <dc:creator>Luke Valenta</dc:creator>
        </item>
    </channel>
</rss>