
<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>Wed, 15 Apr 2026 19:41:43 GMT</lastBuildDate>
        <item>
            <title><![CDATA[Async QUIC and HTTP/3 made easy: tokio-quiche is now open-source]]></title>
            <link>https://blog.cloudflare.com/async-quic-and-http-3-made-easy-tokio-quiche-is-now-open-source/</link>
            <pubDate>Thu, 06 Nov 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ We’re excited to announce the open sourcing of tokio-quiche, our async QUIC library built on quiche and tokio. Relied upon in our services such as iCloud Private Relay and our next-generation Oxy-based proxies, tokio-quiche handles millions of HTTP/3 requests per second with low latency and high throughput.  ]]></description>
            <content:encoded><![CDATA[ <p>A little over 6 years ago, we presented <a href="https://blog.cloudflare.com/enjoy-a-slice-of-quic-and-rust/"><u>quiche</u></a>, our open source QUIC implementation written in Rust. Today we’re announcing the open sourcing of <a href="https://crates.io/crates/tokio-quiche"><b><u>tokio-quiche</u></b></a>, our battle-tested, asynchronous QUIC library combining both <b>quiche</b> and the Rust <b>Tokio</b> async runtime. Powering Cloudflare’s Proxy B in Apple iCloud Private Relay and our next-generation <a href="https://blog.cloudflare.com/introducing-oxy/"><u>Oxy-based</u></a> proxies, <b>tokio-quiche</b> handles millions of HTTP/3 requests per second with low latency and high throughput. tokio-quiche also powers <a href="https://blog.cloudflare.com/zero-trust-warp-with-a-masque/"><u>Cloudflare Warp’s MASQUE</u></a> client, replacing our WireGuard tunnels with QUIC-based tunnels, and the async version of <a href="https://blog.cloudflare.com/h3i/"><u>h3i</u></a>.</p><p>quiche was developed as a <a href="https://sans-io.readthedocs.io/how-to-sans-io.html"><u>sans-io</u></a> library, meaning that it implements the state machine required to handle the QUIC transport protocol while not making any assumptions about how its user intends to perform IO. This means that, with enough elbow grease, anyone can write an IO integration with quiche! This entails <code>connect</code>ing or <code>listen</code>ing on a UDP socket, managing sending and receiving UDP datagrams on that socket while feeding all network information to quiche. Given we need this integration to be async, we’d have to do all this while integrating with an async Rust runtime. tokio-quiche does all of that for you, no grease required.</p>
    <div>
      <h3>Lowering the barrier to entry</h3>
      <a href="#lowering-the-barrier-to-entry">
        
      </a>
    </div>
    <p>Originally, tokio-quiche was only used as the core of <a href="https://blog.cloudflare.com/introducing-oxy/"><u>Oxy’s</u></a> HTTP/3 <i>server</i>. But the spark to create tokio-quiche as a standalone library was our need for a MASQUE-capable HTTP/3 <i>client</i>. Our Zero Trust and Privacy Teams need MASQUE clients to tunnel data through WARP and our Privacy Proxies respectively, and we wanted to use the same technology to build both the client and server.</p><p>We initially open-sourced quiche to share our memory-safe QUIC and HTTP/3 implementation with as many stakeholders as possible. Our focus at the time was a low-level, sans-io design that could integrate into many types of software and be deployed widely. We achieved this goal, with quiche deployed in many different clients and servers. However, integrating sans-io libraries into applications is an error-prone and time-consuming process. Our aim with tokio-quiche is to lower the barrier of entry by providing much of the needed code ourselves.</p><p>Cloudflare alone embracing HTTP/3 is not of much use if others wanting to interact with our products and systems don't also adopt it. Open sourcing tokio-quiche makes integration with our systems more straightforward, and helps propel the industry into the new standard of HTTP. By contributing tokio-quiche back to the Rust ecosystem, we hope to promote the development and usage of HTTP/3, QUIC and new privacy preserving technologies.</p><p>tokio-quiche has been used internally for some years now. This gave us time to refine and battle-test it, demonstrating that it can handle millions of RPS. tokio-quiche is <b>not intended</b> to be a standalone HTTP/3 client or server, but implements low-level protocols and allows for higher-level projects in the future. The README contains examples of <a href="https://github.com/cloudflare/quiche/tree/master/tokio-quiche#starting-an-http3-server"><u>server</u></a> and <a href="https://github.com/cloudflare/quiche/tree/master/tokio-quiche#sending-an-http3-request"><u>client</u></a> event loops.</p>
    <div>
      <h3>It’s actors all the way down</h3>
      <a href="#its-actors-all-the-way-down">
        
      </a>
    </div>
    <p><a href="https://tokio.rs/"><u>Tokio</u></a> is a wildly popular asynchronous Rust runtime. It efficiently manages, schedules and executes the billions of asynchronous tasks which run on our edge. We use Tokio <a href="https://blog.cloudflare.com/introducing-oxy/"><u>extensively</u></a> <a href="https://blog.cloudflare.com/pingora-open-source/"><u>at</u></a> <a href="https://blog.cloudflare.com/20-percent-internet-upgrade/"><u>Cloudflare</u></a>, so we decided to tightly integrate quiche with it – thus the name, tokio-quiche. Under the hood, tokio-quiche uses <i>actors</i> to drive different parts of the QUIC and HTTP/3 state machine. Actors are small tasks with internal state that usually use message passing over channels to communicate with the outside world.</p><p>The actor model is a great abstraction to use for async-ifying sans-io libraries due to the conceptual similarities between the two. Both actors and sans-io libraries have some kind of internal state which they want exclusive access to. They both usually interact with the outside world by sending and receiving  “messages”. quiche’s “messages” are really raw byte buffers which represent incoming and outgoing network data. One of tokio-quiche’s “messages” is the <code>Incoming</code> struct which describes incoming UDP packets. Due to these similarities, async-ifying a sans-io library means: awaiting new messages or IO, translating the messages or IO into something the sans-io library understands, advancing the internal state machine, translating the state machine’s output to a message or IO, and finally sending the message or IO. (For more discussion on actors with Tokio, make sure to take a look at Alice Rhyl’s <a href="https://ryhl.io/blog/actors-with-tokio/"><u>excellent blog post</u></a> on the topic.)</p><p>The primary actor in tokio-quiche is the IO loop actor, which moves packets between quiche and the socket. Since QUIC is a transport protocol, it can carry any application protocol you want. <a href="https://datatracker.ietf.org/doc/rfc9114/"><u>HTTP/3</u></a> is quite common, but <a href="https://datatracker.ietf.org/doc/rfc9250/"><u>DNS over QUIC</u></a> and the upcoming <a href="https://blog.cloudflare.com/moq/"><u>Media over QUIC</u></a> are other examples. There's even <a href="https://www.rfc-editor.org/rfc/rfc9308.html"><u>an RFC</u></a> to help you create your own QUIC application! tokio-quiche exposes the <code>ApplicationOverQuic </code>trait to abstract over application protocols. The trait abstracts over quiche’s methods and the underlying I/O, allowing you to focus on your application logic. For example, our HTTP/3 debug and test client, <a href="https://blog.cloudflare.com/h3i/"><u>h3i</u></a>, is powered by a client-focused, non-HTTP/3 <code>ApplicationOverQuic</code> implementation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6AOaumZTjtZkzdY1iJLVTZ/c958b6937c2e4a455f3b98b0389388fd/image2.png" />
          </figure><p><sup>Server Architecture Diagram</sup></p><p>tokio-quiche ships with an HTTP/3-focused <code>ApplicationOverQuic</code> called <code>H3Driver</code>. <code>H3Driver</code> hooks up quiche’s HTTP/3 module to this IO loop to provide the building blocks for an async HTTP/3 client or server. The driver turns quiche’s raw HTTP/3 events into higher-level events and asynchronous body data streams, allowing you to respond to them in kind. <code>H3Driver</code> is itself generic, exposing <code>ServerH3Driver</code> and <code>ClientH3Driver</code> variants that each stack additional behavior on top of the core driver’s events.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2zxI09AhiqrBSyk8fhcSnr/b78917274391ec855370e565985c7bfc/image4.png" />
          </figure><p><sup>Internal Data Flow</sup></p><p>Inside tokio-quiche, we spawn two important tasks that facilitate data movement from a socket to quiche. The first is the <code>InboundPacketRouter</code>, which owns the receiving half of the socket and routes inbound datagrams by their <a href="https://datatracker.ietf.org/doc/html/rfc9000#name-connection-id"><u>connection ID</u></a> (DCID) to a per-connection channel. The second task, the <code>IoWorker</code> actor, is the aforementioned IO loop and drives a single quiche <code>Connection</code>. It intersperses quiche calls with <code>ApplicationOverQuic</code> methods, ensuring you can inspect the connection before and after any IO interaction.</p><p>More blog posts on the creation of tokio-quiche are coming soon. We’ll discuss actor models and mutexes, UDP GRO and GSO, tokio task coop budgeting, and more.</p>
    <div>
      <h3>Next up: more on QUIC and beyond!</h3>
      <a href="#next-up-more-on-quic-and-beyond">
        
      </a>
    </div>
    <p>tokio-quiche is an important foundation for Cloudflare’s investment into the QUIC and HTTP/3 ecosystem for Tokio – but it is still only a building block with its own complexity. In the future, we plan to release the same easy-to-use HTTP client and server abstractions that power our Oxy proxies and WARP clients today. Stay tuned for more blog posts on QUIC and HTTP/3 at Cloudflare, including an open-source client for customers of our <a href="https://blog.cloudflare.com/privacy-edge-making-building-privacy-first-apps-easier/#privacy-preserving-proxying-built-into-applications"><u>Privacy Proxies</u></a> and a completely new service that’s handling millions of RPS with tokio-quiche!</p><p>For now, check out the <a href="https://crates.io/crates/tokio-quiche"><u>tokio-quiche crate</u></a> on crates.io and its <a href="https://github.com/cloudflare/quiche/tree/master/tokio-quiche"><u>source code</u></a> on GitHub to build your very own QUIC application. Could be a simple echo server, a DNS-over-QUIC client, a custom VPN, or even a fully-fledged HTTP server. Maybe you will beat us to the punch?</p> ]]></content:encoded>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[QUICHE]]></category>
            <category><![CDATA[Privacy]]></category>
            <guid isPermaLink="false">pDSjJ9E3DaqTAtPDR0VV7</guid>
            <dc:creator>Pedro Mendes</dc:creator>
            <dc:creator>Leo Blöcher</dc:creator>
            <dc:creator>Evan Rittenhouse</dc:creator>
            <dc:creator>Fisher Darling</dc:creator>
        </item>
        <item>
            <title><![CDATA[Defending QUIC from acknowledgement-based DDoS attacks]]></title>
            <link>https://blog.cloudflare.com/defending-quic-from-acknowledgement-based-ddos-attacks/</link>
            <pubDate>Wed, 29 Oct 2025 13:00:00 GMT</pubDate>
            <description><![CDATA[ We identified and patched two DDoS vulnerabilities in our QUIC implementation related to packet acknowledgements. Cloudflare customers were not affected. We examine the "Optimistic ACK" attack vector and our solution, which dynamically skips packet numbers to validate client behavior.  ]]></description>
            <content:encoded><![CDATA[ <p></p><p>On April 10th, 2025 12:10 UTC, a security researcher notified Cloudflare of two vulnerabilities (<a href="https://www.cve.org/CVERecord?id=CVE-2025-4820"><u>CVE-2025-4820</u></a> and <a href="https://www.cve.org/CVERecord?id=CVE-2025-4821"><u>CVE-2025-4821</u></a>) related to QUIC packet acknowledgement (ACK) handling, through our <a href="https://hackerone.com/cloudflare?type=team"><u>Public Bug Bounty</u></a> program. These were DDoS vulnerabilities in the <a href="https://github.com/cloudflare/quiche"><u>quiche</u></a> library, and Cloudflare services that use it. quiche is Cloudflare's open-source implementation of QUIC protocol, which is the transport protocol behind <a href="https://blog.cloudflare.com/http3-the-past-present-and-future/"><u>HTTP/3</u></a>.</p><p>Upon notification, Cloudflare engineers patched the affected infrastructure, and the researcher confirmed that the DDoS vector was mitigated. <b>Cloudflare’s investigation revealed no evidence that the vulnerabilities were being exploited or that any customers were affected.</b> quiche versions prior to 0.24.4 were affected.</p><p>Here, we’ll explain why ACKs are important to Internet protocol design and how they help ensure fair network usage. Finally, we will explain the vulnerabilities and discuss our mitigation for the Optimistic ACK attack: a dynamic CWND-aware skip frequency that scales with a connection’s send rate.</p>
    <div>
      <h3>Internet Protocols and Attack Vectors</h3>
      <a href="#internet-protocols-and-attack-vectors">
        
      </a>
    </div>
    <p>QUIC is an Internet transport protocol that offers equivalent features to <a href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/"><u>TCP</u></a> (Transmission Control Protocol) and <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><u>TLS</u></a> (Transport Layer Security). QUIC runs over <a href="https://www.cloudflare.com/en-gb/learning/ddos/glossary/user-datagram-protocol-udp/"><u>UDP</u></a> (User Datagram Protocol), is encrypted by default and offers a few benefits over the prior set of protocols (including smaller handshake time, connection migration, and preventing <a href="https://en.wikipedia.org/wiki/Head-of-line_blocking"><u>head-of-line blocking</u></a> that can manifest in TCP). Similar to TCP, QUIC relies on packet acknowledgements to make general progress. For example, ACKs are used for liveliness checks, validation, loss recovery signals, and congestion algorithm signals.</p><p>ACKs are an important source of signals for Internet protocols, which necessitates validation to ensure a malicious peer is not subverting these signals. Cloudflare's QUIC implementation, quiche, lacked ACK range validation, which meant a peer could send an ACK range for packets never sent by the endpoint; this was patched in <a href="https://www.cve.org/CVERecord?id=CVE-2025-4821"><u>CVE-2025-4821</u></a>. Additionally, a sophisticated attacker could  mount an attack by predicting and preemptively sending ACKs (a technique called Optimistic ACK); this was patched in <a href="https://www.cve.org/CVERecord?id=CVE-2025-4820"><u>CVE-2025-4820</u></a>. By exploiting the lack of ACK validation, an attacker can cause an endpoint to artificially expand its send rate; thereby gaining an unfair advantage over other connections. In the extreme case this can be a DDoS attack vector caused by higher server CPU utilization and an amplification of network traffic.</p>
    <div>
      <h3>Fairness and Congestion control</h3>
      <a href="#fairness-and-congestion-control">
        
      </a>
    </div>
    <p>A typical CDN setup includes hundreds of server processes, serving thousands of concurrent connections. Each connection has its own recovery and congestion control algorithm that is responsible for determining its fair share of the network. The Internet is a shared resource that relies on well-behaved transport protocols correctly implementing congestion control to ensure fairness.</p><p>To illustrate the point, let’s consider a shared network where the first connection (blue) is operating at capacity. When a new connection (green) joins and probes for capacity, it will trigger packet loss, thereby signaling the blue connection to reduce its send rate. The probing can be highly dynamic and although convergence might take time, the hope is that both connections end up sharing equal capacity on the network.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/44jjkcx22rpD7VdnZKsnPD/4d514e73c885a729bd973b3efb2564bf/image4.jpg" />
          </figure><p><sup>New connection joining the shared network. Existing flows make room for the new flow.</sup></p><p>In order to ensure fairness and performance, each endpoint uses a <a href="http://blog.cloudflare.com/cubic-and-hystart-support-in-quiche/"><u>Congestion Control</u></a> algorithm. There are various algorithms but for our purposes let's consider <a href="https://www.rfc-editor.org/rfc/rfc9438.html"><u>Cubic</u></a>, a loss-based algorithm. Cubic, when in steady state, periodically explores higher sending rates. As the peer ACKs new packets, Cubic unlocks additional sending capacity (congestion window) to explore even higher send rates. Cubic continues to increase its send rate until it detects congestion signals (e.g., packet loss), indicating that the network is potentially at capacity and the connection should lower its sending rate.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5FvyfLs39CrWnHv8JjiJkd/d44cc31229e4dafa062d607c4214cba0/image6.png" />
          </figure><p><sup>Cubic congestion control responding to loss on the network.</sup></p>
    <div>
      <h3>The role of ACKs</h3>
      <a href="#the-role-of-acks">
        
      </a>
    </div>
    <p>ACKs are a feedback mechanism that Internet protocols use to make progress. A server serving a large file download will send that data across multiple packets to the client. Since networks are lossy, the client is responsible for ACKing when it has received a packet from the server, thus confirming delivery and progress. Lack of an ACK indicates that the packet has been lost and that the data might require retransmission. This feedback allows the server to confirm when the client has received all the data that it requested.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1LMkCz6BB4aUav8pVhM1Mb/30f94cdaa857a08af3b8c0b9bb24de91/Screenshot_2025-10-28_at_15.23.05.png" />
          </figure><p><sup>The server delivers packets and the client responds with ACKs.</sup></p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3Sa33xjYHj52KZZTL4ITWv/d0347affc68318b36da988331c55fd6c/Screenshot_2025-10-28_at_15.23.38.png" />
          </figure><p><sup>The server delivers packets, but packet [2] is lost. The client responds with ACKs only for packets [1, 3], thereby signalling that packet [2] was lost.</sup></p><p>In QUIC, packet numbers don't have to be sequential; that means skipping packet numbers is natively supported. Additionally, a <a href="https://www.rfc-editor.org/rfc/rfc9000.html#name-ack-frames"><u>QUIC ACK Frame</u></a> can contain gaps and multiple ACK ranges. As we will see, the built-in support for skipping packet numbers is a unique feature of QUIC (over TCP) that will help us enforce ACK validation.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2azePr06Z0kGVQwdEaaqbx/5ab6844b4d515444393ab0b8ca33bf1d/Screenshot_2025-10-28_at_15.25.05.png" />
          </figure><p><sup>The server delivering packets, but skipping packet [4]. The client responds with ACKs only for packets it received, and not sending an ACK for packet [4].</sup></p><p>ACKs also provide signals that control an endpoint's send rate and help provide fairness and performance. Delay between ACKs, variations in the delay, and lack of ACKs provide valuable signals, which suggest a change in the network and are important inputs to a congestion control algorithm.</p>
    <div>
      <h3>Skipping packets to avoid ACK delay</h3>
      <a href="#skipping-packets-to-avoid-ack-delay">
        
      </a>
    </div>
    <p>QUIC allows endpoints to encode the ACK delay: the time by which the ACK for packet number 'X' was intentionally delayed from when the endpoint received packet number 'X.' This delay can result from normal packet processing or be an implementation-specific optimization. For example, since ACKs processing can be expensive (both for CPU and network), delaying ACKs can allow for batching and reducing the associated overhead.</p><blockquote><p>If the sender wants to elicit a faster acknowledgement on PTO, it can skip a packet number to eliminate the acknowledgement delay. -- <a href="https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.4">https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.4</a></p></blockquote><p>However, since a delay in ACK signal also delays peer feedback, this can be detrimental for loss recovery. QUIC endpoints can therefore signal the peer to avoid delaying an ACK packet by skipping a packet number. This detail will become important as we will see later in the post.</p>
    <div>
      <h3>Validating ACK range</h3>
      <a href="#validating-ack-range">
        
      </a>
    </div>
    <p>It is expected that a well-behaved client should only send ACKs for packets that it has received. A lack of validation meant that it was possible for the client to send a very large ACK range for packets never sent by the server. For example, assuming the server has sent packets 0-5, a client was able to send an ACK Frame with the range 0-100.</p><p>By itself this is not actually a huge deal since quiche is smart enough to drop larger ACKs and only process ACKs for packets it has sent. However, as we will see in the next section, this made the Optimistic ACK vulnerability easier to exploit.</p><p>The fix was to enforce ACK range validation based on the largest packets sent by the server and close the connection on violation. This matches the RFC recommendation.</p><blockquote><p>An endpoint SHOULD treat receipt of an acknowledgment for a packet it did not send as a connection error of type PROTOCOL_VIOLATION, if it is able to detect the condition. -- <a href="https://www.rfc-editor.org/rfc/rfc9000#section-13.1">https://www.rfc-editor.org/rfc/rfc9000#section-13.1</a></p></blockquote>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/aPajmSD1NWaWvFv2aXAhs/480054b6514f3a1ddad219e4e81388f5/Screenshot_2025-10-28_at_15.26.15.png" />
          </figure><p><sup>The server validating ACKs: the client sending ACK for packets [4..5] not sent by the server. The server closes the connection since ACK validation fails.</sup></p>
    <div>
      <h3>Optimistic ACK attack</h3>
      <a href="#optimistic-ack-attack">
        
      </a>
    </div>
    <p>In the following scenario, let’s assume the client is trying to mount an Optimistic ACK attack against the server. The goal of a client mounting the attack is to cause the server to send at a high rate. To achieve a high send rate, the client needs to deliver ACKs quickly back to the server, thereby providing an artificially low <a href="https://www.cloudflare.com/learning/cdn/glossary/round-trip-time-rtt/"><u>RTT</u></a> / high bandwidth signal. Since packet numbers are typically monotonically increasing, a clever client can predict the next packet number and preemptively send ACKs (artificial ACK).</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2xCY6yXFysB3yPxfa4TjOb/962a74feaf95e520abf037bd12e19db7/Screenshot_2025-10-28_at_15.28.39.png" />
          </figure><p><sup>Optimistic ACK attack: the client predicting packets sent by the server and preemptively sending ACKs. ACK validation does not help here.</sup></p><p>If the server has proper ACK validation, an invalid ACK for packets not yet sent by the server should trigger a connection close (without ACK range validation, the attack is trivial to execute). Therefore, a malicious client needs to be clever about pacing the artificial ACKs so they arrive just as the server has sent the packet. If the attack is done correctly, the server will see a very low RTT, and result in an inflated send rate.</p><blockquote><p>An endpoint that acknowledges packets it has not received might cause a congestion controller to permit sending at rates beyond what the network supports. An endpoint MAY skip packet numbers when sending packets to detect this behavior. An endpoint can then immediately close the connection with a connection error of type PROTOCOL_VIOLATION -- <a href="https://www.rfc-editor.org/rfc/rfc9000#section-21.4">https://www.rfc-editor.org/rfc/rfc9000#section-21.4</a></p></blockquote>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2fppvXzvdTOugNzCtxgiH5/897da7f980f1de95bdafa1aee423dcf2/Screenshot_2025-10-28_at_15.40.37.png" />
          </figure><p><sup>Preventing an Optimistic ACK attack: the client predicting packets sent by the server and preemptively sending ACKs. Since the server skipped packet [4], it is able to detect the invalid ACK and close the connection.</sup></p><p>The <a href="https://www.rfc-editor.org/rfc/rfc9000#section-21.4"><u>QUIC RFC</u></a> mentions the Optimistic ACK attack and suggests skipping packets to detect this attack. By skipping packets, the client is unable to easily predict the next packet number and risks connection close if the server implements invalid ACK range validation. Implementation details – like how many packet numbers to skip and how often – are missing, however.</p><p>The [malicious] client transmission pattern does not indicate any malicious behavior.</p><blockquote><p>As such, the bit rate towards the server follows normal behavior. Considering that QUIC packets are end-to-end encrypted, a middlebox cannot identify the attack by analyzing the client’s traffic. -- <a href="https://louisna.github.io/files/2025-anrw-oack.pdf">MAY is not enough! QUIC servers SHOULD skip packet numbers</a></p></blockquote><p>Ideally, the client would like to use as few resources as possible, while simultaneously causing the server to use as many as possible. In fact, as the security researchers confirmed in their paper: it is difficult to detect a malicious QUIC client using external traffic analysis, and it’s therefore necessary for QUIC implementations to mitigate the Optimistic ACK attack by skipping packets.</p><p>The Optimistic ACK vulnerability is not unique to QUIC. In fact the vulnerability was first discovered against TCP. However, since TCP does not natively support skipping packet numbers, an Optimistic ACK attack in TCP is harder to mitigate and can require additional DDoS analysis. By allowing for packet skipping, QUIC is able to prevent this type of attack at the protocol layer and more effectively ensure correctness and fairness over untrusted networks.</p>
    <div>
      <h3>How often to skip packet numbers</h3>
      <a href="#how-often-to-skip-packet-numbers">
        
      </a>
    </div>
    <p>According to the QUIC RFC, skipping packet numbers currently has two purposes. The first is to elicit a faster acknowledgement for loss recovery and the second is to mitigate an Optimistic ACK attack. A QUIC implementation skipping packets for Optimistic ACK attack therefore needs to skip frequently enough to mitigate the attack, while considering the effects on eliminating ACK delay.</p><p>Since packet skipping needs to be unpredictable, a simple implementation could be to skip packet numbers based on a random number from a static range. However, since the number of packets increases as the send rate increases, this has the downside of not adapting to the send rate. At smaller send rates, a static range will be too frequent, while at higher send rates it won't be frequent enough and therefore be less effective. It's also arguably most important to validate the send rate when there are higher send rates. It therefore seems necessary to adapt the skip frequency based on the send rate.</p><p>Congestion window (CWND) is a parameter used by congestion control algorithms to determine the amount of bytes that can be sent per round. Since the send rate increases based on the amount of bytes ACKed (capped by bytes sent), we claim that CWND makes a great proxy for dynamically adjusting the skip frequency. This CWND-aware skip frequency allows all connections, regardless of current send rate, to effectively mitigate the Optimistic ACK attack.</p>
            <pre><code>// c: the current packet number
// s: range of random packet number to skip from
//
// curr_pn
//  |
//  v                 |--- (upper - lower) ---|
// [c x x x x x x x x s s s s s s s s s s s s s x x]
//    |--min_skip---| |------skip_range-------|

const DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS: usize = 10;
const MIN_SKIP_COUNTER_VALUE: u64 = DEFAULT_INITIAL_CONGESTION_WINDOW_PACKETS * 2;

let packets_per_cwnd = (cwnd / max_datagram_size) as u64;
let lower = packets_per_cwnd / 2;
let upper = packets_per_cwnd * 2;

let skip_range = upper - lower;
let rand_skip_value = rand(skip_range);

let skip_pn = MIN_SKIP_COUNTER_VALUE + lower + rand_skip_value;</code></pre>
            <p><sup>Skip frequency calculation in quiche.</sup></p>
    <div>
      <h3>Timeline</h3>
      <a href="#timeline">
        
      </a>
    </div>
    <p>All timestamps are in UTC.</p><ul><li><p>2025–04-10 12:10 - Cloudflare is notified of an ACK validation and Optimistic ACK vulnerability via the Bug Bounty Program.</p></li><li><p>2025-04-19 00:20 – Cloudflare confirms both vulnerabilities are reproducible and begins working on fix.</p></li><li><p>2025-05-02 20:12 - Security patch is complete and infrastructure patching starts.</p></li><li><p>2025–05-16 04:52 - Cloudflare infrastructure patching is complete.</p></li><li><p>New quiche version released.</p></li></ul>
    <div>
      <h3>Conclusion</h3>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>We would like to sincerely thank <a href="https://louisna.github.io/"><u>Louis Navarre</u></a> and <a href="https://perso.uclouvain.be/olivier.bonaventure/blog/html/pages/bio.html"><u>Olivier Bonaventure</u></a> from <a href="https://www.uclouvain.be/en"><u>UCLouvain</u></a>, who responsibly disclosed this issue via our <a href="https://www.cloudflare.com/en-gb/disclosure/"><u>Cloudflare Bug Bounty Program</u></a>, allowing us to identify and mitigate the vulnerability. They also published a <a href="https://louisna.github.io/publication/2025-anrw-oack"><u>paper</u></a> with their findings, notifying 10 other QUIC implementations that also suffered from the Optimistic ACK vulnerability. </p><p>We welcome further <a href="https://www.cloudflare.com/en-gb/disclosure/"><u>submissions</u></a> from our community of researchers to continually improve the security of all of our products and open source projects.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[QUIC]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Vulnerabilities]]></category>
            <category><![CDATA[Security]]></category>
            <guid isPermaLink="false">1vU4Xmgau85ysMJVxTEx09</guid>
            <dc:creator>Apoorv Kothari</dc:creator>
            <dc:creator>Louis Navarre (Guest author)</dc:creator>
        </item>
        <item>
            <title><![CDATA[Open sourcing h3i: a command line tool and library for low-level HTTP/3 testing and debugging]]></title>
            <link>https://blog.cloudflare.com/h3i/</link>
            <pubDate>Mon, 30 Dec 2024 14:00:00 GMT</pubDate>
            <description><![CDATA[ h3i is a command line tool and Rust library designed for low-level testing and debugging of HTTP/3, which runs over QUIC. ]]></description>
            <content:encoded><![CDATA[ <p>Have you ever built a piece of IKEA furniture, or put together a LEGO set, by following the instructions closely and only at the end realized at some point you didn't <i>quite</i> follow them correctly? The final result might be close to what was intended, but there's a nagging thought that maybe, just maybe, it's not as rock steady or functional as it could have been.</p><p>Internet protocol specifications are instructions designed for engineers to build things. Protocol designers take great care to ensure the documents they produce are clear. The standardization process gathers consensus and review from experts in the field, to further ensure document quality. Any reasonably skilled engineer should be able to take a specification and produce a performant, reliable, and secure implementation. The Internet is central to everyone's lives, and we depend on these implementations. Any deviations from the specification can put us at risk. For example, mishandling of malformed requests can allow attacks such as <a href="https://en.wikipedia.org/wiki/HTTP_request_smuggling"><u>request smuggling</u></a>.</p><p>h3i is a binary command line tool and Rust library designed for low-level testing and debugging of HTTP/3, which runs over QUIC. <a href="https://crates.io/crates/h3i"><u>h3i</u></a> is free and open source as part of Cloudflare's <a href="https://github.com/cloudflare/quiche"><u>quiche</u></a> project. In this post we'll explain the motivation behind developing h3i, how we use it to help develop robust and safe standards-compliant software and production systems, and how you can similarly use it to test your own software or services. If you just want to jump into how to use h3i, go to the <a href="#the-h3i-command-line-tool"><u>h3i command line tool</u></a> section.</p>
    <div>
      <h2>A recap of QUIC and HTTP/3</h2>
      <a href="#a-recap-of-quic-and-http-3">
        
      </a>
    </div>
    <p><a href="https://blog.cloudflare.com/http3-the-past-present-and-future/"><u>QUIC</u></a> is a secure-by-default transport protocol that provides performance advantages compared to TCP and TLS via a more efficient handshake, along with stream multiplexing that provides <a href="https://en.wikipedia.org/wiki/Head-of-line_blocking"><u>head-of-line blocking</u></a> avoidance. <a href="https://www.cloudflare.com/en-gb/learning/performance/what-is-http3/"><u>HTTP/3</u></a> is an application protocol that maps HTTP semantics to QUIC, such as defining how HTTP requests and responses are assigned to individual QUIC streams.</p><p>Cloudflare has supported QUIC on our global network in some shape or form <a href="https://blog.cloudflare.com/http3-the-past-present-and-future/"><u>since 2018</u></a>. We started while the <a href="https://ietf.org/"><u>Internet Engineering Task Force (IETF)</u></a> was earnestly standardizing the protocol, working through early iterations and using interoperability testing and experience to help provide feedback for the standards process. We <a href="https://blog.cloudflare.com/quic-version-1-is-live-on-cloudflare/"><u>launched support</u></a> for QUIC version 1 and HTTP/3 as soon as <a href="https://datatracker.ietf.org/doc/html/rfc9000"><u>RFC 9000</u></a> (and its accompanying specifications) were published in 2021.</p><p>We work on the Protocols team, who own the ingress proxy into the Cloudflare network. This is essentially Cloudflare’s “front door” — HTTP requests that come to Cloudflare from the Internet pass through us first. The majority of requests are passed onwards to things like rulesets, workers, caches, or a customer origin. However, you might be surprised that many requests don't ever make it that far because they are, in some way, invalid or malformed. Servers listening on the Internet have to be robust to traffic that is not RFC compliant, whether caused by accident or malicious intent.</p><p>The Protocols team actively participates in IETF standardization work and has also helped build and maintain other Cloudflare services that leverage quiche for QUIC and HTTP/3, from the proxies that help <a href="https://blog.cloudflare.com/icloud-private-relay/"><u>iCloud Private Relay</u></a> via <a href="https://blog.cloudflare.com/unlocking-quic-proxying-potential/"><u>MASQUE proxying</u></a>, to replacing <a href="https://blog.cloudflare.com/zero-trust-warp-with-a-masque/"><u>WARP's use of Wireguard with MASQUE</u></a>, and beyond.</p><p>Throughout all of these different use cases, it is important for us to extensively test all aspects of the protocols. A deep dive into protocol details is a blog post (or three) in its own right. So let's take a thin slice across HTTP to help illustrate the concepts.</p><p><a href="https://www.rfc-editor.org/rfc/rfc9110.html"><u>HTTP Semantics</u></a> are common to all versions of HTTP — the overall architecture, terminology, and protocol aspects such as request and response messages, methods, status codes, header and trailer fields, message content, and much more. Each individual HTTP version defines how semantics are transformed into a "wire format" for exchange over the Internet. You can read more about HTTP/1.1 and HTTP/2 in some of our previous <a href="https://blog.cloudflare.com/a-primer-on-proxies/"><u>blog</u></a> <a href="https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/"><u>posts</u></a>.</p><p>With HTTP/3, HTTP request and response messages are split into a series of binary frames. <a href="https://datatracker.ietf.org/doc/html/rfc9114#section-7.2.2"><u>HEADERS</u></a> frames carry a representation of HTTP metadata (method, path, status code, field lines). The payload of the frame is the encoded <a href="https://datatracker.ietf.org/doc/html/rfc9204"><u>QPACK</u></a> compression output. <a href="https://datatracker.ietf.org/doc/html/rfc9114#section-7.2.1"><u>DATA</u></a> frames carry <a href="https://datatracker.ietf.org/doc/html/rfc9110#section-6.4.1"><u>HTTP content</u></a> (aka "message body"). In order to exchange these frames, HTTP/3 relies on QUIC <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-2"><u>streams</u></a>. These provide an ordered and reliable byte stream and each have an identifier (ID) that is unique within the scope of a connection. There are <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-2.1"><u>four different stream types</u></a>, denominated by the two least significant bits of the ID.</p><p>As a simple example, assuming a QUIC connection has already been established, a client can make a GET request and receive a 200 OK response with an HTML body using the follow sequence:</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7vVfQ5CYaaVPVmGloRUnkI/88bd727c3526e540bd493bc15fbe904a/unnamed.png" />
          </figure><ol><li><p>Client allocates the first available client-initiated bidirectional QUIC stream. (The IDs start at 0, then 4, 8, 12 and so on)</p></li><li><p>Client sends the request HEADERS frame on the stream and sets the stream's <a href="https://datatracker.ietf.org/doc/html/rfc9000#section-19.8"><u>FIN bit</u></a> to mark the end of stream.</p></li><li><p>Server receives the request HEADERS frame and validates it against <a href="https://datatracker.ietf.org/doc/html/rfc9114#section-4.1.2"><u>RFC 9114 rules</u></a>. If accepted, it processes the request and prepares the response.</p></li><li><p>Server sends the response HEADERS frame on the same stream.</p></li><li><p>Server sends the response DATA frame on the same stream and sets the FIN bit.</p></li><li><p>Client receives the response frames and validates them. If accepted, the content is presented to the user.</p></li></ol><p>At the QUIC layer, stream data is split into STREAM frames, which are sent in QUIC packets over UDP. QUIC deals with any loss detection and recovery, helping to ensure stream data is reliable. The layer cake diagram below provides a handy comparison of how HTTP/1.1, HTTP/2 and HTTP/3 use TCP, UDP and IP.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4049UpKGn4BJcYcEXSFgWz/32143a5ba3672786639908ad96851225/image2.png" />
          </figure>
    <div>
      <h2>Background on testing QUIC and HTTP/3 at Cloudflare</h2>
      <a href="#background-on-testing-quic-and-http-3-at-cloudflare">
        
      </a>
    </div>
    <p>The Protocols team has a diverse set of automated test tools that exercise our ingress proxy software in order to ensure it can stand up to the deluge that the Internet can throw at it. Just like a bouncer at a nightclub front door, we need to prevent as much bad traffic as possible before it gets inside and potentially causes damage.</p><p>HTTP/2 and HTTP/3 share several concepts. When we started developing early HTTP/3 support, we'd already learned a lot from production experience with HTTP/2. While HTTP/2 addressed many issues with HTTP/1.1 (especially problems like <a href="https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf"><u>request smuggling</u></a>, caused by its ASCII-based message delineation), HTTP/2 also added complexity and new avenues for attack. Security is an ongoing process, and the Protocols team continually hardens our software and systems to threats. For example, mitigating the range of <a href="https://blog.cloudflare.com/on-the-recent-http-2-dos-attacks/"><u>denial-of-service attacks</u></a> identified by Netflix in 2019, or the <a href="https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/"><u>HTTP/2 Rapid Reset</u></a> attacks of 2023.</p><p>For testing HTTP/2, we rely on the Python <a href="https://pypi.org/project/requests/"><u>Requests</u></a> library for testing conventional HTTP exchanges. However, that mostly only exercises HEADERS and DATA frames. There are eight other frame types and a plethora of ways that they can interact (hence the new attack vectors mentioned above). In order to get full testing coverage, we have to break down into the lower layer <a href="https://pypi.org/project/h2/"><u>h2</u></a> library, which allows exact frame-by-frame control. However, even that is not always enough. Libraries tend to want to follow the RFC rules and prevent their users from doing "the wrong thing". This is entirely logical for most purposes. For our needs though, we need to take off the safety guards just like any potential attackers might do. We have a few cases where the best way to exercise certain traffic patterns is to handcraft HTTP/2 frames in a hex editor, store that as binary, and replay it with a tool such as <a href="https://docs.openssl.org/1.0.2/man1/s_client/"><u>OpenSSL s_client</u></a>.</p><p>We knew we'd need similar testing approaches for HTTP/3. However, when we started in 2018, there weren't many other suitable client implementations. The rate of iteration on the specifications also meant it was hard to always keep in sync. So we built tests on quiche, using a mix of our <a href="https://github.com/cloudflare/quiche/blob/master/apps/src/client.rs"><u>quiche-client</u></a> and <a href="https://github.com/cloudflare/quiche/tree/master/tools/http3_test"><u>http3_test</u></a>. Over time, the python library <a href="https://github.com/aiortc/aioquic"><u>aioquic</u></a> has matured, and we have used it to add a range of lower-layer tests that break or bend HTTP/3 rules, in order to prove our proxies are robust.</p><p>Finally, we would be remiss not to mention that all the tests in our ingress proxy are <b>in addition to </b>the suite of over 500 integration tests that run on the quiche project itself.</p>
    <div>
      <h2>Making HTTP/3 testing more accessible and maintainable with h3i</h2>
      <a href="#making-http-3-testing-more-accessible-and-maintainable-with-h3i">
        
      </a>
    </div>
    <p>While we are happy with the coverage of our current tests, the smorgasbord of test tools makes it hard to know what to reach for when adding new tests. For example, we've had cases where aioquic's safety guards prevent us from doing something, and it has needed a patch or workaround. This sort of thing requires a time investment just to debug/develop the tests.</p><p>We believe it shouldn't take a protocol or code expert to develop what are often very simple to describe tests. While it is important to provide guide rails for the majority of conventional use cases, it is also important to provide accessible methods for taking them off.</p><p>Let's consider a simple example. In HTTP/3 there is something called the control stream. It's used to exchange frames such as SETTINGS, which affect the HTTP/3 connection. RFC 9114 <a href="https://datatracker.ietf.org/doc/html/rfc9114#section-6.2.1"><u>Section 6.2.1</u></a> states:</p><blockquote><p><i>Each side MUST initiate a single control stream at the beginning of the connection and send its SETTINGS frame as the first frame on this stream. If the first frame of the control stream is any other frame type, this MUST be treated as a connection error of type H3_MISSING_SETTINGS. Only one control stream per peer is permitted; receipt of a second stream claiming to be a control stream MUST be treated as a connection error of type H3_STREAM_CREATION_ERROR. The sender MUST NOT close the control stream, and the receiver MUST NOT request that the sender close the control stream. If either control stream is closed at any point, this MUST be treated as a connection error of type H3_CLOSED_CRITICAL_STREAM. Connection errors are described in Section 8.</i></p></blockquote><p>There are many tests we can conjure up just from that paragraph:</p><ol><li><p>Send a non-SETTINGS frame as the first frame on the control stream.</p></li><li><p>Open two control streams.</p></li><li><p>Open a control stream and then close it with a FIN bit.</p></li><li><p>Open a control stream and then reset it with a RESET_STREAM QUIC frame.</p></li><li><p>Wait for the peer to open a control stream and then ask for it to be reset with a STOP_SENDING QUIC frame.</p></li></ol><p>All of the above actions should cause a remote peer that has implemented the RFC properly to close the connection. Therefore, it is not in the interest of the local client or server applications to ever do these actions.</p><p>Many QUIC and HTTP/3 implementations are developed as libraries that are integrated into client or server applications. There may be an extensive set of unit or integration tests of the library checking RFC rules. However, it is also important to run the same tests on the integrated assembly of library and application, since it's all too common that an unhandled/mishandled library error can cascade to cause issues in upper layers. For instance, the HTTP/2 Rapid Reset attacks affected Cloudflare due to their <a href="https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/#impact-on-customers"><u>impact on how one service spoke to another</u></a>.</p><p>We've developed h3i, a command line tool and library, to make testing more accessible and maintainable for all. We started with a client that can exercise servers, since that's what our focus has been. Future developments could support the opposite, a server that behaves in unusual ways in order to exercise clients.</p><p><b>Note: </b>h3i is <i>not</i> intended to be a production client! Its flexibility may cause issues that are not observed in other production-oriented clients. It is also not intended to be used for any type of performance testing and measurement.</p>
    <div>
      <h2>The h3i command line tool</h2>
      <a href="#the-h3i-command-line-tool">
        
      </a>
    </div>
    <p>The primary purpose of the h3i command line tool is quick low-level debugging and exploratory testing. Rather than worrying about writing code or a test script, users can quickly run an ad-hoc client test against a target, guided by interactive prompts.</p><p>In the simplest case, you can think of h3i a bit like <a href="https://curl.se/"><u>curl</u></a> but with access to some extra HTTP/3 parameters. In the example below, we issue a request to <a href="https://cloudflare-quic.com"><u>https://cloudflare-quic.com</u></a>/ and receive a response.</p><div>
  
</div><p>Walking through a simple GET with h3i step-by-step:</p><ol><li><p>Grab a copy of the h3i binary either by running <code>cargo install h3i</code> or cloning the quiche source repo at <a href="https://github.com/cloudflare/quiche/"><u>https://github.com/cloudflare/quiche/</u></a>. Both methods assume you have some familiarity with Rust and Cargo. See the cargo <a href="https://doc.rust-lang.org/book/ch14-04-installing-binaries.html"><u>documentation</u></a> for more information.</p><ol><li><p><code>cargo install</code> will place the binary on your path, so you can then just run it by executing <code>h3i</code>.</p></li><li><p>If running from source, navigate to the quiche/h3i directory and then use <code>cargo run</code>.</p></li></ol></li><li><p>Run the binary and provide the name and port of the target server. If the port is omitted, the default value 443 is assumed. E.g, <code>cargo run cloudflare-quic.com</code></p></li><li><p>h3i then enters the action prompting phase. A series of one or more HTTP/3 actions can be queued up, such as sending frames, opening or terminating streams, or waiting on data from the server. The full set of options is documented in the <a href="https://github.com/cloudflare/quiche/blob/master/h3i/README.md#command-line-tool"><u>readme</u></a>.</p><ol><li><p>The prompting interface adapts to keyboard inputs and supports tab completion.</p></li><li><p>In the example above, the <code>headers</code> action is selected, which walks through populating the fields in a HEADERS frame. It includes <a href="https://datatracker.ietf.org/doc/html/rfc9114#section-4.3.1"><u>mandatory fields</u></a> from RFC 9114 for convenience. If a test requires omitting these, the <code>headers_no_pseudo</code> can be used instead.</p></li></ol></li><li><p>The <code>commit</code> prompt choice finalizes the action list and moves to the connection phase. h3i initiates a QUIC connection to the server identified in step 2. Once connected, actions are executed in order.</p></li><li><p>By default, h3i reports some limited information about the frames the server sent. To get more detailed information, the <code>RUST_LOG</code> environment can be set with either <code>debug</code> or <code>trace</code> levels.</p></li></ol>
    <div>
      <h2>Instant record and replay, powered by qlog</h2>
      <a href="#instant-record-and-replay-powered-by-qlog">
        
      </a>
    </div>
    <p>It can be fun to play around with the h3i command line tool to see how different servers respond to different combinations or sequences of actions. Occasionally, you'll find a certain set that you want to run over and over again, or share with a friend or colleague. Having to manually enter the prompts repeatedly, or share screenshots of the h3i input can turn tedious. Fortunately, h3i records all the actions in a log file by default — the file path is printed immediately after h3i starts. The format of this file is based on <a href="https://datatracker.ietf.org/doc/html/draft-ietf-quic-qlog-main-schema"><u>qlog</u></a>, an in-progress standard in development at the IETF for network protocol logging. It’s a perfect fit for our low-level needs.</p><p>Here's an example h3i qlog file:</p>
            <pre><code>{"qlog_version":"0.3","qlog_format":"JSON-SEQ","title":"h3i","description":"h3i","trace":{"vantage_point":{"type":"client"},"title":"h3i","description":"h3i","configuration":{"time_offset":0.0}}}
{
  "time": 0.172783,
  "name": "http:frame_created",
  "data": {
    "stream_id": 0,
    "frame": {
      "frame_type": "headers",
      "headers": [
        {
          "name": ":method",
          "value": "GET"
        },
        {
          "name": ":authority",
          "value": "cloudflare-quic.com"
        },
        {
          "name": ":path",
          "value": "/"
        },
        {
          "name": ":scheme",
          "value": "https"
        },
        {
          "name": "user-agent",
          "value": "h3i"
        }
      ]
    }
  },
  "fin_stream": true
}</code></pre>
            <p>h3i logs can be replayed using the <code>--qlog-input</code> option. You can change the target server host and port, and keep all the same actions. However, most servers will validate the :authority pseudo-header or Host header contained in a HEADERS frame. The --replay-host-override option allows changing these fields without needing to modify the file by hand.</p><p>And yes, qlog files are human-readable text in the JSON-SEQ format. So you can also just write these by hand in the first place if you like! However, if you're going to start writing things, maybe Rust is your preferred option…</p>
    <div>
      <h2>Using the h3i library to send a malformed request with Rust</h2>
      <a href="#using-the-h3i-library-to-send-a-malformed-request-with-rust">
        
      </a>
    </div>
    <p>In our previous example, we just sent a valid request so there wasn't anything interesting to observe. Where h3i really shines is in generating traffic that isn't RFC compliant, such as malformed HTTP messages, invalid frame sequences, or other actions on streams. This helps determine if a server is acting robustly and defensively.</p><p>Let's explore this more with an example of HTTP content-length mismatch. RFC 9114 <a href="https://datatracker.ietf.org/doc/html/rfc9114#section-4.1.2"><u>section 4.1.2</u></a> specifies:</p><blockquote><p><i>A request or response that is defined as having content when it contains a Content-Length header field (Section 8.6 of [HTTP]) is malformed if the value of the Content-Length header field does not equal the sum of the DATA frame lengths received. A response that is defined as never having content, even when a Content-Length is present, can have a non-zero Content-Length header field even though no content is included in DATA frames.</i></p><p><i>Intermediaries that process HTTP requests or responses (i.e., any intermediary not acting as a tunnel) MUST NOT forward a malformed request or response. Malformed requests or responses that are detected MUST be treated as a stream error of type H3_MESSAGE_ERROR.</i></p><p><i>For malformed requests, a server MAY send an HTTP response indicating the error prior to closing or resetting the stream.</i></p></blockquote><p>There are good reasons that the RFC is so strict about handling mismatched content lengths. They can be a vector for <a href="https://portswigger.net/research/http2"><u>desynchronization attacks</u></a> (similar to request smuggling), especially when a proxy is converting inbound HTTP/3 to outbound HTTP/1.1.</p><p>We've provided an <a href="https://github.com/cloudflare/quiche/blob/master/h3i/examples/content_length_mismatch.rs"><u>example</u></a> of how to use the h3i Rust library to write a tailor-made test client that sends a mismatched content length request. It sends a Content-Length header of 5, but its body payload is “test”, which is only 4 bytes. It then waits for the server to respond, after which it explicitly closes the connection by sending a QUIC CONNECTION_CLOSE frame.</p><p>When running low-level tests, it can be interesting to also take a packet capture (<a href="https://en.wikipedia.org/wiki/Pcap"><u>pcap</u></a>) and observe what is happening on the wire. Since QUIC is an encrypted transport, we'll need to use the SSLKEYLOG environment variable to capture the session keys so that tools like Wireshark can <a href="https://wiki.wireshark.org/TLS#using-the-pre-master-secret"><u>decrypt and dissect</u></a>.</p><p>To follow along at home, clone a copy of the quiche repository, start a packet capture on the appropriate network interface and then run:</p>
            <pre><code>cd quiche/h3i
SSLKEYLOGFILE="h3i-example.keys" cargo run --example content_length_mismatch</code></pre>
            <p>In our decrypted capture, we see the expected sequence of handshake, request, response, and then closure.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6Qkdd3h0x826tH95S61u92/5de829e018b9d3ef409a2452362fa81e/image1.png" />
          </figure>
    <div>
      <h2>Surveying the example code</h2>
      <a href="#surveying-the-example-code">
        
      </a>
    </div>
    <p>The <a href="https://github.com/cloudflare/quiche/blob/master/h3i/examples/content_length_mismatch.rs"><u>example</u></a> is a simple binary app with a <code>main()</code> entry point. Let's survey the key elements.</p><p>First, we set up an h3i configuration to a target server:</p>
            <pre><code>let config = Config::new()
        .with_host_port("cloudflare-quic.com".to_string())
        .with_idle_timeout(2000)
        .build()
        .unwrap();</code></pre>
            <p>The idle timeout is a QUIC concept which tells each endpoint when it should close the connection if the connection has been idle. This prevents endpoints from spinning idly if the peer hasn’t closed the connection. h3i’s default is 30 seconds, which can be too long for tests, so we set ours to 2 seconds here.</p><p>Next, we define a set of request headers and encode them with QPACK compression, ready to put in a HEADERS frame. Note that h3i does provide a <a href="https://docs.rs/h3i/latest/h3i/actions/h3/fn.send_headers_frame.html"><u>send_headers_frame</u></a> helper method which does this for you, but the example does it manually for clarity:</p>
            <pre><code>let headers = vec![
        Header::new(b":method", b"POST"),
        Header::new(b":scheme", b"https"),
        Header::new(b":authority", b"cloudflare-quic.com"),
        Header::new(b":path", b"/"),
        // We say that we're going to send a body with 5 bytes...
        Header::new(b"content-length", b"5"),
    ];

    let header_block = encode_header_block(&amp;headers).unwrap();</code></pre>
            <p>Then, we define the set of h3i actions that we want to execute in order: send HEADERS, send a too-short DATA frame, wait for the server's HEADERS, then close the connection.</p>
            <pre><code>let actions = vec![
        Action::SendHeadersFrame {
            stream_id: STREAM_ID,
            fin_stream: false,
            headers,
            frame: Frame::Headers { header_block },
        },
        Action::SendFrame {
            stream_id: STREAM_ID,
            fin_stream: true,
            frame: Frame::Data {
                // ...but, in actuality, we only send 4 bytes. This should yield a
                // 400 Bad Request response from an RFC-compliant
                // server: https://datatracker.ietf.org/doc/html/rfc9114#section-4.1.2-3
                payload: b"test".to_vec(),
            },
        },
        Action::Wait {
            wait_type: WaitType::StreamEvent(StreamEvent {
                stream_id: STREAM_ID,
                event_type: StreamEventType::Headers,
            }),
        },
        Action::ConnectionClose {
            error: quiche::ConnectionError {
                is_app: true,
                error_code: quiche::h3::WireErrorCode::NoError as u64,
                reason: vec![],
            },
        },
    ];</code></pre>
            <p>Finally, we'll set things in motion with <code>connect()</code>, which sets up the QUIC connection, executes the actions list and collects the summary.</p>
            <pre><code>let summary =
        sync_client::connect(config, &amp;actions).expect("connection failed");

    println!(
        "=== received connection summary! ===\n\n{}",
        serde_json::to_string_pretty(&amp;summary).unwrap_or_else(|e| e.to_string())
    );</code></pre>
            <p><a href="https://docs.rs/h3i/latest/h3i/client/connection_summary/struct.ConnectionSummary.html"><u>ConnectionSummary</u></a>  provides data about the connection, including the frames h3i received, details about why the connection closed, and connection statistics. The example prints the summary out. However, you can programmatically check it. We do this to write our own internal automation tests.</p><p>If you're running the example, it should print something like the following:</p>
            <pre><code>=== received connection summary! ===

{
  "stream_map": {
    "0": [
      {
        "UNKNOWN": {
          "raw_type": 2471591231244749708,
          "payload": ""
        }
      },
      {
        "UNKNOWN": {
          "raw_type": 2031803309763646295,
          "payload": "4752454153452069732074686520776f7264"
        }
      },
      {
        "enriched_headers": {
          "header_block_len": 75,
          "headers": [
            {
              "name": ":status",
              "value": "400"
            },
            {
              "name": "server",
              "value": "cloudflare"
            },
            {
              "name": "date",
              "value": "Sat, 07 Dec 2024 00:34:12 GMT"
            },
            {
              "name": "content-type",
              "value": "text/html"
            },
            {
              "name": "content-length",
              "value": "155"
            },
            {
              "name": "cf-ray",
              "value": "8ee06dbe2923fa17-ORD"
            }
          ]
        }
      },
      {
        "DATA": {
          "payload_len": 104
        }
      },
      {
        "DATA": {
          "payload_len": 51
        }
      }
    ]
  },
  "stats": {
    "recv": 10,
    "sent": 5,
    "lost": 0,
    "retrans": 0,
    "sent_bytes": 1712,
    "recv_bytes": 4178,
    "lost_bytes": 0,
    "stream_retrans_bytes": 0,
    "paths_count": 1,
    "reset_stream_count_local": 0,
    "stopped_stream_count_local": 0,
    "reset_stream_count_remote": 0,
    "stopped_stream_count_remote": 0,
    "path_challenge_rx_count": 0
  },
  "path_stats": [
    {
      "local_addr": "0.0.0.0:64418",
      "peer_addr": "104.18.29.7:443",
      "active": true,
      "recv": 10,
      "sent": 5,
      "lost": 0,
      "retrans": 0,
      "rtt": 0.008140072,
      "min_rtt": 0.004645536,
      "rttvar": 0.004238173,
      "cwnd": 13500,
      "sent_bytes": 1712,
      "recv_bytes": 4178,
      "lost_bytes": 0,
      "stream_retrans_bytes": 0,
      "pmtu": 1350,
      "delivery_rate": 247720
    }
  ],
  "error": {
    "local_error": {
      "is_app": true,
      "error_code": 256,
      "reason": ""
    },
    "timed_out": false
  }
}
</code></pre>
            <p>Let’s walk through the output. Up first is the <a href="https://docs.rs/h3i/latest/h3i/client/connection_summary/struct.StreamMap.html"><u>StreamMap</u></a>, which is a record of all frames received on each stream. We can see that we received 5 frames on stream 0: 2 UNKNOWNs, one <a href="https://docs.rs/h3i/latest/h3i/frame/struct.EnrichedHeaders.html"><u>EnrichedHeaders</u></a> frame, and two DATA frames.</p><p>The UNKNOWN frames are extension frames that are unknown to h3i; the server under test is sending what are known as <a href="https://datatracker.ietf.org/doc/draft-edm-protocol-greasing/"><u>GREASE</u></a> frames to help exercise the protocol and ensure clients are not erroring when they receive something unexpected per <a href="https://datatracker.ietf.org/doc/html/rfc9114#extensions"><u>RFC 9114 requirements</u></a>.</p><p>The EnrichedHeaders frame is essentially an HTTP/3 HEADERS frame, but with some small helpers, like one to get the response status code. The server under test sent a 400 as expected.</p><p>The DATA frames carry response body bytes. In this case, the body is the HTML required to render the Cloudflare Bad Request page (you can peek at the HTML yourself in Wireshark). We chose to omit the raw bytes from the ConnectionSummary since they may not be representable safely as text. A future improvement could be to encode the bytes in base64 or hex, in order to support tests that need to check response content.</p>
    <div>
      <h2>h3i for test automation</h2>
      <a href="#h3i-for-test-automation">
        
      </a>
    </div>
    <p>We believe h3i is a great library for building automated tests on. You can take the above example and modify it to fit within various types of (continuous) integration tests.</p><p>We outlined earlier how the Protocols team HTTP/3 testing has organically grown to use three different frameworks. Even within those, we still didn't have much flexibility and ease of use. Over the last year we've been building h3i itself and reimplementing our suite of ingress proxy test cases using the Rust library. This has helped us improve test coverage with a range of new tests not previously possible. It also surprisingly identified some problems with the old tests, particularly for some edge cases where it wasn't clear how the old test code implementation was running under the hood.</p>
    <div>
      <h2>Bake offs, interop, and wider testing of HTTP</h2>
      <a href="#bake-offs-interop-and-wider-testing-of-http">
        
      </a>
    </div>
    <p><a href="https://datatracker.ietf.org/doc/html/rfc1025"><u>RFC 1025</u></a> was published in 1987. Authored by <a href="https://icannwiki.org/Jon_Postel"><u>Jon Postel</u></a>, it discusses bake offs:</p><blockquote><p><i>In the early days of the development of TCP and IP, when there were very few implementations and the specifications were still evolving, the only way to determine if an implementation was "correct" was to test it against other implementations and argue that the results showed your own implementation to have done the right thing.  These tests and discussions could, in those early days, as likely change the specification as change the implementation.</i></p><p><i>There were a few times when this testing was focused, bringing together all known implementations and running through a set of tests in hopes of demonstrating the N squared connectivity and correct implementation of the various tricky cases.  These events were called "Bake Offs".</i></p></blockquote><p>While nearly 4 decades old, the concept of exercising Internet protocol implementations and seeing how they compare to the specification still holds true. The QUIC WG made heavy use of interoperability testing through its standardization process. We started off sitting in a room and running tests manually by hand (or with some help from scripts). Then <a href="https://seemann.io/"><u>Marten Seemann</u></a> developed the <a href="https://interop.seemann.io/"><u>QUIC Interop Runner</u></a>, which runs regular automated testing and collects and renders all the results. This has proven to be incredibly useful.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2OGnVUbatoX8Ya2IO5RdCl/754316e004a8e658ac089e10e70b72ca/image6.png" />
          </figure><p>The state of HTTP/3 interoperability testing is not quite as mature. Although there are tools such as <a href="https://kazu-yamamoto.hatenablog.jp/"><u>Kazu Yamamoto's</u></a> excellent <a href="https://github.com/kazu-yamamoto/h3spec"><u>h3spec</u></a> (in Haskell) for testing conformance, there isn't a similar continuous integration process of collection and rendering of results. While h3i shares similarities with h3spec, we felt it important to focus on the framework capabilities rather than creating a corpus of tests and assertions. Cloudflare is a big fan of Rust and as several teams move to Rust-based proxies, having a consistent ecosystem provides advantages (such as developer velocity).</p><p>We certainly feel there is a great opportunity for continued collaboration and cross-pollination between projects in the QUIC and HTTP space. For example, h3i might provide a suitable basis to build another tool (or set of scripts) to run bake offs or interop tests. Perhaps it even makes sense to have a common collection of test cases owned by the community, that can be specialized to the most appropriate or preferred tooling. This topic was recently presented at the <a href="https://github.com/HTTPWorkshop/workshop2024/blob/main/talks/5.%20Testing/testing.pdf"><u>HTTP Workshop 2024</u></a> by Mohammed Al-Sahaf, and it excites us to see <a href="https://www.caffeinatedwonders.com/2024/12/18/towards-validated-http-implementation/"><u>new potential directions</u></a> of testing improvements.</p><p>When using any tools or methods for protocol testing, we encourage responsible handling of security-related matters. If you believe you may have identified a vulnerability in an IETF Internet protocol itself, please follow the IETF's <a href="https://www.ietf.org/standards/rfcs/vulnerabilities/"><u>reporting guidance</u></a>. If you believe you may have discovered an implementation vulnerability in a product, open source project, or service using QUIC or HTTP, then you should report these directly to the responsible party. Implementers or operators often provide their own publicly-available guidance and contact details to send reports. For example, the Cloudflare quiche <a href="https://github.com/cloudflare/quiche/security/policy"><u>security policy</u></a> is available in the Security tab of the GitHub repository.</p>
    <div>
      <h2>Summary and outlook</h2>
      <a href="#summary-and-outlook">
        
      </a>
    </div>
    <p>Cloudflare takes testing very seriously. While h3i has a limited feature set as a test HTTP/3 client, we believe it provides a strong framework that can be extended to a wider range of different cases and different protocols. For example, we'd like to add support for low-level HTTP/2.</p><p>We've designed h3i to integrate into a wide range of testing methodologies, from manual ad-hoc testing, to native Rust tests, to conformance testbenches built with scripting languages. We've had great success migrating our existing zoo of test tools to a single one that is more accessible and easier to maintain.</p><p>Now that you've read about h3i's capabilities, it's left as an exercise to the reader to go back to the example of HTTP/3 control streams and consider how you could write tests to exercise a server.</p><p>We encourage the community to experiment with h3i and provide feedback, and propose ideas or contributions to the <a href="https://github.com/cloudflare/quiche"><u>GitHub repository</u></a> as issues or Pull Requests.</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5rp4YDTbXm37OxK7dtjiKF/816c0eed08926b7d34842f4769808277/image4.png" />
          </figure><p></p> ]]></content:encoded>
            <category><![CDATA[QUIC]]></category>
            <category><![CDATA[HTTP3]]></category>
            <category><![CDATA[Testing]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Rust]]></category>
            <guid isPermaLink="false">2yX9ADcaKBprzyI9BaBoqN</guid>
            <dc:creator>Lucas Pardue</dc:creator>
            <dc:creator>Evan Rittenhouse</dc:creator>
        </item>
        <item>
            <title><![CDATA[connect() - why are you so slow?]]></title>
            <link>https://blog.cloudflare.com/linux-transport-protocol-port-selection-performance/</link>
            <pubDate>Thu, 08 Feb 2024 14:00:27 GMT</pubDate>
            <description><![CDATA[ This is our story of what we learned about the connect() implementation for TCP in Linux. Both its strong and weak points. How connect() latency changes under pressure, and how to open connection so that the syscall latency is deterministic and time-bound ]]></description>
            <content:encoded><![CDATA[ <p></p><p>It is no secret that Cloudflare is encouraging companies to deprecate their use of IPv4 addresses and move to IPv6 addresses. We have a couple articles on the subject from this year:</p><ul><li><p><a href="/amazon-2bn-ipv4-tax-how-avoid-paying/">Amazon’s $2bn IPv4 tax – and how you can avoid paying it</a></p></li><li><p><a href="/ipv6-from-dns-pov/">Using DNS to estimate worldwide state of IPv6 adoption</a></p></li></ul><p>And many more in our <a href="/searchresults#q=IPv6&amp;sort=date%20descending&amp;f:@customer_facing_source=[Blog]&amp;f:@language=[English]">catalog</a>. To help with this, we spent time this last year investigating and implementing infrastructure to reduce our internal and egress use of IPv4 addresses. We prefer to re-allocate our addresses than to purchase more due to increasing costs. And in this effort we discovered that our cache service is one of our bigger consumers of IPv4 addresses. Before we remove IPv4 addresses for our cache services, we first need to understand how cache works at Cloudflare.</p>
    <div>
      <h2>How does cache work at Cloudflare?</h2>
      <a href="#how-does-cache-work-at-cloudflare">
        
      </a>
    </div>
    <p>Describing the full scope of the <a href="https://developers.cloudflare.com/reference-architecture/cdn-reference-architecture/#cloudflare-cdn-architecture-and-design">architecture</a> is out of scope of this article, however, we can provide a basic outline:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/70ULgxsqU4zuyWYVrNn6et/8c80079d6dd93083059a875bbf48059d/image1-2.png" />
            
            </figure><ol><li><p>Internet User makes a request to pull an asset</p></li><li><p>Cloudflare infrastructure routes that request to a handler</p></li><li><p>Handler machine returns cached asset, or if miss</p></li><li><p>Handler machine reaches to origin server (owned by a customer) to pull the requested asset</p></li></ol><p>The particularly interesting part is the cache miss case. When a website suddenly becomes very popular, many uncached assets may need to be fetched all at once. Hence we may make an upwards of: 50k TCP unicast connections to a single destination_._</p><p>That is a lot of connections! We have strategies in place to limit the impact of this or avoid this problem altogether. But in these rare cases when it occurs, we will then balance these connections over two source IPv4 addresses.</p><p>Our goal is to remove the load balancing and prefer one IPv4 address. To do that, we need to understand the performance impact of two IPv4 addresses vs one.</p>
    <div>
      <h2>TCP connect() performance of two source IPv4 addresses vs one IPv4 address</h2>
      <a href="#tcp-connect-performance-of-two-source-ipv4-addresses-vs-one-ipv4-address">
        
      </a>
    </div>
    <p>We leveraged a tool called <a href="https://github.com/wg/wrk">wrk</a>, and modified it to distribute connections over multiple source IP addresses. Then we ran a workload of 70k connections over 48 threads for a period of time.</p><p>During the test we measured the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/tcp_ipv4.c#L201">tcp_v4_connect()</a> with the BPF BCC libbpf-tool <a href="https://github.com/iovisor/bcc/blob/master/libbpf-tools/funclatency.c">funclatency</a> tool to gather latency metrics as time progresses.</p><p>Note that throughout the rest of this article, all the numbers are specific to a single machine with no production traffic. We are making the assumption that if we can improve a worse case scenario in an algorithm with a best case machine, that the results could be extrapolated to production. Lock contention was specifically taken out of the equation, but will have production implications.</p>
    <div>
      <h3>Two IPv4 addresses</h3>
      <a href="#two-ipv4-addresses">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1q7v3WNgI5X3JQg5ua0B8g/5b557ca762a08422badae379233dee76/image6.png" />
            
            </figure><p>The y-axis are buckets of nanoseconds in powers of ten. The x-axis represents the number of connections made per bucket. Therefore, more connections in a lower power of ten buckets is better.</p><p>We can see that the majority of the connections occur in the fast case with roughly ~20k in the slow case. We should expect this bimodal to increase over time due to wrk continuously closing and establishing connections.</p><p>Now let us look at the performance of one IPv4 address under the same conditions.</p>
    <div>
      <h3>One IPv4 address</h3>
      <a href="#one-ipv4-address">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6kpueuXS3SbBTIig306IDN/b27ab899656fbfc0bf3c885a44fb04a4/image8.png" />
            
            </figure><p>In this case, the bimodal distribution is even more pronounced. Over half of the total connections are in the slow case than in the fast! We may conclude that simply switching to one IPv4 address for cache egress is going to introduce significant latency on our connect() syscalls.</p><p>The next logical step is to figure out where this bottleneck is happening.</p>
    <div>
      <h2>Port selection is not what you think it is</h2>
      <a href="#port-selection-is-not-what-you-think-it-is">
        
      </a>
    </div>
    <p>To investigate this, we first took a flame graph of a production machine:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1tFwadYDdC5UVK78j4yKsv/64aca09189acba5bf3dab2e043265e0f/image7.png" />
            
            </figure><p>Flame graphs depict a run-time function call stack of a system. Y-axis depicts call-stack depth, and x-axis depicts a function name in a horizontal bar that represents the amount of times the function was sampled. Checkout this in-depth <a href="https://www.brendangregg.com/flamegraphs.html">guide</a> about flame graphs for more details.</p><p>Most of the samples are taken in the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1000"><code>__inet_hash_connect()</code></a>. We can see that there are also many samples for <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L544"><code>__inet_check_established()</code></a> with some lock contention sampled between. We have a better picture of a potential bottleneck, but we do not have a consistent test to compare against.</p><p>Wrk introduces a bit more variability than we would like to see. Still focusing on the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/tcp_ipv4.c#L201"><code>tcp_v4_connect()</code></a>, we performed another synthetic test with a homegrown benchmark tool to test one IPv4 address. A tool such as <a href="https://github.com/ColinIanKing/stress-ng">stress-ng</a> may also be used, but some modification is necessary to implement the socket option <a href="https://man7.org/linux/man-pages/man7/ip.7.html"><code>IP_LOCAL_PORT_RANGE</code></a>. There is more about that socket option later.</p><p>We are now going to ensure a deterministic amount of connections, and remove lock contention from the problem. The result is something like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5d6tJum5BBe3jsLRqhXtFN/7952fb3d0a3da761de158fae4f925eb5/Screenshot-2024-02-07-at-15.54.29.png" />
            
            </figure><p>On the y-axis we measured the latency between the start and end of a connect() syscall. The x-axis denotes when a connect() was called. Green dots are even numbered ports, and red dots are odd numbered ports. The orange line is a linear-regression on the data.</p><p>The disparity between the average time for port allocation between even and odd ports provides us with a major clue. Connections with odd ports are found significantly slower than the even. Further, odd ports are not interleaved with earlier connections. This implies we exhaust our even ports before attempting the odd. The chart also confirms our bimodal distribution.</p>
    <div>
      <h3>__inet_hash_connect()</h3>
      <a href="#__inet_hash_connect">
        
      </a>
    </div>
    <p>At this point we wanted to understand this split a bit better. We know from the flame graph and the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1000"><code>__inet_hash_connect()</code></a> that this holds the algorithm for port selection. For context, this function is responsible for associating the socket to a source port in a late bind. If a port was previously provided with bind(), the algorithm just tests for a unique TCP 4-tuple (src ip, src port, dest ip, dest port) and ignores port selection.</p><p>Before we dive in, there is a little bit of setup work that happens first. Linux first generates a time-based hash that is used as the basis for the starting port, then adds randomization, and then puts that information into an offset variable. This is always set to an even integer.</p><p><a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1043">net/ipv4/inet_hashtables.c</a></p>
            <pre><code>   offset &amp;= ~1U;
    
other_parity_scan:
    port = low + offset;
    for (i = 0; i &lt; remaining; i += 2, port += 2) {
        if (unlikely(port &gt;= high))
            port -= remaining;

        inet_bind_bucket_for_each(tb, &amp;head-&gt;chain) {
            if (inet_bind_bucket_match(tb, net, port, l3mdev)) {
                if (!check_established(death_row, sk, port, &amp;tw))
                    goto ok;
                goto next_port;
            }
        }
    }

    offset++;
    if ((offset &amp; 1) &amp;&amp; remaining &gt; 1)
        goto other_parity_scan;</code></pre>
            <p>Then in a nutshell: loop through one half of ports in our range (all even or all odd ports) before looping through the other half of ports (all odd or all even ports respectively) for each connection. Specifically, this is a variation of the <a href="https://datatracker.ietf.org/doc/html/rfc6056#section-3.3.4">Double-Hash Port Selection Algorithm</a>. We will ignore the bind bucket functionality since that is not our main concern.</p><p>Depending on your port range, you either start with an even port or an odd port. In our case, our low port, 9024, is even. Then the port is picked by adding the offset to the low port:</p><p><a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L1045">net/ipv4/inet_hashtables.c</a></p>
            <pre><code>port = low + offset;</code></pre>
            <p>If low was odd, we will have an odd starting port because odd + even = odd.</p><p>There is a bit too much going on in the loop to explain in text. I have an example instead:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6uVqtAUR07epRRKqQbHWkp/2a5671b1dd3c68c012e7171b8103a53e/image5.png" />
            
            </figure><p>This example is bound by 8 ports and 8 possible connections. All ports start unused. As a port is used up, the port is grayed out. Green boxes represent the next chosen port. All other colors represent open ports. Blue arrows are even port iterations of offset, and red are the odd port iterations of offset. Note that the offset is randomly picked, and once we cross over to the odd range, the offset is incremented by one.</p><p>For each selection of a port, the algorithm then makes a call to the function <code>check_established()</code> which dereferences <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/inet_hashtables.c#L544"><code>__inet_check_established()</code></a>. This function loops over sockets to verify that the TCP 4-tuple is unique. The takeaway is that the socket list in the function is usually smaller than not. This grows as more unique TCP 4-tuples are introduced to the system. Longer socket lists may slow down port selection eventually. We have a blog post on <a href="/how-to-stop-running-out-of-ephemeral-ports-and-start-to-love-long-lived-connections/">ephemeral port exhausting</a> that dives into the socket list and port uniqueness criteria.</p><p>At this point, we can summarize that the odd/even port split is what is causing our performance bottleneck. And during the investigation, it was not obvious to me (or even maybe you) why the offset was initially calculated the way it was, and why the odd/even port split was introduced. After some git-archaeology the decisions become more clear.</p>
    <div>
      <h3>Security considerations</h3>
      <a href="#security-considerations">
        
      </a>
    </div>
    <p>Port selection has been shown to be used in device <a href="https://lwn.net/Articles/910435/">fingerprinting</a> in the past. This led the authors to introduce more randomization into the initial port selection. Prior, ports were predictably picked solely based on their initial hash and a salt value which does not change often. This helps with explaining the offset, but does not explain the split.</p>
    <div>
      <h3>Why the even/odd split?</h3>
      <a href="#why-the-even-odd-split">
        
      </a>
    </div>
    <p>Prior to this <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=07f4c90062f8fc7c8c26f8f95324cbe8fa3145a5">patch</a> and that <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1580ab63fc9a03593072cc5656167a75c4f1d173">patch</a>, services may have conflicts between the connect() and bind() heavy workloads. Thus, to avoid those conflicts, the split was added. An even offset was chosen for the connect() workloads, and an odd offset for the bind() workloads. However, we can see that the split works great for connect() workloads that do not exceed one half of the allotted port range.</p><p>Now we have an explanation for the flame graph and charts. So what can we do about this?</p>
    <div>
      <h2>User space solution (kernel &lt; 6.8)</h2>
      <a href="#user-space-solution-kernel-6-8">
        
      </a>
    </div>
    <p>We have a couple of strategies that would work best for us. Infrastructure or architectural strategies are not considered due to significant development effort. Instead, we prefer to tackle the problem where it occurs.</p><h3>Select, test, repeat<p>For the “select, test, repeat” approach, you may have code that ends up looking like this:</p>
            <pre><code>sys = get_ip_local_port_range()
estab = 0
i = sys.hi
while i &gt;= 0:
    if estab &gt;= sys.hi:
        break

    random_port = random.randint(sys.lo, sys.hi)
    connection = attempt_connect(random_port)
    if connection is None:
        i += 1
        continue

    i -= 1
    estab += 1</code></pre>
            <p>The algorithm simply loops through the system port range, and randomly picks a port each iteration. Then test that the connect() worked. If not, rinse and repeat until range exhaustion.</p><p>This approach is good for up to ~70-80% port range utilization. And this may take roughly eight to twelve attempts per connection as we approach exhaustion. The major downside to this approach is the extra syscall overhead on conflict. In order to reduce this overhead, we can consider another approach that allows the kernel to still select the port for us.</p><h3>Select port by random shifting range<p>This approach leverages the <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=91d0b78c5177f3e42a4d8738af8ac19c3a90d002"><code>IP_LOCAL_PORT_RANGE</code></a> socket option. And we were able to achieve performance like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/Uz8whp12VuvqvKTDnE1u9/4701177d739bdffe2a2399213cf72941/Screenshot-2024-02-07-at-16.00.22.png" />
            
            </figure><p>That is much better! The chart also introduces black dots that represent errored connections. However, they have a tendency to clump at the very end of our port range as we approach exhaustion. This is not dissimilar to what we may see in “<a href="#selecttestrepeat">select, test, repeat</a>”.</p><p>The way this solution works is something like:</p>
            <pre><code>IP_BIND_ADDRESS_NO_PORT = 24
IP_LOCAL_PORT_RANGE = 51
sys = get_local_port_range()
window.lo = 0
window.hi = 1000
range = window.hi - window.lo
offset = randint(sys.lo, sys.hi - range)
window.lo = offset
window.hi = offset + range

sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1)
range = pack("@I", window.lo | (window.hi &lt;&lt; 16))
sk.setsockopt(IPPROTO_IP, IP_LOCAL_PORT_RANGE, range)
sk.bind((src_ip, 0))
sk.connect((dest_ip, dest_port))</code></pre>
            <p>We first fetch the system's local port range, define a custom port range, and then randomly shift the custom range within the system range. Introducing this randomization helps the kernel to start port selection randomly at an odd or even port. Then reduces the loop search space down to the range of the custom window.</p><p>We tested with a few different window sizes, and determined that a five hundred or one thousand size works fairly well for our port range:</p>
<table>
<thead>
  <tr>
    <th><span>Window size</span></th>
    <th><span>Errors</span></th>
    <th><span>Total test time</span></th>
    <th><span>Connections/second</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><span>500</span></td>
    <td><span>868</span></td>
    <td><span>~1.8 seconds</span></td>
    <td><span>~30,139</span></td>
  </tr>
  <tr>
    <td><span>1,000</span></td>
    <td><span>1,129</span></td>
    <td><span>~2 seconds</span></td>
    <td><span>~27,260</span></td>
  </tr>
  <tr>
    <td><span>5,000</span></td>
    <td><span>4,037</span></td>
    <td><span>~6.7 seconds</span></td>
    <td><span>~8,405</span></td>
  </tr>
  <tr>
    <td><span>10,000</span></td>
    <td><span>6,695</span></td>
    <td><span>~17.7 seconds</span></td>
    <td><span>~3,183</span></td>
  </tr>
</tbody>
</table><p>As the window size increases, the error rate increases. That is because a larger window provides less random offset opportunity. A max window size of 56,512 is no different from using the kernels default behavior. Therefore, a smaller window size works better. But you do not want it to be too small either. A window size of one is no different from “<a href="#selecttestrepeat">select, test, repeat</a>”.</p><p>In kernels &gt;= 6.8, we can do even better.</p><h2>Kernel solution (kernel &gt;= 6.8)</h2><p>A new <a href="https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=207184853dbd">patch</a> was introduced that eliminates the need for the window shifting. This solution is going to be available in the 6.8 kernel.</p><p>Instead of picking a random window offset for <code>setsockopt(IPPROTO_IP, IP_LOCAL_PORT_RANGE</code>, …), like in the previous solution, we instead just pass the full system port range to activate the solution. The code may look something like this:</p>
            <pre><code>IP_BIND_ADDRESS_NO_PORT = 24
IP_LOCAL_PORT_RANGE = 51
sys = get_local_port_range()
sk = socket(AF_INET, SOCK_STREAM)
sk.setsockopt(IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, 1)
range = pack("@I", sys.lo | (sys.hi &lt;&lt; 16))
sk.setsockopt(IPPROTO_IP, IP_LOCAL_PORT_RANGE, range)
sk.bind((src_ip, 0))
sk.connect((dest_ip, dest_port))</code></pre>
            <p>Setting <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=91d0b78c5177f3e42a4d8738af8ac19c3a90d002"><code>IP_LOCAL_PORT_RANGE</code></a> option is what tells the kernel to use a similar approach to “<a href="#random">select port by random shifting range</a>” such that the start offset is randomized to be even or odd, but then loops incrementally rather than skipping every other port. We end up with results like this:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1ttWStZgNYfwftr71r8Vrt/7c333411ef01b674cc839f27ae4cbbbf/Screenshot-2024-02-07-at-16.04.24.png" />
            
            </figure><p>The performance of this approach is quite comparable to our user space implementation. Albeit, a little faster. Due in part to general improvements, and that the algorithm can always find a port given the full search space of the range. Then there are no cycles wasted on a potentially filled sub-range.</p><p>These results are great for TCP, but what about other protocols?</p>
    <div>
      <h2>Other protocols &amp; connect()</h2>
      <a href="#other-protocols-connect">
        
      </a>
    </div>
    <p>It is worth mentioning at this point that the algorithms used for the protocols are <i>mostly</i> the same for IPv4 &amp; IPv6. Typically, the key difference is how the sockets are compared to determine uniqueness and where the port search happens. We did not compare performance for all protocols. But it is worth mentioning some similarities and differences with TCP and a couple of others.</p>
    <div>
      <h3>DCCP</h3>
      <a href="#dccp">
        
      </a>
    </div>
    <p>The DCCP protocol leverages the same port selection <a href="https://elixir.bootlin.com/linux/v6.6/source/net/dccp/ipv4.c#L115">algorithm</a> as TCP. Therefore, this protocol benefits from the recent kernel changes. It is also possible the protocol could benefit from our user space solution, but that is untested. We will let the reader exercise DCCP use-cases.</p>
    <div>
      <h3>UDP &amp; UDP-Lite</h3>
      <a href="#udp-udp-lite">
        
      </a>
    </div>
    <p><a href="https://www.cloudflare.com/learning/ddos/glossary/user-datagram-protocol-udp/">UDP</a> leverages a different algorithm found in the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/udp.c#L239"><code>udp_lib_get_port()</code></a>. Similar to TCP, the algorithm will loop over the whole port range space incrementally. This is only the case if the port is not already supplied in the bind() call. The key difference between UDP and TCP is that a random number is generated as a step variable. Then, once a first port is identified, the algorithm loops on that port with the random number. This relies on an uint16_t overflow to eventually loop back to the chosen port. If all ports are used, increment the port by one and repeat. There is no port splitting between even and odd ports.</p><p>The best comparison to the TCP measurements is a UDP setup similar to:</p>
            <pre><code>sk = socket(AF_INET, SOCK_DGRAM)
sk.bind((src_ip, 0))
sk.connect((dest_ip, dest_port))</code></pre>
            <p>And the results should be unsurprising with one IPv4 source address:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4UM5d0RBTgqADgVLbbqMlQ/940306c90767ba4b5e3762c6467b71ed/Screenshot-2024-02-07-at-16.06.27.png" />
            
            </figure><p>UDP fundamentally behaves differently from TCP. And there is less work overall for port lookups. The outliers in the chart represent a worst-case scenario when we reach a fairly bad random number collision. In that case, we need to more-completely loop over the ephemeral range to find a port.</p><p>UDP has another problem. Given the socket option <code>SO_REUSEADDR</code>, the port you get back may conflict with another UDP socket. This is in part due to the function <a href="https://elixir.bootlin.com/linux/v6.6/source/net/ipv4/udp.c#L141"><code>udp_lib_lport_inuse()</code></a> ignoring the UDP 2-tuple (src ip, src port) check given the socket option. When this happens you may have a new socket that overwrites a previous. Extra care is needed in that case. We wrote more in depth about these cases in a previous <a href="/how-to-stop-running-out-of-ephemeral-ports-and-start-to-love-long-lived-connections/">blog post</a>.</p>
    <div>
      <h2>In summary</h2>
      <a href="#in-summary">
        
      </a>
    </div>
    <p>Cloudflare can make a lot of unicast egress connections to origin servers with popular uncached assets. To avoid port-resource exhaustion, we balance the load over a couple of IPv4 source addresses during those peak times. Then we asked: “what is the performance impact of one IPv4 source address for our connect()-heavy workloads?”. Port selection is not only difficult to get right, but is also a performance bottleneck. This is evidenced by measuring connect() latency with a flame graph and synthetic workloads. That then led us to discovering TCP’s quirky port selection process that loops over half your ephemeral ports before the other for each connect().</p><p>We then proposed three solutions to solve the problem outside of adding more IP addresses or other architectural changes: “<a href="#selecttestrepeat">select, test, repeat</a>”, “<a href="#random">select port by random shifting range</a>”, and an <a href="https://man7.org/linux/man-pages/man7/ip.7.html"><code>IP_LOCAL_PORT_RANGE</code></a> socket option <a href="#kernel">solution</a> in newer kernels. And finally closed out with other protocol honorable mentions and their quirks.</p><p>Do not take our numbers! Please explore and measure your own systems. With a better understanding of your workloads, you can make a good decision on which strategy works best for your needs. Even better if you come up with your own strategy!</p></h3></h3> ]]></content:encoded>
            <category><![CDATA[Linux]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Performance]]></category>
            <category><![CDATA[Deep Dive]]></category>
            <category><![CDATA[IPv4]]></category>
            <category><![CDATA[IPv6]]></category>
            <category><![CDATA[Network]]></category>
            <guid isPermaLink="false">1C6z0btasEsz1cmdmoug0m</guid>
            <dc:creator>Frederick Lawler</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare’s commitment to the 2023 Summit for Democracy]]></title>
            <link>https://blog.cloudflare.com/cloudflare-commitment-to-the-2023-summit-for-democracy/</link>
            <pubDate>Tue, 28 Mar 2023 13:00:00 GMT</pubDate>
            <description><![CDATA[ Cloudflare is proud to participate in and contribute commitments to the 2023 Summit Summit for Democracy because we believe that everyone should have access to an Internet that is faster, ]]></description>
            <content:encoded><![CDATA[ <p></p><p>On Tuesday, March 28, 2023, the US Government will launch the <a href="https://www.state.gov/summit-for-democracy-2023/">Summit for Democracy 2023</a>, following up on the inaugural <a href="https://www.state.gov/summit-for-democracy-2021/">Summit for Democracy 2021</a>. The Summit is co-hosted by the United States, Costa Rica, Zambia, the Netherlands, and South Korea. Cloudflare is proud to participate in and contribute commitments to the Summit because we believe that everyone should have access to an Internet that is faster, more reliable, more private, and more secure.  We work to ensure that the responsibility to respect human rights is embedded throughout our business functions. Cloudflare’s mission — to help build a better Internet — reflects a long-standing belief that we can help make the Internet better for everyone.</p><p>Our mission and core values dovetail with the Summit’s goals of strengthening democratic governance, respect for human rights and human rights defenders, and working in partnership to strengthen respect for these values. As we have <a href="/applying-human-rights-frameworks-to-our-approach-to-abuse/">written about before</a>, access to the Internet allows activists and human rights defenders to expose abuses across the globe, allows collective causes to grow into global movements, and provides the foundation for large-scale organizing for political and social change in ways that have never been possible before.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5rSJ6ucWgBy2LkLs1AU6uJ/6622ab0532e0a40defb39f373a3afda6/Screenshot-2023-03-28-at-11.34.32.png" />
            
            </figure>
    <div>
      <h3>What is the Summit for Democracy?</h3>
      <a href="#what-is-the-summit-for-democracy">
        
      </a>
    </div>
    <p>In December 2021, in an effort to respond to challenges to democracy worldwide, the United States held the first ever global Summit for Democracy. The Summit provided an opportunity to strengthen collaboration between democracies around the world and address common challenges from authoritarian threats.  The United States invited over 100 countries plus the President of the European Commission and the United Nations Secretary-General. The Summit focused on three key themes: (1) defending against authoritarianism; (2) addressing and fighting corruption; and (3) promoting respect for human rights, and gave participants an opportunity to announce commitments, reforms, and initiatives to defend democracy and human rights. The Summit was followed by a Year of Action, during which governments implemented their commitments to the Summit.</p><p>The 2023 Summit will focus more directly on partnering with the private sector to promote an affirmative vision for technology by countering the misuse of technology and shaping emerging technologies so that they strengthen democracy and human rights, which Cloudflare supports in theory and in practice.</p><p>The three-day Summit will highlight the importance of the private sector’s role in responding to challenges to democracy. The first day of the Summit is the <a href="https://www.state.gov/summit-for-democracy-2023/#March28">Thematic Day</a>, where Cabinet-level officials, the private sector and civil society organizations will spotlight key Summit themes. On the second day of the Summit, the <a href="https://www.state.gov/summit-for-democracy-2023/#March29">Plenary Day</a>, the five co-hosts will each host a high-level plenary session. On the final day of the Summit, <a href="https://www.state.gov/summit-for-democracy-2023/#March30">Co-Host Event Day</a>, each of the co-hosts will lead high-level regional conversations with partners from government, civil society, and the private sector.</p><p>Cloudflare will be participating in the Thematic Day and the Co-Host Event Day in Washington, DC, in addition to other related events.</p>
    <div>
      <h3>Cloudflare commitments</h3>
      <a href="#cloudflare-commitments">
        
      </a>
    </div>
    <p>In advance of the 2023 Summit, the United States issued a <a href="https://www.state.gov/wp-content/uploads/2023/02/Private-Sector-Call-to-Advance-Democracy-1.pdf">Call to Action</a> to the private sector to consider commitments that advance an affirmative agenda for democratic renewal. The United States encouraged the private sector to make commitments that align with the <a href="https://www.state.gov/presidential-initiative-for-democratic-renewal-drl-office-of-global-programs-efforts/">Presidential Initiative on Democratic Renewal</a>, the <a href="https://www.state.gov/declaration-for-the-future-of-the-internet">Declaration on the Future of the Internet</a>, and the Summit’s four objectives:</p><ul><li><p>Countering the misuse of technology</p></li><li><p>Fighting corruption</p></li><li><p>Protecting civic space</p></li><li><p>Advancing labor rights</p></li></ul><p>Cloudflare answered the United States’s call to action and made commitments to (1) help democratize post-quantum cryptography; (2) work with researchers to share data on Internet censorship and shutdowns; and (3) engage with civil society on Internet protocols and the application of privacy-enhancing technologies.</p>
    <div>
      <h3>Democratizing post-quantum cryptography by including it for free, by default</h3>
      <a href="#democratizing-post-quantum-cryptography-by-including-it-for-free-by-default">
        
      </a>
    </div>
    <p>At Cloudflare, we believe to enhance privacy as a human right the most advanced cryptography needs to be available to everyone, free of charge, forever. Cloudflare has committed to including post-quantum cryptography for free by default to all customers – including individual web developers, small businesses, non-profits, and governments. In particular, this will benefit at-risk groups using Cloudflare services like humanitarian organizations, human rights defenders, and journalists through <a href="https://www.cloudflare.com/galileo/">Project Galileo</a>, as well as state and local government election websites through the <a href="https://www.cloudflare.com/athenian/">Athenian Project</a>, to help secure their websites, APIs, cloud tools and remote employees against future threats.</p><p>We believe everyone should have access to the next era of <a href="https://www.cloudflare.com/learning/security/what-is-cyber-security/">cybersecurity standards</a>–instantly and for free. To that end, Cloudflare will also publish vendor-neutral roadmaps based on NIST standards to help businesses secure any connections that are not protected by Cloudflare. We hope that others will follow us in making their implementations of post-quantum cryptography free so that we can create a secure and private Internet without a “quantum” up-charge.  More details about our commitment is <a href="https://www.cloudflare.com/press-releases/2023/cloudflare-democratizes-post-quantum-cryptography-by-delivering-it-for-free/">here</a> and <a href="/post-quantum-crypto-should-be-free/">here</a>.</p>
    <div>
      <h3>Working with researchers to better document Internet censorship and shutdowns</h3>
      <a href="#working-with-researchers-to-better-document-internet-censorship-and-shutdowns">
        
      </a>
    </div>
    <p>Cloudflare commits to working with researchers to share data about Internet shutdowns and selective Internet traffic interference and to make the results of the analysis of this data public and accessible. The Cloudflare Network includes 285 locations in over 100 countries, interconnects with over 11,500 networks globally, and serves a significant portion of global Internet traffic. Cloudflare shares aggregated data on the Internet's patterns, insights, threats and trends with the public through <a href="https://radar.cloudflare.com/">Cloudflare Radar</a>, including providing alerts and data to help organizations like <a href="https://www.accessnow.org/">Access Now's</a> <a href="https://www.accessnow.org/campaign/keepiton/">KeepItOn</a> coalition, the <a href="https://freedomonlinecoalition.com/">Freedom Online Coalition</a>, the <a href="https://www.internetsociety.org/">Internet Society</a>, and <a href="https://ooni.org/">Open Observatory of Network Interference</a> (OONI) monitor Internet censorship and shutdowns around the world. Cloudflare commits to working with research partners to identify signatures associated with connection tampering and failures, which are believed to be caused primarily by active censorship and blocking. Cloudflare is well-positioned to observe and report on these signatures from a global perspective, and will provide access to its findings to support additional tampering detection efforts.</p>
    <div>
      <h3>Engaging with civil society on Internet protocols and the development and application of privacy-enhancing technologies</h3>
      <a href="#engaging-with-civil-society-on-internet-protocols-and-the-development-and-application-of-privacy-enhancing-technologies">
        
      </a>
    </div>
    <p>Cloudflare believes that meaningful consultation with civil society is a fundamental part of building an Internet that advances human rights. As Cloudflare works with Internet standards bodies and other Internet providers on the next-generation of privacy-enhancing technologies and protocols, like protocols to <a href="/dns-encryption-explained/">encrypt Domain Name Service</a> records and <a href="/handshake-encryption-endgame-an-ech-update/">Encrypted Client Hello</a> (ECH) and privacy enhancing technologies like OHTTP, we commit to direct engagement with civil society and human rights experts on standards and technologies that might have implications for human rights.</p><p>Cloudflare has long worked with industry partners, stakeholders, and international standards organizations to build a more private, secure, and resilient Internet for everyone. For example, Cloudflare has built privacy technologies into its network infrastructure, helped develop and deploy TLS 1.3 alongside helping lead QUIC  and other Internet protocols, improve transparency around routing and public key infrastructure (PKI), and operating a public DNS resolver that supports encryption protocols. Ensuring civil society and human rights experts are able to contribute and provide feedback as part of those efforts will make certain that future development and application of privacy-enhancing technologies and protocols are consistent with human rights principles and account for human rights impacts.</p><p>Our commitments to democratizing post-quantum cryptography, working with researchers on Internet censorship and shutdowns, and engaging with civil society on Internet protocols and the development and application of privacy-preserving technologies will help to secure access to a free, open, and interconnected Internet.</p>
    <div>
      <h3>Partnering to make the Summit a success</h3>
      <a href="#partnering-to-make-the-summit-a-success">
        
      </a>
    </div>
    <p>In the lead-up to the Summit, Cloudflare has been working in partnership with the US Department of State, the National Security Council, the US Agency for International Development (USAID), and various private sector and civil society partners to prepare for the Summit. As part of our involvement, we have also contributed to roundtables and discussions with the Center for Strategic and International Studies, GNI, the Design 4 Democracy Coalition, and the Freedom Online Coalition. Cloudflare is also participating in official meetings and side events including at the Carnegie Endowment for International Peace and the Council on Foreign Relations.</p><p>In addition to the official Summit events, there are a wide range of events organized by civil society which the <a href="https://accountabilitylab.org/">Accountability Lab</a> has created a <a href="https://summit4democracy.org/">website</a> to highlight. Separately, on Monday, March 27 the <a href="https://globaldemocracycoalition.org/">Global Democracy Coalition</a> convened a <a href="https://globaldemocracycoalition.org/event/partners-for-democracy-day/">Partners Day</a> to organize civil society and other non-governmental events. Many of these events are being held by some of our Galileo partners like the National Democratic Institute, the International Republican Institute, Freedom House, and the Council of Europe.</p><p>Cloudflare is grateful for all of the hard work that our partners in government, civil society, and the private sector have done over the past few months to make this Summit a success. At a time where we are seeing increasing challenges to democracy and the struggle for human rights around the world, maintaining a secure, open, Internet is critical. Cloudflare is proud of our participation in the Summit and in the commitments we are making to help advance human rights. We look forward to continuing our engagement in the Summit partnership to fulfill our mission to help build a better Internet.</p> ]]></content:encoded>
            <category><![CDATA[USA]]></category>
            <category><![CDATA[Human Rights]]></category>
            <category><![CDATA[Post-Quantum]]></category>
            <category><![CDATA[Internet Shutdown]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Project Galileo]]></category>
            <category><![CDATA[Policy & Legal]]></category>
            <guid isPermaLink="false">5NzVC7zRmPw0EB11aLk3Ou</guid>
            <dc:creator>Zaid Zaid</dc:creator>
            <dc:creator>Patrick Day</dc:creator>
        </item>
        <item>
            <title><![CDATA[Privacy Gateway: a privacy preserving proxy built on Internet standards]]></title>
            <link>https://blog.cloudflare.com/building-privacy-into-internet-standards-and-how-to-make-your-app-more-private-today/</link>
            <pubDate>Thu, 27 Oct 2022 13:01:00 GMT</pubDate>
            <description><![CDATA[ Privacy Gateway enables privacy-forward applications to use Cloudflare as a trusted Relay, limiting which identifying information, including IP addresses, is visible to their infrastructure ]]></description>
            <content:encoded><![CDATA[ <p></p><p>If you’re running a privacy-oriented application or service on the Internet, your options to provably protect users’ privacy are limited. You can minimize logs and data collection but even then, at a network level, every HTTP request needs to come from <i>somewhere.</i> Information generated by HTTP requests, like users’ IP addresses and TLS fingerprints, can be sensitive especially when combined with application data.</p><p>Meaningful improvements to your users’ privacy require a change in how HTTP requests are sent from client devices to the server that runs your application logic. This was the motivation for Privacy Gateway: a service that relays encrypted HTTP requests and responses between a client and application server. With Privacy Gateway, Cloudflare knows where the request is coming from, but not what it contains, and applications can see what the request contains, but not where it comes from. <b>Neither Cloudflare nor the application server has the full picture</b>, improving end-user privacy.</p><p>We recently deployed Privacy Gateway for <a href="https://flo.health/">Flo Health Inc</a>., a leading female health app, for the launch of their <a href="https://www.theverge.com/2022/9/14/23351957/flo-period-tracker-privacy-anonymous-mode">Anonymous Mode</a>. With Privacy Gateway in place, all request data for Anonymous Mode users is encrypted between the app user and Flo, which prevents Flo from seeing the IP addresses of those users and Cloudflare from seeing the contents of that request data.</p><p>With Privacy Gateway in place, several other privacy-critical applications are possible:</p><ul><li><p>Browser developers can collect user telemetry in a privacy-respecting manner– what extensions are installed, what defaults a user might have changed — while removing what is still a potentially personal identifier (the IP address) from that data.</p></li><li><p>Users can visit a healthcare site to report a Covid-19 exposure without worrying that the site is tracking their IP address and/or location.</p></li><li><p>DNS resolvers can serve DNS queries without linking who made the request with what website they’re visiting – a pattern we’ve implemented with <a href="/oblivious-dns/">Oblivious DNS</a>.Privacy Gateway is based on <a href="https://datatracker.ietf.org/doc/draft-ietf-ohai-ohttp/">Oblivious HTTP (OHTTP), an emerging IETF standard</a> and is built upon standard <a href="https://datatracker.ietf.org/doc/html/rfc9180">hybrid public-key cryptography</a>.</p></li></ul>
    <div>
      <h2>How does it work?</h2>
      <a href="#how-does-it-work">
        
      </a>
    </div>
    <p>The main innovation in the Oblivious HTTP standard – beyond a basic proxy service – is that these messages are encrypted <i>to the application’s server</i>, such that Privacy Gateway learns nothing of the application data beyond the source and destination of each message.</p><p>Privacy Gateway enables application developers and platforms, especially those with strong privacy requirements, to build something that closely resembles a “<a href="https://en.wikipedia.org/wiki/Mix_network">Mixnet</a>”: an approach to obfuscating the source and destination of a message across a network. To that end, Privacy Gateway consists of three main components:</p><ol><li><p><b>Client:</b> the user’s device, or any client that’s configured to forward requests to Privacy Gateway.</p></li><li><p><b>Privacy Gateway:</b> a service operated by Cloudflare and designed to relay requests between the Client and the Gateway, without being able to observe the contents within.</p></li><li><p><b>Application server</b>: the origin or application web server responsible for decrypting requests from clients, and encrypting responses back.</p></li></ol><p>If you were to imagine request data as the contents of the envelope (a letter) and the IP address and request metadata as the address on the outside, with Privacy Gateway, Cloudflare is able to see the envelope’s address and safely forward it to its destination without being able to see what’s inside.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2sYdEzCvuyKU7h3wIUKju0/b845a85835291ffe7c9751355b9c6b5f/image4-9.png" />
            
            </figure><p>An Oblivious HTTP transaction using Privacy Gateway</p><p>In slightly more detail, the data flow is as follows:</p><ol><li><p>Client <a href="https://datatracker.ietf.org/doc/html/draft-thomson-http-oblivious-02#section-5.1">encapsulates an HTTP request</a> using the public key of the application server, and sends it to Privacy Gateway over an HTTPS connection.</p></li><li><p>Privacy Gateway forwards the request to the server over its own, separate HTTPS connection with the application server.</p></li><li><p>The application server  decapsulates the request, forwarding it to the target server which can produce the response.</p></li><li><p>The application server returns an <a href="https://datatracker.ietf.org/doc/html/draft-thomson-http-oblivious-02#section-5.2">encapsulated response</a> to Privacy Gateway, which then forwards the result to the client.As specified in the protocol, requests from the client to the server are encrypted using HPKE, a state-of-the-art standard for public key encryption – which you can read more about <a href="/hybrid-public-key-encryption/">here</a>. We’ve taken additional measures to ensure that OHTTP’s use of HPKE is secure by conducting a <a href="/stronger-than-a-promise-proving-oblivious-http-privacy-properties/">formal analysis of the protocol</a>, and we expect to publish a deeper analysis in the coming weeks.</p></li></ol>
    <div>
      <h2>How Privacy Gateway improves end-user privacy</h2>
      <a href="#how-privacy-gateway-improves-end-user-privacy">
        
      </a>
    </div>
    <p>This interaction offers two types of privacy, which we informally refer to as <i>request privacy</i> and <i>client privacy</i>.</p><p>Request privacy means that the application server does not learn information that would otherwise be revealed by an HTTP request, such as IP address, geolocation, TLS and HTTPS fingerprints, and so on. Because Privacy Gateway uses a separate HTTPS connection between itself and the application server, all of this per-request information revealed to the application server represents that of Privacy Gateway, not of the client. However, developers need to take care to not send personally identifying information in the contents of requests. If the request, once decapsulated, includes information like users’ email, phone number, or credit card info, for example, Privacy Gateway will not meaningfully improve privacy.</p><p>Client privacy is a stronger notion. Because Cloudflare and the application server are not colluding to share individual user’s data, from the server’s perspective, each individual transaction came from some unknown client behind Privacy Gateway. In other words, a properly configured Privacy Gateway deployment means that applications cannot link any two requests to the same client. In particular, with Privacy Gateway, privacy loves company. If there is only one end-user making use of Privacy Gateway, then it only provides request privacy (since the client IP address remains hidden from the Gateway). It would not provide client privacy, since the server would know that each request corresponds to the same, single client. Client privacy requires that there be many users of the system, so the application server cannot make this determination.</p><p>To better understand request and client privacy, consider the following HTTP request between a client and server:</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6tEmiR5nN2XWpa1EqATvBY/e74edca6ab779548c43aaa357fd88578/image3-7.png" />
            
            </figure><p>Normal HTTP configuration with a client anonymity set of size 1</p><p>If a client connects directly to the server (or “Gateway” in OHTTP terms), the server is likely to see information about the client, including the IP address, TLS cipher used, and a degree of location data based on that IP address:</p>
            <pre><code>- ipAddress: 192.0.2.33 # the client’s real IP address
- ASN: 7922
- AS Organization: Comcast Cable
- tlsCipher: AEAD-CHACHA20-POLY1305-SHA256 # potentially unique
- tlsVersion: TLSv1.3
- Country: US
- Region: California
- City: Campbell</code></pre>
            <p>There’s plenty of sensitive information here that might be unique to the end-user. In other words, the connection offers neither request nor client privacy.</p><p>With Privacy Gateway, clients do not connect directly to the application server itself. Instead, they connect to Privacy Gateway, which in turn connects to the server. This means that the server only observes connections from Privacy Gateway, not individual connections from clients, yielding a different view:</p>
            <pre><code>- ipAddress: 104.16.5.5 # a Cloudflare IP
- ASN: 13335
- AS Organization: Cloudflare
- tlsCipher: ECDHE-ECDSA-AES128-GCM-SHA256 # shared across several clients
- tlsVersion: TLSv1.3
- Country: US
- Region: California
- City: Los Angeles</code></pre>
            
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/34pNp8QRamMWLMqBpT2Q05/4b400b029df3a7ad8821e7da69dd30b9/image1-18.png" />
            
            </figure><p>Privacy Gateway configuration with a client anonymity set of size k</p><p>This is request privacy. All information about the client’s location and identity are hidden from the application server. And all details about the application data are hidden from Privacy Gateway. For sensitive applications and protocols like DNS, keeping this metadata separate from the application data is an important step towards improving end-user privacy.</p><p>Moreover, applications should take care to not reveal sensitive, per-client information in their individual requests. Privacy Gateway cannot guarantee that applications do not send identifying info – such as email addresses, full names, etc – in request bodies, since it cannot observe plaintext application data. Applications which reveal user identifying information in requests may violate client privacy, but not request privacy. This is why – unlike our full <a href="/privacy-edge-making-building-privacy-first-apps-easier/">application-level Privacy Proxy</a> product – Privacy Gateway is <i>not</i> meant to be used as a generic proxy-based protocol for arbitrary applications and traffic. It is meant to be a special purpose protocol for sensitive applications, including DNS (as is evidenced by <a href="/oblivious-dns/">Oblivious DNS-over-HTTPS</a>), telemetry data, or generic API requests as discussed above.</p>
    <div>
      <h2>Integrating Privacy Gateway into your application</h2>
      <a href="#integrating-privacy-gateway-into-your-application">
        
      </a>
    </div>
    <p>Integrating with Privacy Gateway requires applications to implement the client and server side of the OHTTP protocol. Let’s walk through what this entails.</p>
    <div>
      <h3>Server Integration</h3>
      <a href="#server-integration">
        
      </a>
    </div>
    <p>The server-side part of the protocol is responsible for two basic tasks:</p><ol><li><p>Publishing a public key for request encapsulation; and</p></li><li><p>Decrypting encapsulated client requests, processing the resulting request, and encrypting the corresponding response.</p></li></ol><p>A <a href="https://ietf-wg-ohai.github.io/oblivious-http/draft-ietf-ohai-ohttp.html#name-key-configuration">public encapsulation key</a>, called a key configuration, consists of a key identifier (so the server can support multiple keys at once for rotation purposes), cryptographic algorithm identifiers for encryption and decryption, and a public key:</p>
            <pre><code>HPKE Symmetric Algorithms {
  HPKE KDF ID (16),
  HPKE AEAD ID (16),
}

OHTTP Key Config {
  Key Identifier (8),
  HPKE KEM ID (16),
  HPKE Public Key (Npk * 8),
  HPKE Symmetric Algorithms Length (16),
  HPKE Symmetric Algorithms (32..262140),
}</code></pre>
            <p>Clients need this public key to create their request, and there are lots of ways to do this. Servers could fix a public key and then bake it into their application, but this would require a software update to rotate the key. Alternatively, clients could discover the public key some other way. Many discovery mechanisms exist and vary based on your threat model – see <a href="https://datatracker.ietf.org/doc/html/draft-wood-key-consistency">this document</a> for more details. To start, a simple approach is to have clients fetch the public key directly from the server over some API. Below is a snippet of the API that our <a href="https://github.com/cloudflare/app-relay-gateway-go/blob/main/gateway.go#L116-L134">open source OHTTP server provides</a>:</p>
            <pre><code>func (s *GatewayResource) configHandler(w http.ResponseWriter, r *http.Request) {
	config, err := s.Gateway.Config(s.keyID)
	if err != nil {
		http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
		return
	}
	w.Write(config.Marshal())
}</code></pre>
            <p>Once public key generation and distribution is solved, the server then needs to handle encapsulated requests from clients. For each request, the server needs to decrypt the request, translate the plaintext to a corresponding HTTP request that can be resolved, and then encrypt the resulting response back to the client.</p><p>Open source OHTTP libraries typically offer functions for <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L455">request decryption</a> and <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L502-L541">response encryption</a>, whereas plaintext translation from <a href="https://datatracker.ietf.org/doc/html/rfc9292">binary HTTP</a> to an HTTP request is handled separately. For example, our open source server delegates this translation to a different library that is specific to how Go HTTP requests are represented in memory. In particular, the function to translate from a plaintext request to a <a href="https://pkg.go.dev/net/http#Request">Go HTTP request</a> is done with a function that has the following signature:</p>
            <pre><code>func UnmarshalBinaryRequest(data []byte) (*http.Request, error) {
	...
}</code></pre>
            <p>Conversely, translating a <a href="https://pkg.go.dev/net/http#Response">Go HTTP response</a> to a plaintext binary HTTP response message is done with a function that has the following signature:</p>
            <pre><code>type BinaryResponse http.Response

func (r *BinaryResponse) Marshal() ([]byte, error) {
	...
}</code></pre>
            <p>While there exist several open source libraries that one can use to implement OHTTP server support, we’ve packaged all of it up in our open source server implementation <a href="https://github.com/cloudflare/app-relay-gateway-go">available here</a>. It includes instructions for building, testing, and deploying to make it easy to get started.</p>
    <div>
      <h3>Client integration</h3>
      <a href="#client-integration">
        
      </a>
    </div>
    <p>Naturally, the client-side behavior of OHTTP mirrors that of the server. In particular, the client must:</p><ol><li><p>Discover or obtain the server public key; and</p></li><li><p>Encode and encrypt HTTP requests, send them to Privacy Gateway, and decrypt and decode the HTTP responses.</p></li></ol><p>Discovery of the server public key depends on the server’s chosen deployment model. For example, if the public key is available over an API, clients can simply fetch it directly:</p>
            <pre><code>$ curl https://server.example/ohttp-configs &gt; config.bin</code></pre>
            <p><a href="https://github.com/chris-wood/ohttp-go/blob/main/bhttp.go#L66">Encoding</a>, <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L321">encrypting</a>, <a href="https://github.com/chris-wood/ohttp-go/blob/main/ohttp.go#L373">decrypting</a>, and decoding are again best handled by OHTTP libraries when available. With these functions available, building client support is rather straightforward. A trivial example Go client using the library functions linked above is as follows:</p>
            <pre><code>configEnc := ... // encoded public key
config, err := ohttp.UnmarshalPublicConfig(configEnc)
if err != nil {
	return err
}

request, err := http.NewRequest(http.MethodGet, "https://test.example/index.html", nil)
if err != nil {
	return err
}

binaryRequest := ohttp.BinaryRequest(*request)
encodedRequest, err := binaryRequest.Marshal()
if err != nil {
	return err
}

ohttpClient := ohttp.NewDefaultClient(config)
encapsulatedReq, reqContext, err := ohttpClient.EncapsulateRequest(encodedRequest)

relayRequest, err := http.NewRequest(http.MethodPost, "https://relay.example", bytes.NewReader(encapsulatedReq.Marshal()))
if err != nil {
	return err
}
relayRequest.Header.Set("Content-Type", "message/ohttp-req")

client := http.Client{}
relayResponse, err := client.Do(relayRequest)
if err != nil {
	return err
}
bodyBytes, err := ioutil.ReadAll(relayResponse.Body)
if err != nil {
	return err
}
encapsulatedResp, err := ohttp.UnmarshalEncapsulatedResponse(bodyBytes)
if err != nil {
	return err
}

receivedResp, err := reqContext.DecapsulateResponse(encapsulatedResp)
if err != nil {
	return err
}

response, err := ohttp.UnmarshalBinaryResponse(receivedResp)
if err != nil {
	return err
}

fmt.Println(response)</code></pre>
            <p>A standalone client like this isn’t likely very useful to you if you have an existing application. To help integration into your existing application, we created a <a href="https://github.com/cloudflare/app-relay-client-library">sample OHTTP client library</a> that’s compatible with iOS and macOS applications. Additionally, if there’s language or platform support you would like to see to help ease integration on either or the client or server side, please let us know!</p>
    <div>
      <h2>Interested?</h2>
      <a href="#interested">
        
      </a>
    </div>
    <p>Privacy Gateway is currently in early access – available to select privacy-oriented companies and partners. If you’re interested, <a href="https://www.cloudflare.com/lp/privacy-edge/">please get in touch</a>.</p> ]]></content:encoded>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Standards]]></category>
            <guid isPermaLink="false">4KXLduwaLrRcnGTcApXBpH</guid>
            <dc:creator>Mari Galicer</dc:creator>
            <dc:creator>Christopher Wood</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare and the IETF]]></title>
            <link>https://blog.cloudflare.com/cloudflare-and-the-ietf/</link>
            <pubDate>Wed, 13 Oct 2021 12:59:37 GMT</pubDate>
            <description><![CDATA[ Cloudflare helps build a better Internet through collaboration on open and interoperable standards. This post will describe how Cloudflare contributes to the standardization process to enable incremental innovation and drive long-term architectural change. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>The Internet, far from being just a series of tubes, is a huge, incredibly complex, decentralized system. Every action and interaction in the system is enabled by a complicated mass of protocols woven together to accomplish their task, each handing off to the next like trapeze artists high above a virtual circus ring. Stop to think about details, and it is a marvel.</p><p>Consider one of the simplest tasks enabled by the Internet: Sending a message from sender to receiver.</p><p>The location (address) of a receiver is discovered using <a href="https://www.cloudflare.com/learning/dns/what-is-dns/">DNS</a>, a connection between sender and receiver is established using a transport protocol like TCP, and (hopefully!) secured with a protocol like TLS. The sender's message is encoded in a format that the receiver can recognize and parse, like HTTP, because the two disparate parties need a common language to communicate. Then, ultimately, the message is sent and carried in an IP datagram that is forwarded from sender to receiver based on routes established with BGP.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5Z79TEfHR8kGEqa8qMWBCQ/eecb98d60c7bbcbf5baae72ee10d8357/image1-35.png" />
            
            </figure><p>Even an explanation this dense is laughably oversimplified. For example, the four protocols listed are just the start, and ignore many others with acronyms of their own. The truth is that things are complicated. And because things are complicated, how these protocols and systems interact and influence the user experience on the Internet is complicated. Extra round trips to establish a secure connection increase the amount of time before useful work is done, harming user performance. The use of unauthenticated or unencrypted protocols reveals potentially sensitive information to the network or, worse, to malicious entities, which harms user security and privacy. And finally, consolidation and centralization — seemingly a prerequisite for reducing costs and protecting against attacks — makes it challenging to provide high availability even for essential services. (What happens when that one system goes down or is otherwise unavailable, or to extend our earlier metaphor, when a trapeze isn’t there to catch?)</p><p>These four properties — performance, security, privacy, and availability — are crucial to the Internet. At Cloudflare, and especially in the Cloudflare Research team, where we use all these various protocols, we're committed to improving them at every layer in the stack. We work on problems as diverse as <a href="https://www.cloudflare.com/network-security/">helping network security</a> and privacy with <a href="https://datatracker.ietf.org/doc/html/rfc8446">TLS 1.3</a> and <a href="https://datatracker.ietf.org/doc/html/rfc9000">QUIC,</a> improving DNS privacy via <a href="/oblivious-dns/">Oblivious DNS-over-HTTPS</a>, reducing end-user CAPTCHA annoyances with Privacy Pass and <a href="/introducing-cryptographic-attestation-of-personhood/">Cryptographic Attestation of Personhood (CAP)</a>, performing Internet-wide measurements to understand how things work in the real world, and much, much more.</p><p>Above all else, these projects are meant to do one thing: focus beyond the horizon to help build a better Internet. We do that by developing, advocating, and advancing open standards for the many protocols in use on the Internet, all backed by implementation, experimentation, and analysis.</p>
    <div>
      <h3>Standards</h3>
      <a href="#standards">
        
      </a>
    </div>
    <p>The Internet is a network of interconnected autonomous networks. Computers attached to these networks have to be able to route messages to each other. However, even if we can send messages back and forth across the Internet, much like the storied Tower of Babel, to achieve anything those computers have to use a common language, a lingua franca, so to speak. And for the Internet, standards are that common language.</p><p>Many of the parts of the Internet that Cloudflare is interested in are standardized by the IETF, which is a standards development organization responsible for producing technical specifications for the Internet's most important protocols, including IP, BGP, DNS, TCP, TLS, QUIC, HTTP, and so on. The <a href="https://www.ietf.org/about/mission/">IETF's mission</a> is:</p><p>&gt; to make the Internet work better by producing high-quality, relevant technical documents that influence the way people design, use, and manage the Internet.</p><p>Our individual contributions to the IETF help further this mission, especially given our role on the Internet. We can only do so much on our own to improve the end-user experience. So, through standards, we engage with those who use, manage, and operate the Internet to achieve three simple goals that lead to a better Internet:</p><p>1. Incrementally improve existing and deployed protocols with innovative solutions;</p><p>2. Provide holistic solutions to long-standing architectural problems and enable new use cases; and</p><p>3. Identify key problems and help specify reusable, extensible, easy-to-implement abstractions for solving them.</p><p>Below, we’ll give an example of how we helped achieve each goal, touching on a number of important technical specifications produced in recent years, including DNS-over-HTTPS, QUIC, and (the still work-in-progress) TLS Encrypted Client Hello.</p>
    <div>
      <h3>Incremental innovation: metadata privacy with DoH and ECH</h3>
      <a href="#incremental-innovation-metadata-privacy-with-doh-and-ech">
        
      </a>
    </div>
    <p>The Internet is not only complicated — it is leaky. Metadata seeps like toxic waste from nearly every protocol in use, from DNS to TLS, and even to HTTP at the application layer.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1t1ZVnKH9ZGQnKCgx6I8Pr/ada911c196fb971b19b8a4a3f7767362/image6-14.png" />
            
            </figure><p>One critically important piece of metadata that still leaks today is the name of the server that clients connect to. When a client opens a connection to a server, it reveals the name and identity of that server in many places, including DNS, TLS, and even sometimes at the IP layer (if the destination IP address is unique to that server). Linking client identity (IP address) to target server names enables third parties to build a profile of per-user behavior without end-user consent. The result is a set of protocols that does not respect end-user privacy.</p><p>Fortunately, it’s possible to incrementally address this problem without regressing security. For years, Cloudflare has been working with the standards community to plug all of these individual leaks through separate specialized protocols:</p><ul><li><p><a href="https://datatracker.ietf.org/doc/html/rfc8484">DNS-over-HTTPS</a> encrypts DNS queries between clients and recursive resolvers, ensuring only clients and trusted recursive resolvers see plaintext DNS traffic.</p></li><li><p><a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-13">TLS Encrypted Client Hello</a> encrypts metadata in the TLS handshake, ensuring only the client and authoritative TLS server see sensitive TLS information.</p></li></ul><p>These protocols impose a barrier between the client and server and everyone else. However, neither of them prevent the server from building per-user profiles. Servers can track users via one critically important piece of information: the client IP address. Fortunately, for the overwhelming majority of cases, the IP address is not essential for providing a service. For example, DNS recursive resolvers do not need the full client IP address to provide accurate answers, as is evidenced by the <a href="https://datatracker.ietf.org/doc/html/rfc7871">EDNS(0) Client Subnet</a> extension. To further reduce information exposure on the web, we helped push further with two more incremental improvements:</p><ul><li><p><a href="https://datatracker.ietf.org/doc/html/draft-pauly-dprive-oblivious-doh-07">Oblivious DNS-over-HTTPS</a> (ODoH) uses cryptography and network proxies to break linkability between client identity (IP address) and DNS traffic, ensuring that recursive resolvers have only the minimal amount of information to provide DNS answers -- the queries themselves, without any per-client information.</p></li><li><p><a href="https://datatracker.ietf.org/doc/html/draft-ietf-masque-h3-datagram-04">MASQUE</a> is standardizing techniques for proxying UDP and IP protocols over QUIC connections, similar to the existing <a href="https://www.rfc-editor.org/rfc/rfc7231.html#section-4.3.6">HTTP CONNECT</a> method for TCP-based protocols. Generally, the CONNECT method allows clients to use services without revealing any client identity (IP address).</p></li></ul><p>While each of these protocols may seem only an incremental improvement over what we have today, together, they raise many possibilities for the future of the Internet. Are DoH and ECH sufficient for end-user privacy, or are technologies like ODoH and MASQUE necessary? How do proxy technologies like MASQUE complement or even subsume protocols like ODoH and ECH? These are questions the Cloudflare Research team strives to answer through experimentation, analysis, and deployment together with other stakeholders on the Internet through the IETF. And we could not ask the questions without first laying the groundwork.</p>
    <div>
      <h3>Architectural advancement: QUIC and HTTP/3</h3>
      <a href="#architectural-advancement-quic-and-http-3">
        
      </a>
    </div>
    <p><a href="https://quicwg.org">QUIC</a> and <a href="https://datatracker.ietf.org/doc/html/draft-ietf-quic-http-34">HTTP/3</a> are transformative technologies. Whilst the TLS handshake forms the heart of QUIC’s security model, QUIC is an improvement beyond TLS over TCP, in many respects, including more encryption (privacy), better protection against active attacks and ossification at the network layer, fewer round trips to establish a secure connection, and generally better security properties. QUIC and HTTP/3 give us a clean slate for future innovation.</p><p>Perhaps one of QUIC’s most important contributions is that it challenges and even breaks many established conventions and norms used on the Internet. For example, the antiquated socket API for networking, which treats the network connection as an in-order bit pipe is no longer appropriate for modern applications and developers. Modern networking APIs such as Apple’s <a href="https://developer.apple.com/documentation/network">Network.framework</a> provide high-level interfaces that take advantage of the new transport features provided by QUIC. Applications using this or even higher-level HTTP abstractions can take advantage of the many security, privacy, and performance improvements of QUIC and HTTP/3 today with minimal code changes, and without being constrained by sockets and their inherent limitations.</p><p>Another salient feature of QUIC is its wire format. Nearly every bit of every QUIC packet is encrypted and authenticated between sender and receiver. And within a QUIC packet, individual frames can be rearranged, repackaged, and otherwise transformed by the sender.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4qpdpgnX8A8M6iHvf0ECWP/aae602a63abed5400ffa431b4ce3cdce/image2-22.png" />
            
            </figure><p>Together, these are powerful tools to help mitigate future network ossification and enable continued extensibility. (TLS’s wire format ultimately led to the <a href="https://datatracker.ietf.org/doc/html/rfc8446#appendix-D.4">middlebox compatibility mode</a> for TLS 1.3 due to the many middlebox ossification problems that were encountered during early deployment tests.)</p><p>Exercising these features of QUIC is important for the <a href="https://datatracker.ietf.org/doc/html/draft-iab-use-it-or-lose-it-03">long-term health</a> of the protocol and applications built on top of it. Indeed, this sort of extensibility is what enables innovation.</p><p>In fact, we've already seen a flurry of new work based on QUIC: extensions to enable multipath QUIC, different congestion control approaches, and ways to carry data unreliably in the DATAGRAM frame.</p><p>Beyond functional extensions, we’ve also seen a number of new use cases emerge as a result of QUIC. DNS-over-QUIC is an upcoming proposal that complements DNS-over-TLS for recursive to authoritative DNS query protection. As mentioned above, MASQUE is a working group focused on standardizing methods for proxying arbitrary UDP and IP protocols over QUIC connections, enabling a number of fascinating solutions and unlocking the future of proxy and VPN technologies. In the context of the web, the WebTransport working group is standardizing methods to use QUIC as a “supercharged WebSocket” for transporting data efficiently between client and server while also depending on the WebPKI for security.</p><p>By definition, these extensions are nowhere near complete. The future of the Internet with QUIC is sure to be a fascinating adventure.</p>
    <div>
      <h3>Specifying abstractions: Cryptographic algorithms and protocol design</h3>
      <a href="#specifying-abstractions-cryptographic-algorithms-and-protocol-design">
        
      </a>
    </div>
    <p>Standards allow us to build abstractions. An ideal standard is one that is usable in many contexts and contains all the information a sufficiently skilled engineer needs to build a compliant implementation that successfully interoperates with other independent implementations. Writing a new standard is sort of like creating a new Lego brick. Creating a new Lego brick allows us to build things that we couldn’t have built before. For example, one new “brick” that’s nearly finished (as of this writing) is <a href="https://www.ietf.org/archive/id/draft-irtf-cfrg-hpke-12.html">Hybrid Public Key Encryption (HPKE)</a>. HPKE allows us to efficiently encrypt arbitrary plaintexts under the recipient’s public key.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5eWRfVLYtCcnUohsI2X8SE/48ccbddb899b98e65baea220bd7c06f6/image4-21.png" />
            
            </figure><p>Mixing asymmetric and symmetric cryptography for efficiency is a common technique that has been used for many years in all sorts of protocols, from TLS to <a href="https://en.wikipedia.org/wiki/Pretty_Good_Privacy">PGP</a>. However, each of these applications has come up with their own design, each with its own security properties. HPKE is intended to be a single, standard, interoperable version of this technique that turns this complex and technical corner of protocol design into an easy-to-use black box. The standard has undergone extensive analysis by cryptographers throughout its development and has numerous implementations available. The end result is a simple abstraction that protocol designers can include without having to consider how it works under-the-hood. In fact, HPKE is already a dependency for a number of other draft protocols in the IETF, such as <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-13">TLS Encrypted Client Hello</a>, <a href="https://datatracker.ietf.org/doc/html/draft-pauly-dprive-oblivious-doh-07">Oblivious DNS-over-HTTPS</a>, and <a href="https://datatracker.ietf.org/doc/html/draft-ietf-mls-architecture-07.html">Message Layer Security</a>.</p>
    <div>
      <h3>Modes of Interaction</h3>
      <a href="#modes-of-interaction">
        
      </a>
    </div>
    <p>We engage with the IETF in the specification, implementation, experimentation, and analysis phases of a standard to help achieve our three goals of incremental innovation, architectural advancement, and production of simple abstractions.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/0tbHRFLSsWV7qBNiKi4WN/34d3b7742fe21500bcaa4970729bd4e6/image3-20.png" />
            
            </figure><p>Our participation in the standards process hits all four phases. Individuals in Cloudflare bring a diversity of knowledge and domain expertise to each phase, especially in the production of technical specifications. Today, we also published <a href="/exported-authenticators-the-long-road-to-rfc/">a blog post</a> about an upcoming standard that we’ve been working on for a number of years and will be sharing details about how we used formal analysis to make sure that we ruled out as many security issues in the design as possible. We work in close collaboration with people from all around the world as an investment in the future of the Internet. Open standards mean that everyone can take advantage of the latest and greatest in protocol design, whether they use Cloudflare or not.</p><p>Cloudflare’s scale and perspective on the Internet are essential to the standards process. We have experience rapidly implementing, deploying, and experimenting with emerging technologies to gain confidence in their maturity. We also have a proven track record of publishing the results of these experiments to help inform the standards process. Moreover, we open source as much of the code we use for these experiments as possible to enable reproducibility and transparency. Our unique collection of engineering expertise and wide perspective allows us to help build standards that work in a wide variety of use cases. By investing time in developing standards that everyone can benefit from, we can make a clear contribution to building a better Internet.</p><p>One final contribution we make to the IETF is more procedural and based around building consensus in the community. A challenge to any open process is gathering consensus to make forward progress and avoiding deadlock. We help build consensus through the production of running code, leadership on technical documents such as QUIC and ECH, and even logistically by chairing working groups. (Working groups at the IETF are chaired by volunteers, and Cloudflare numbers a few working group chairs amongst its employees, covering a broad spectrum of the IETF (and its related research-oriented group, the <a href="https://irtf.org/">IRTF</a>) from security and privacy to transport and applications.) Collaboration is a cornerstone of the standards process and a hallmark of Cloudflare Research, and we apply it most prominently in the standards process.</p><p>If you too want to help build a better Internet, check out some IETF Working Groups and mailing lists. All you need to start contributing is an Internet connection and an email address, so why not give it a go? And if you want to join us on our mission to help build a better Internet through open and interoperable standards, check out our <a href="https://www.cloudflare.com/careers/jobs/?department=Technology%20Research&amp;location=default">open</a> <a href="https://boards.greenhouse.io/cloudflare/jobs/3271134?gh_jid=3271134">positions</a>, <a href="/visiting-researcher-program/">visiting researcher program</a>, and <a href="https://www.cloudflare.com/careers/jobs/?department=University&amp;location=default">many internship opportunities</a>!</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[IETF]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Standards]]></category>
            <guid isPermaLink="false">72sMlOH9eqnKfiCmxSGHnU</guid>
            <dc:creator>Jonathan Hoyland</dc:creator>
            <dc:creator>Christopher Wood</dc:creator>
        </item>
        <item>
            <title><![CDATA[Exported Authenticators: The long road to RFC]]></title>
            <link>https://blog.cloudflare.com/exported-authenticators-the-long-road-to-rfc/</link>
            <pubDate>Wed, 13 Oct 2021 12:59:28 GMT</pubDate>
            <description><![CDATA[ Learn more about Exported Authenticators, a new extension to TLS, currently going through the IETF standardisation process. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Our earlier <a href="/cloudflare-and-the-ietf">blog post</a> talked in general terms about how we work with the IETF. In this post we’re going to talk about a particular IETF project we’ve been working on, Exported Authenticators (EAs). Exported Authenticators is a new extension to TLS that we think will prove really exciting. It unlocks all sorts of fancy new authentication possibilities, from TLS connections with multiple certificates attached, to logging in to a website without ever revealing your password.</p><p>Now, you might have thought that given the innumerable hours that went into the design of TLS 1.3 that it couldn’t possibly be improved, but it turns out that there are a number of places where the design falls a little short. TLS allows us to establish a secure connection between a client and a server. The TLS connection presents a certificate to the browser, which proves the server is authorised to use the name written on the certificate, for example <a href="/">blog.cloudflare.com</a>. One of the most common things we use that ability for is delivering webpages. In fact, if you’re reading this, your browser has already done this for you. The Cloudflare Blog is delivered over TLS, and by presenting a certificate for <a href="/">blog.cloudflare.com</a> the server proves that it’s allowed to deliver Cloudflare’s blog.</p><p>When your browser requests <a href="/">blog.cloudflare.com</a> you receive a big blob of HTML that your browser then starts to render. In the dim and distant past, this might have been the end of the story. Your browser would render the HTML, and display it. Nowadays, the web has become more complex, and the HTML your browser receives often tells it to go and load lots of other resources. For example, when I loaded the Cloudflare blog just now, my browser made 73 subrequests.</p><p>As we mentioned in our <a href="/connection-coalescing-experiments">connection coalescing</a> blog post, sometimes those resources are also served by Cloudflare, but on a different domain. In our connection coalescing experiment, we acquired certificates with a special extension, called a Subject Alternative Name (SAN), that tells the browser that the owner of the certificate can act as two different websites. Along with some further shenanigans that you can read about in our <a href="/connection-coalescing-experiments">blog post</a>, this lets us serve the resources for both the domains over a single TLS connection.</p><p>Cloudflare, however, services millions of domains, and we have millions of certificates. It’s possible to generate certificates that cover lots of domains, and in fact this is what Cloudflare used to do. We used to use so-called “<a href="https://dl.acm.org/doi/pdf/10.1145/2976749.2978301">cruise-liner</a>” certificates, with dozens of names on them. But for connection coalescing this quickly becomes impractical, as we would need to know what sub-resources each webpage might request, and acquire certificates to match. We switched away from this model because issues with individual domains could affect other customers.</p><p>What we’d like to be able to do is serve as much content as possible down a single connection. When a user requests a resource from a different domain they need to perform a new TLS handshake, <a href="/how-expensive-is-crypto-anyway/">costing valuable time and resources</a>. Our connection coalescing experiment showed the benefits when we know in advance what resources are likely to be requested, but most of the time we don’t know what subresources are going to be requested until the requests actually arrive. What we’d rather do is attach extra identities to a connection after it’s been established, and we know what extra domains the client actually wants. Because the TLS connection is just a transport mechanism and doesn’t understand the information being sent across it, it doesn’t actually know what domains might subsequently be requested. This is only available to higher-layer protocols such as HTTP. However, we don’t want any website to be able to impersonate another, so we still need to have strong authentication.</p>
    <div>
      <h3>Exported Authenticators</h3>
      <a href="#exported-authenticators">
        
      </a>
    </div>
    <p>Enter Exported Authenticators. They give us even more than we asked for. They allow us to do application layer authentication that’s just as strong as the authentication you get from TLS, and then tie it to the TLS channel. Now that’s a pretty complicated idea, so let’s break it down.</p><p>To understand application layer authentication we first need to explain what the application layer is. The application layer is a reference to the <a href="https://www.cloudflare.com/learning/ddos/glossary/open-systems-interconnection-model-osi/">OSI model</a>. The OSI model describes the various layers of abstraction we use, to make things work across the Internet. When you’re developing your latest web application you don’t want to have to worry about how light is flickered down a fibre optic cable, or even how the TLS handshake is encoded (although that’s a fascinating topic in its own right, let’s leave that for another time.)</p><p>All you want to care about is having your content delivered to your end-user, and using TLS gives you a guaranteed in-order, reliable, authenticated channel over which you can communicate. You just shove bits in one end of the pipe, and after lots of blinky lights, fancy routing, maybe a touch of congestion control, and a little decoding, *poof*, your data arrives at the end-user.</p><p>The application layer is the top of the OSI stack, and contains things like HTTP. Because the TLS handshake is lower in the stack, the application is oblivious to this process. So, what Exported Authenticators give us is the ability for the very top of the stack to reliably authenticate their partner.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5gnmKyKSeUeRR2kNpasByF/ce60689aede76d539b46a440ac9c87f8/osi-model-7-layers-1.png" />
            
            </figure><p>The seven-layered OSI model</p><p>Now let’s jump back a bit, and discuss what we mean when we say that EAs give us authentication that’s as strong as TLS authentication. TLS, as we know, is used to create a secure connection between two endpoints, but lots of us are hazy when we try and pin down exactly what we mean by “secure”. The TLS standard makes <a href="https://datatracker.ietf.org/doc/html/rfc8446#appendix-E.1">eight specific promises</a>, but rather than get buried in that particular ocean of weeds, let’s just pick out the one guarantee that we care about most: Peer Authentication.</p>
            <pre><code>Peer authentication: The client's view of the peer identity should reflect the server's identity. [...]</code></pre>
            <p>In other words, if the client thinks that it’s talking to <code>example.com</code> then it should, in fact, be talking to <code>example.com</code>.</p><p>What we want from EAs is that if I receive an EA then I have cryptographic proof that the person I’m talking to is the person I think I’m talking to. Now at this point you might be wondering what an EA actually looks like, and what it has to do with certificates. Well, an EA is actually a trio of messages, the first of which is a <code>Certificate</code>. The second is a <code>CertificateVerify</code>, a cryptographic proof that the sender knows the private key for the certificate. Finally there is a <code>Finished</code> message, which acts as a MAC, and proves the first two parts of the message haven’t been tampered with. If this structure sounds familiar to you, it’s because it’s the same structure as used by the server in the TLS handshake to prove it is the owner of the certificate.</p><p>The final piece of unpacking we need to do is explaining what we mean by tying the authentication to the TLS channel. Because EAs are an application layer construct they don’t provide any transport mechanism. So, whilst I know that the EA was created by the server I want to talk to, without binding the EA to a TLS connection I can’t be sure that I’m talking <i>directly</i> to the server I want.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1TE1tNAHGeIgpWWXLSo6d4/73aab69ccbfdcb00ba7819d8936df1d7/image5-16.png" />
            
            </figure><p>Without protection, a malicious server can move Exported Authenticators from one connection to another.</p><p>For all I know, the TLS server I’m talking to is creating a new TLS connection to the EA Server, and relaying my request, and then returning the response. This would be very bad, because it would allow a malicious server to impersonate any server that supports EAs.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1zeVsOVQkSEccH77eRqMQb/0868ebd0c27b34da59f32fa0837e3b29/image2-23.png" />
            
            </figure><p>Because EAs are bound to a single TLS connection, if a malicious server copies an EA from one connection to another it will fail to verify.</p><p>EAs therefore have an extra security feature. They use the fact that every TLS connection is guaranteed to produce a unique set of keys. EAs take one of these keys and use it to construct the EA. This means that if some malicious third-party copies an EA from one TLS session to another, the recipient wouldn’t be able to validate it. This technique is called <a href="https://datatracker.ietf.org/doc/html/rfc5056">channel binding</a>, and is another fascinating topic, but this post is already getting a bit long, so we’ll have to revisit channel binding in a future blog post.</p>
    <div>
      <h3>How the sausage is made</h3>
      <a href="#how-the-sausage-is-made">
        
      </a>
    </div>
    <p>OK, now we know what EAs do, let’s talk about how they were designed and built. EAs are going through the <a href="https://www.ietf.org/standards/process/informal/">IETF standardisation process</a>. Draft standards move through the IETF process starting as Internet Drafts (I-Ds), and ending up as published Requests For Comment (RFCs). RFCs are voluntary standards that underpin much of the global Internet plumbing, and not just for security protocols like TLS. RFCs define DNS, UDP, TCP, and many, many more.</p><p>The first step in producing a new IETF standard is coming up with a proposal. Designing security protocols is a very conservative business, firstly because it’s very easy to introduce really subtle bugs, and secondly, because if you do introduce a security issue, things can go very wrong, very quickly. A flaw in the design of a protocol can be especially problematic as it can be replicated across multiple independent implementations — for example the <a href="https://kryptera.se/Renegotiating%20TLS.pdf">TLS renegotiation vulnerabilities reported in 2009</a> and the <a href="https://dl.acm.org/doi/10.1145/2382196.2382206">custom EC(DH) parameters vulnerability from 2012</a>. To minimise the risks of design issues, EAs hew closely to the design of the TLS 1.3 handshake.</p>
    <div>
      <h3>Security and Assurance</h3>
      <a href="#security-and-assurance">
        
      </a>
    </div>
    <p>Before making a big change to how authentication works on the Internet, we want as much assurance as possible that we’re not going to break anything. To give us more confidence that EAs are secure, they reuse parts of the design of TLS 1.3. The TLS 1.3 design was carefully examined by dozens of experts, and underwent multiple rounds of formal analysis — more on that in a moment. Using well understood design patterns is a super important part of security protocols. Making something secure is incredibly difficult, because security issues can be introduced in thousands of ways, and an attacker only needs to find one. By starting from a well understood design we can leverage the years of expertise that went into it.</p><p>Another vital step in catching design errors early is baked into the IETF process: achieving rough consensus. Although the ins and outs of the IETF process are worthy of their own blog post, suffice it to say the IETF works to ensure that all technical objections get addressed, and even if they aren’t solved they are given due care and attention. Exported Authenticators were proposed way back in 2016, and after many rounds of comments, feedback, and analysis the TLS Working Group (WG) at the IETF has finally reached consensus on the protocol. All that’s left before the EA I-D becomes an RFC is for a final revision of the text to be submitted and sent to the RFC Editors, leading hopefully to a published standard very soon.</p><p>As we just mentioned, the WG has to come to a consensus on the design of the protocol. One thing that can hold up achieving consensus are worries about security. After the Snowden revelations there was a <a href="https://www.mitls.org/downloads/tlsauth.pdf">barrage</a> <a href="https://heartbleed.com/">of</a> <a href="https://www.openssl.org/~bodo/ssl-poodle.pdf">attacks</a> <a href="https://freakattack.com/">on</a> <a href="https://www.imperva.com/docs/HII_Attacking_SSL_when_using_RC4.pdf">TLS 1.2</a>, not to mention some even earlier attacks from academia. Changing how trust works on the Internet can be pretty scary, and the TLS WG didn’t want to be caught flat-footed. Luckily this coincided with the maturation of some tools and techniques we can use to get mathematical guarantees that a protocol is secure. This class of techniques is known as <a href="https://en.wikipedia.org/wiki/Formal_methods">formal methods</a>. To help ensure that people are confident in the security of EAs I performed a formal analysis.</p>
    <div>
      <h3>Formal Analysis</h3>
      <a href="#formal-analysis">
        
      </a>
    </div>
    <p>Formal analysis is a special technique that can be used to examine security protocols. It creates a mathematical description of the protocol, the security properties we want it to have, and a model attacker. Then, aided by some sophisticated software, we create a proof that the protocol has the properties we want even in the presence of our model attacker. This approach is able to catch incredibly subtle edge cases, which, if not addressed, could lead to attacks, as has <a href="https://cispa.saarland/group/cremers/downloads/papers/CHSV2016-TLS13.pdf">happened</a> <a href="https://hal.inria.fr/hal-01528752/document">before</a>. Trotting out a formal analysis gives us strong assurances that we haven’t missed any horrible issues. By sticking as closely as possible to the design of TLS 1.3 we were able to repurpose much of the original analysis for EAs, giving us a big leg up in our ability to prove their security. Our EA model is <a href="https://bitbucket.org/jhoyla/tamarin-exported-authenticators/src/master/">available in Bitbucket</a>, along with the proofs. You can check it out using <a href="https://tamarin-prover.github.io/">Tamarin</a>, a theorem prover for security protocols.</p><p>Formal analysis, and formal methods in general, give very strong guarantees that rule out entire classes of attack. However, they are not a panacea. TLS 1.3 was subject to a number of rounds of formal analysis, and yet <a href="https://eprint.iacr.org/2019/347.pdf">an attack</a> was still found. However, this attack in many ways confirms our faith in formal methods. The attack was found in a blind spot of the proof, showing that attackers have been pushed to the very edges of the protocol. As our formal analyses get more and more rigorous, attackers will have fewer and fewer places to search for attacks. As formal analysis has become more and more practical, more and more groups at the IETF have been asking to see proofs of security before standardising new protocols. This hopefully will mean that future attacks on protocol design will become rarer and rarer.</p><p>Once the EA I-D becomes an RFC, then all sorts of cool stuff gets unlocked — for example <a href="https://datatracker.ietf.org/doc/html/draft-sullivan-tls-opaque-01">OPAQUE-EA</a>s, which will allow us to do password-based login on the web without the server ever seeing the password! Watch this space.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5QK1yWnP1qWPVURzf9ZlIk/63325574b90a74a60ed147994cc197fc/image4-22.png" />
            
            </figure> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[TLS]]></category>
            <category><![CDATA[Cryptography]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[IETF]]></category>
            <guid isPermaLink="false">6DwixIOBiqkrJfubkZlOGa</guid>
            <dc:creator>Jonathan Hoyland</dc:creator>
        </item>
        <item>
            <title><![CDATA[Handshake Encryption: Endgame (an ECH update)]]></title>
            <link>https://blog.cloudflare.com/handshake-encryption-endgame-an-ech-update/</link>
            <pubDate>Tue, 12 Oct 2021 12:59:22 GMT</pubDate>
            <description><![CDATA[ In this post, we’ll dig into ECH details and describe what this protocol does to move the needle to help build a better Internet. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Privacy and security are fundamental to Cloudflare, and we believe in and champion the use of cryptography to help provide these fundamentals for customers, end-users, and the Internet at large. In the past, we helped <a href="/rfc-8446-aka-tls-1-3/">specify, implement, and ship TLS 1.3</a>, the latest version of the transport security protocol underlying the web, to all of our users. TLS 1.3 vastly improved upon prior versions of the protocol with respect to security, privacy, and performance: simpler cryptographic algorithms, more handshake encryption, and fewer round trips are just a few of the many great features of this protocol.</p><p>TLS 1.3 was a tremendous improvement over TLS 1.2, but there is still room for improvement. Sensitive metadata relating to application or user intent is still visible in plaintext on the wire. In particular, all client parameters, including the name of the target server the client is connecting to, are visible in plaintext. For obvious reasons, this is problematic from a privacy perspective: Even if your application traffic to crypto.cloudflare.com is encrypted, the fact you’re visiting crypto.cloudflare.com can be quite revealing.</p><p>And so, in collaboration with other participants in the standardization community and members of industry, <a href="/esni/">we embarked towards a solution</a> for encrypting all sensitive TLS metadata in transit. The result: <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-13">TLS Encrypted ClientHello (ECH)</a>, an extension to protect this sensitive metadata during connection establishment.</p><p>Last year, <a href="/encrypted-client-hello/">we described the current status of this standard</a> and its relation to the TLS 1.3 standardization effort, as well as ECH's predecessor, Encrypted SNI (ESNI). The protocol has come a long way since then, but when will we know when it's ready? There are many ways by which one can measure a protocol. Is it implementable? Is it easy to enable? Does it seamlessly integrate with existing protocols or applications? In order to assess these questions and see if the Internet is ready for ECH, the community needs deployment experience. Hence, for the past year, we’ve been focused on making the protocol stable, interoperable, and, ultimately, deployable. And today, we’re pleased to announce that we’ve begun our initial deployment of TLS ECH.</p><p>What does ECH mean for connection security and privacy on the network? How does it relate to similar technologies and concepts such as domain fronting? In this post, we’ll dig into ECH details and describe what this protocol does to move the needle to help build a better Internet.</p>
    <div>
      <h3>Connection privacy</h3>
      <a href="#connection-privacy">
        
      </a>
    </div>
    <p>For most Internet users, connections are made to perform some type of task, such as loading a web page, sending a message to a friend, purchasing some items online, or accessing bank account information. Each of these connections reveals some limited information about user behavior. For example, a connection to a messaging platform reveals that one might be trying to send or receive a message. Similarly, a connection to a bank or financial institution reveals when the user typically makes financial transactions. Individually, this metadata might seem harmless. But consider what happens when it accumulates: does the set of websites you visit on a regular basis uniquely identify you as a user? The safe answer is: yes.</p><p>This type of metadata is privacy-sensitive, and ultimately something that should only be known by two entities: the user who initiates the connection, and the service which accepts the connection. However, the reality today is that this metadata is known to more than those two entities.</p><p>Making this information private is no easy feat. The nature or intent of a connection, i.e., the name of the service such as crypto.cloudflare.com, is revealed in multiple places during the course of connection establishment: during DNS resolution, wherein clients map service names to IP addresses; and during connection establishment, wherein clients indicate the service name to the target server. (Note: there are other small leaks, though DNS and TLS are the primary problems on the Internet today.)</p><p>As is common in recent years, the solution to this problem is encryption. DNS-over-HTTPS (DoH) is a protocol for encrypting DNS queries and responses to hide this information from onpath observers. Encrypted Client Hello (ECH) is the complementary protocol for TLS.</p><p>The TLS handshake begins when the client sends a ClientHello message to the server over a TCP connection (or, in the context of <a href="https://datatracker.ietf.org/doc/html/rfc9000">QUIC</a>, over UDP) with relevant parameters, including those that are sensitive. The server responds with a ServerHello, encrypted parameters, and all that’s needed to finish the handshake.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6B6iYtQ5u2IZkww1qmL2SP/5d8eccfa2749e6907d2c4851bd741a9d/image1-28.png" />
            
            </figure><p>The goal of ECH is as simple as its name suggests: to encrypt the ClientHello so that privacy-sensitive parameters, such as the service name, are unintelligible to anyone listening on the network. The client encrypts this message using a public key it learns by making a DNS query for a special record known as the <a href="https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-07">HTTPS resource record</a>. This record advertises the server's various TLS and HTTPS capabilities, including ECH support. The server decrypts the encrypted ClientHello using the corresponding secret key.</p><p>Conceptually, DoH and ECH are somewhat similar. With DoH, clients establish an encrypted connection (HTTPS) to a DNS recursive resolver such as 1.1.1.1 and, within that connection, perform DNS transactions.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6uBrhlpXqeiYY1TVOxo6Wb/d1c4048e7fabb347af1e0e18e862ab06/image3-18.png" />
            
            </figure><p>With ECH, clients establish an encrypted connection to a TLS-terminating server such as crypto.cloudflare.com, and within that connection, request resources for an authorized domain such as cloudflareresearch.com.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5EIiZ1q7pBHrnNXSMHy5NJ/273f38bb845b3c6546bf71a6f8b6b80f/image5-14.png" />
            
            </figure><p>There is one very important difference between DoH and ECH that is worth highlighting. Whereas a DoH recursive resolver is specifically designed to allow queries for any domain, a TLS server is configured to allow connections for a select set of authorized domains. Typically, the set of authorized domains for a TLS server are those which appear on its certificate, as these constitute the set of names for which the server is authorized to terminate a connection.</p><p>Basically, this means the DNS resolver is <i>open</i>, whereas the ECH client-facing server is <i>closed</i>. And this closed set of authorized domains is informally referred to as the anonymity set. (This will become important later on in this post.) Moreover, the anonymity set is assumed to be public information. Anyone can query DNS to discover what domains map to the same client-facing server.</p><p>Why is this distinction important? It means that one cannot use ECH for the purposes of <i>connecting</i> to an authorized domain and then <i>interacting</i> with a different domain, a practice commonly referred to as <i>domain fronting</i>. When a client connects to a server using an authorized domain but then tries to interact with a different domain <i>within</i> that connection, e.g., by sending HTTP requests for an origin that does not match the domain of the connection, the request will fail.</p><p>From a high level, encrypting names in DNS and TLS may seem like a simple feat. However, as we’ll show, ECH demands a different look at security and an updated threat model.</p>
    <div>
      <h3>A changing threat model and design confidence</h3>
      <a href="#a-changing-threat-model-and-design-confidence">
        
      </a>
    </div>
    <p>The typical threat model for TLS is known as the <a href="https://en.wikipedia.org/wiki/Dolev%E2%80%93Yao_model">Dolev-Yao</a> model, in which an active network attacker can read, write, and delete packets from the network. This attacker’s goal is to derive the shared session key. There has been <a href="https://ieeexplore.ieee.org/document/7958594">a</a> <a href="https://eprint.iacr.org/2020/1044.pdf">tremendous</a> <a href="https://dl.acm.org/doi/10.1145/3133956.3134063">amount</a> <a href="https://www.research-collection.ethz.ch/bitstream/handle/20.500.11850/452409/main.pdf?sequence=8">of</a> <a href="https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.738.9908&amp;rep=rep1&amp;type=pdf">research</a> <a href="https://hal.inria.fr/hal-01674096/file/record.pdf">analyzing</a> <a href="https://link.springer.com/chapter/10.1007/978-3-662-53018-4_10">the</a> <a href="https://ieeexplore.ieee.org/abstract/document/7546517">security</a> of TLS to gain confidence that the protocol achieves this goal.</p><p>The threat model for ECH is somewhat stronger than considered in previous work. Not only should it be hard to derive the session key, it should also be hard for the attacker to determine the identity of the server from a <i>known anonymity set</i>. That is, ideally, it should have no more advantage in identifying the server than if it simply guessed from the set of servers in the anonymity set. And recall that the attacker is free to read, write, and modify any packet as part of the TLS connection. This means, for example, that an attacker can replay a ClientHello and observe the server’s response. It can also extract pieces of the ClientHello — including the ECH extension — and use them in its own modified ClientHello.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2UDOt4nL1dZujWFI6uVzLI/c17e28d83342592427b17ad55e208d61/image2-20.png" />
            
            </figure><p>The design of ECH ensures that this sort of attack is virtually impossible by ensuring the server certificate can only be decrypted by either the client or client-facing server.</p><p>Something else an attacker might try is masquerade as the server and actively interfere with the client to observe its behavior. If the client reacted differently based on whether the server-provided certificate was correct, this would allow the attacker to test whether a given connection using ECH was for a particular name.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4BSHqa7Vz8fRJqffZTtKht/efeb05714d785273db9571c73160b1a4/image4-18.png" />
            
            </figure><p>ECH also defends against this attack by ensuring that an attacker without access to the private ECH key material cannot actively inject anything into the connection.</p><p>The attacker can also be entirely passive and try to infer encrypted information from other visible metadata, such as packet sizes and timing. (Indeed, traffic analysis is an open problem for ECH and in general for TLS and related protocols.) Passive attackers simply sit and listen to TLS connections, and use what they see and, importantly, what they know to make determinations about the connection contents. For example, if a passive attacker knows that the name of the client-facing server is crypto.cloudflare.com, and it sees a ClientHello with ECH to crypto.cloudflare.com, it can conclude, with reasonable certainty, that the connection is to some domain in the anonymity set of crypto.cloudflare.com.</p><p>The number of potential attack vectors is astonishing, and something that the TLS working group has tripped over in prior iterations of the ECH design. Before any sort of real world deployment and experiment, we needed confidence in the design of this protocol. To that end, we are working closely with external researchers on a formal analysis of the ECH design which captures the following security goals:</p><ol><li><p>Use of ECH does not weaken the security properties of TLS without ECH.</p></li><li><p>TLS connection establishment to a host in the client-facing server’s anonymity set is indistinguishable from a connection to any other host in that anonymity set.</p></li></ol><p>We’ll write more about the model and analysis when they’re ready. Stay tuned!</p><p>There are plenty of other subtle security properties we desire for ECH, and some of these drill right into the most important question for a privacy-enhancing technology: Is this deployable?</p>
    <div>
      <h3>Focusing on deployability</h3>
      <a href="#focusing-on-deployability">
        
      </a>
    </div>
    <p>With confidence in the security and privacy properties of the protocol, we then turned our attention towards deployability. In the past, significant protocol changes to fundamental Internet protocols such as <a href="https://conferences.sigcomm.org/imc/2011/docs/p181.pdf">TCP</a> or <a href="https://datatracker.ietf.org/doc/html/rfc8446#appendix-D.4">TLS</a> have been complicated by some form of benign interference. Network software, like any software, is prone to bugs, and sometimes these bugs manifest in ways that we only detect when there’s a change elsewhere in the protocol. For example, TLS 1.3 unveiled middlebox ossification bugs that ultimately led to the <a href="https://datatracker.ietf.org/doc/html/rfc8446#appendix-D.4">middlebox compatibility mode</a> for TLS 1.3.</p><p>While itself just an extension, the risk of ECH exposing (or introducing!) similar bugs is real. To combat this problem, ECH supports a variant of <a href="https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-13#section-6.2">GREASE</a> whose goal is to ensure that all ECH-capable clients produce <i>syntactically equivalent</i> ClientHello messages. In particular, if a client supports ECH but does not have the corresponding ECH configuration, it uses GREASE. Otherwise, it produces a ClientHello with real ECH support. In both cases, the syntax of the ClientHello messages is equivalent.</p><p>This hopefully avoids network bugs that would otherwise trigger upon real or fake ECH. Or, in other words, it helps ensure that all ECH-capable client connections are treated similarly in the presence of benign network bugs or otherwise passive attackers. Interestingly, active attackers can easily distinguish -- with some probability -- between real or fake ECH. Using GREASE, the ClientHello carries an ECH extension, though its contents are effectively randomized, whereas a real ClientHello using ECH has information that will match what is contained in DNS. This means an active attacker can simply compare the ClientHello against what’s in the DNS. Indeed, anyone can query DNS and use it to determine if a ClientHello is real or fake:</p>
            <pre><code>$ dig +short crypto.cloudflare.com TYPE65
\# 134 0001000001000302683200040008A29F874FA29F884F000500480046 FE0D0042D500200020E3541EC94A36DCBF823454BA591D815C240815 77FD00CAC9DC16C884DF80565F0004000100010013636C6F7564666C 6172652D65736E692E636F6D00000006002026064700000700000000 0000A29F874F260647000007000000000000A29F884F</code></pre>
            <p>Despite this obvious distinguisher, the end result isn’t that interesting. If a server is capable of ECH and a client is capable of ECH, then the connection most likely used ECH, and whether clients and servers are capable of ECH is assumed public information. Thus, GREASE is primarily intended to ease deployment against benign network bugs and otherwise passive attackers.</p><p>Note, importantly, that GREASE (or fake) ECH ClientHello messages are semantically different from real ECH ClientHello messages. This presents a real problem for networks such as enterprise settings or school environments that otherwise use plaintext TLS information for the purposes of implementing various features like filtering or parental controls. (Encrypted DNS protocols like DoH also encountered similar obstacles in their deployment.) Fundamentally, this problem reduces to the following: How can networks securely disable features like DoH and ECH? Fortunately, there are a number of approaches that might work, with the more promising one centered around DNS discovery. In particular, if clients could securely discover encrypted recursive resolvers that can perform filtering in lieu of it being done at the TLS layer, then TLS-layer filtering might be wholly unnecessary. (Other approaches, such as the use of <a href="https://support.mozilla.org/en-US/kb/configuring-networks-disable-dns-over-https">canary domains</a> to give networks an opportunity to signal that certain features are not permitted, may work, though it’s not clear if these could or would be abused to disable ECH.)</p><p>We are eager to collaborate with browser vendors, network operators, and other stakeholders to find a feasible deployment model that works well for users without ultimately stifling connection privacy for everyone else.</p>
    <div>
      <h3>Next steps</h3>
      <a href="#next-steps">
        
      </a>
    </div>
    <p>ECH is rolling out for some FREE zones on our network in select geographic regions. We will continue to expand the set of zones and regions that support ECH slowly, monitoring for failures in the process. Ultimately, the goal is to work with the rest of the TLS working group and IETF towards updating the specification based on this experiment in hopes of making it safe, secure, usable, and, ultimately, deployable for the Internet.</p><p>ECH is one part of the connection privacy story. Like a leaky boat, it’s important to look for and plug all the gaps before taking on lots of passengers! Cloudflare Research is committed to these narrow technical problems and their long-term solutions. Stay tuned for more updates on this and related protocols.</p> ]]></content:encoded>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[TLS]]></category>
            <guid isPermaLink="false">796U3yTtzV0G33HROsW9Nu</guid>
            <dc:creator>Christopher Wood</dc:creator>
            <dc:creator>Christopher Patton</dc:creator>
        </item>
        <item>
            <title><![CDATA[OPAQUE: The Best Passwords Never Leave your Device]]></title>
            <link>https://blog.cloudflare.com/opaque-oblivious-passwords/</link>
            <pubDate>Tue, 08 Dec 2020 12:00:00 GMT</pubDate>
            <description><![CDATA[ Imagine passwords for online services that never leave your device, encrypted or otherwise. OPAQUE is a new cryptographic protocol that makes this idea possible, giving you and only you full control of your password. ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/ooidY51NqRXSzRAvVf2Kc/d952f9c1e38f135a535cbd1641b03d0f/Opaque-Header-1.png" />
            
            </figure><p><i>Update: On January 19, 2022, we added </i><a href="https://opaque-full.research.cloudflare.com/"><i>a new demo for the OPAQUE protocol</i></a><i>.</i></p><p>Passwords are a problem. They are a problem for reasons that are familiar to most readers. For us at Cloudflare, the problem lies much deeper and broader. Most readers will immediately acknowledge that passwords are hard to remember and manage, especially as password requirements grow increasingly complex. Luckily there are great software packages and browser add-ons to help manage passwords. Unfortunately, the greater underlying problem is beyond the reaches of software to solve.</p><p>The fundamental password problem is simple to explain, but hard to solve: A password that leaves your possession is guaranteed to sacrifice security, no matter its complexity or how hard it may be to guess. Passwords are insecure by their very existence.</p><p>You might say, “but passwords are always stored in encrypted format!” That would be great. More accurately, they are likely stored as a salted hash, as explained below. Even worse is that there is no way to verify the way that passwords are stored, and so we can assume that on some servers passwords are stored in cleartext. The truth is that even responsibly stored passwords can be leaked and broken, albeit (and thankfully) with enormous effort. An increasingly pressing problem stems from the nature of passwords themselves: any direct use of a password, today, means that the password must be handled in the clear.</p><p>You say, “but my password is transmitted securely over HTTPS!” This is true.</p><p>You say, “but I know the server stores my password in hashed form, secure so no one can access it!” Well, this puts a lot of faith in the server. Even so, let’s just say that yes, this may be true, too.</p><p>There remains, however, an important caveat — a gap in the end-to-end use of passwords. Consider that once a server receives a password, between being securely transmitted and securely stored, the password has to be read and processed. Yes, as cleartext!</p><p>And it gets worse — because so many are used to thinking in software, it’s easy to forget about the vulnerability of hardware. This means that even if the software is somehow trusted, the password must at some point reside in memory. The password must at some point be transmitted over a shared bus to the CPU. These provide vectors of attack to on-lookers in many forms. Of course, these attack vectors are far less likely than those presented by transmission and permanent storage, but they are no less severe (recent CPU vulnerabilities such as Spectre and Meltdown should serve as a stark reminder.)</p><p>The only way to fix this problem is to get rid of passwords altogether. There is hope! Research and private sector communities are working hard to do just that. New standards are emerging and growing mature. Unfortunately, passwords are so ubiquitous that it will take a long time to agree on and supplant passwords with new standards and technology.</p><p>At Cloudflare, we’ve been asking if there is something that can be done now, imminently. Today’s deep-dive into OPAQUE is one possible answer. OPAQUE is one among many examples of systems that enable a password to be useful without it ever leaving your possession. No one likes passwords, but as long they’re in use, at least we can ensure they are never given away.</p><p>I’ll be the first to admit that password-based authentication is annoying. Passwords are hard to remember, tedious to type, and notoriously insecure. Initiatives to reduce or replace passwords are promising. For example, <a href="/cloudflare-now-supports-security-keys-with-web-authentication-webauthn/">WebAuthn</a> is a standard for web authentication based primarily on public key cryptography using hardware <a href="https://github.com/github/SoftU2F">(or software)</a> tokens. Even so, passwords are frustratingly persistent as an authentication mechanism. Whether their persistence is due to their ease of implementation, familiarity to users, or simple ubiquity on the web and elsewhere, we’d like to make password-based authentication as secure as possible while they persist.</p><p>My internship at Cloudflare focused on OPAQUE, a cryptographic protocol that solves one of the most glaring security issues with password-based authentication on the web: though passwords are typically protected in transit by HTTPS, <b>servers</b> <b>handle them in plaintext</b> to check their correctness. Handling plaintext passwords is dangerous, as accidentally logging or caching them could lead to a catastrophic breach. The goal of the project, rather than to advocate for adoption of any particular protocol, is to show that OPAQUE is a viable option among many for authentication. Because the web case is most familiar to me, and likely many readers, I will use the web as my main example.</p>
    <div>
      <h3>Web Authentication 101: Password-over-TLS</h3>
      <a href="#web-authentication-101-password-over-tls">
        
      </a>
    </div>
    <p>When you type in a password on the web, what happens? The website must check that the password you typed is the same as the one you originally registered with the site. But how does this check work?</p><p>Usually, your username and password are sent to a server. The server then checks if the registered password associated with your username matches the password you provided. Of course, to prevent an attacker eavesdropping on your Internet traffic from stealing your password, your connection to the server should be encrypted via HTTPS (HTTP-over-TLS).</p><p>Despite use of HTTPS, there still remains a glaring problem in this flow: the server must store a representation of your password somewhere. Servers are hard to secure, and breaches are all too common. Leaking this representation can cause catastrophic security problems. (For records of the latest breaches, check out <a href="https://haveibeenpwned.com/">https://haveibeenpwned.com/</a>).</p><p>To make these leaks less devastating, servers often apply a <i>hash function</i> to user passwords. A hash function maps each password to a unique, random-looking value. It’s easy to apply the hash to a password, but almost impossible to reverse the function and retrieve the password. (That said, anyone can guess a password, apply the hash function, and check if the result is the same.)</p><p>With password hashing, plaintext passwords are no longer stored on servers.  An attacker who steals a password database no longer has direct access to passwords. Instead, the attacker must apply the hash to many possible passwords and compare the results with the leaked hashes.</p><p>Unfortunately, if a server hashes only the passwords, attackers can download precomputed <i>rainbow tables</i> containing hashes of trillions of possible passwords and almost instantly retrieve the plaintext passwords. (See <a href="https://project-rainbowcrack.com/table.htm">https://project-rainbowcrack.com/table.htm</a> for a list of some rainbow tables).</p><p>With this in mind, a good defense-in-depth strategy is to use <i>salted</i> hashing, where the server hashes your password appended to a random, per-user value called a <i>salt</i>. The server also saves the salt alongside the username, so the user never sees or needs to submit it. When the user submits a password, the server re-computes this hash function using the salt. An attacker who steals password data, i.e., the password representations and salt values, must then guess common passwords one by one and apply the (salted) hash function to each guessed password. Existing rainbow tables won’t help because they don’t take the salts into account, so the attacker needs to make a new rainbow table for each user!</p><p>This (hopefully) slows down the attack enough for the service to inform users of a breach, so they can change their passwords. In addition, the salted hashes should be <i>hardened</i> by applying a hash many times to further slow attacks. (See <a href="/keeping-passwords-safe-by-staying-up-to-date/">https://blog.cloudflare.com/keeping-passwords-safe-by-staying-up-to-date/</a> for a more detailed discussion).</p><p>These two mitigation strategies — encrypting the password in transit and storing salted, hardened hashes — are the current best practices.</p><p>A large security hole remains open. <i>Password-over-TLS</i> (as we will call it) requires users to <b>send plaintext passwords to servers during login</b>, because servers must see these passwords to match against registered passwords on file. Even a well-meaning server could accidentally cache or log your password attempt(s), or become corrupted in the course of checking passwords. (For example, Facebook detected in 2019 that it had <a href="https://about.fb.com/news/2019/03/keeping-passwords-secure/">accidentally been storing hundreds of millions of plaintext user passwords</a>). Ideally, servers should never see a plaintext password at all.</p><p>But that’s quite a conundrum: how can you check a password if you never see the password? Enter OPAQUE: a Password-Authenticated Key Exchange (PAKE) protocol that simultaneously proves knowledge of a password and derives a secret key. Before describing OPAQUE in detail, we’ll first summarize PAKE functionalities in general.</p>
    <div>
      <h3>Password Proofs with Password-Authenticated Key Exchange</h3>
      <a href="#password-proofs-with-password-authenticated-key-exchange">
        
      </a>
    </div>
    <p>Password-Authenticated Key Exchange (PAKE) was proposed by Bellovin and Merrit[1] in 1992, with an initial motivation of allowing password-authentication without the possibility of dictionary attacks based on data transmitted over an insecure channel.</p><p>Essentially, a plain, or <i>symmetric</i>, PAKE is a cryptographic protocol that allows two parties who share only a password to establish a strong shared secret key. The goals of PAKE are:</p><ol><li><p>The secret keys will match if the passwords match, and appear random otherwise.</p></li><li><p>Participants do not need to trust third parties (in particular, no Public Key Infrastructure),</p></li><li><p>The resulting secret key is not learned by anyone not participating in the protocol - including those who know the password.</p></li><li><p>The protocol does not reveal either parties’ password to each other (unless the passwords match), or to eavesdroppers.</p></li></ol><p>In sum, the only way to successfully attack the protocol is to guess the password correctly while participating in the protocol. (Luckily, such attacks can be mostly thwarted by rate-limiting, i.e, blocking a user from logging in after a certain number of incorrect password attempts).</p><p>Given these requirements, password-over-TLS is clearly <i>not</i> a PAKE, because:</p><ul><li><p>It relies on WebPKI, which places trust in third-parties called Certificate Authorities (see <a href="/introducing-certificate-transparency-and-nimbus/">https://blog.cloudflare.com/introducing-certificate-transparency-and-nimbus/</a> for an in-depth explanation of WebPKI and some of its shortcomings).</p></li><li><p>The user’s password is revealed to the server.</p></li><li><p>Password-over-TLS provides the user no assurance that the server knows their password or a derivative of it — a server could accept any input from the user with no checks whatsoever.</p></li></ul><p>That said, plain PAKE is still worse than Password-over-TLS, simply because it requires the server to <i>store</i> plaintext passwords. We need a PAKE that lets the server store salted hashes if we want to beat the current practice.</p><p>An improvement over plain PAKE is what’s called an <i>asymmetric</i> PAKE (aPAKE), because only the client knows the password, and the server knows a <i>hashed</i> password. An aPAKE has the four properties of PAKE, plus one more:</p><ol><li><p>An attacker who steals password data stored on the server must perform a dictionary attack to retrieve the password.</p></li></ol><p>The issue with most existing aPAKE protocols, however, is that they do not allow for a <i>salted</i> hash (or if they do, they require that salt to be transmitted to the user, which means the attacker has access to the salt beforehand and can begin computing a rainbow table for the user before stealing any data). We’d like, therefore, to upgrade the security property as follows:</p><p>5*) An attacker who steals password data stored on the server must perform a <i>per-user</i> dictionary attack to retrieve the password <i>after the data is compromised</i>.</p><p>OPAQUE is the first aPAKE protocol with a formal security proof that has this property: it allows for a completely secret salt.</p>
    <div>
      <h3>OPAQUE - Servers safeguard secrets without knowing them!</h3>
      <a href="#opaque-servers-safeguard-secrets-without-knowing-them">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/39WP72kgESNW6mjf08g5UM/db539617b444e7683825d02b9d704b14/opaque-wordmark.png" />
            
            </figure><p><a href="https://eprint.iacr.org/2018/163.pdf">OPAQUE</a> is what’s referred to as a <i>strong aPAKE</i>, which simply means that it resists these pre-computation attacks by using a secretly salted hash on the server. OPAQUE was proposed and formally analyzed by Stanislaw Jarecki, Hugo Krawcyzk and Jiayu Xu in 2018 (full disclosure: Stanislaw Jarecki is my academic advisor). The name OPAQUE is a combination of the names of two cryptographic protocols: OPRF and PAKE. We already know PAKE, but what is an OPRF? OPRF stands for Oblivious Pseudo-Random Function, which is a protocol by which two parties compute a function <i>F(key, x)</i> that is deterministic but outputs random-looking values. One party inputs the value <i>x</i>, and another party inputs the key - the party who inputs <i>x</i> learns the result <i>F(key, x)</i> but not the key, and the party providing the key learns nothing.  (You can dive into the math of OPRFs here: <a href="/privacy-pass-the-math/">https://blog.cloudflare.com/privacy-pass-the-math/</a>).</p><p>The core of OPAQUE is a method to store user secrets for safekeeping on a server, without giving the server access to those secrets. Instead of storing a traditional salted password hash, the server stores a secret envelope for you that is “locked” by two pieces of information: your password known only by you, and a random secret key (like a salt) known only by the server. To log in, the client initiates a cryptographic exchange that reveals the envelope key to the client, but, importantly, not to the server.</p><p>The server then sends the envelope to the user, who now can retrieve the encrypted keys. (The keys included in the envelope are a private-public key pair for the user, and a public key for the server.) These keys, once unlocked, will be the inputs to an Authenticated Key Exchange (AKE) protocol, which allows the user and server to establish a secret key which can be used to encrypt their future communication.</p><p>OPAQUE consists of two phases, being credential registration and login via key exchange.</p>
    <div>
      <h3>OPAQUE: Registration Phase</h3>
      <a href="#opaque-registration-phase">
        
      </a>
    </div>
    <p>Before registration, the user first signs up for a service and picks a username and password. Registration begins with the OPRF flow we just described: Alice (the user) and Bob (the server) do an OPRF exchange. The result is that Alice has a random key <b><i>rwd</i></b>, derived from the OPRF output <i>F(key, pwd), where key</i> is a server-owned OPRF key specific to Alice and <i>pwd</i> is Alice’s password.</p><p>Within his OPRF message, Bob sends the public key for his OPAQUE identity. Alice then generates a new private/public key pair, which will be her persistent OPAQUE identity for Bob’s service, and encrypts <i>her</i> private key along with <i>Bob’s</i> public key with the <b>rwd</b> (we will call the result an <i>encrypted envelope</i>). She sends this encrypted envelope along with her public key (unencrypted) to Bob, who stores the data she provided, along with Alice’s specific OPRF keysecret, in a database indexed by her username.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5FwREcK0qMw6EVKrxDjUyg/399a52baf731039c16d03644a57cb5f2/OPAQUE-diagram-1_3x.png" />
            
            </figure>
    <div>
      <h3>OPAQUE: Login Phase</h3>
      <a href="#opaque-login-phase">
        
      </a>
    </div>
    <p>The login phase is very similar. It starts the same way as registration — with an OPRF flow. However, on the server side, instead of generating a new OPRF key, Bob instead looks up the one he created during Alice’s registration. He does this by looking up Alice’s username (which she provides in the first message), and retrieving his record of her. This record contains her public key, her encrypted envelope, and Bob’s OPRF key for Alice.</p><p>He also sends over the encrypted envelope which Alice can decrypt with the output of the OPRF flow. (If decryption fails, she aborts the protocol — this likely indicates that she typed her password incorrectly, or Bob isn’t who he says he is). If decryption succeeds, she now has her own secret key and Bob’s public key. She inputs these into an AKE protocol with Bob, who, in turn, inputs his private key and her public key, which gives them both a fresh shared secret key.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/75WquAD9w7Z3AJ8RcBdtiF/03e77ccaad51380d96fcc8e1c395d1b8/OPAQUE-diagram-2_3x.png" />
            
            </figure>
    <div>
      <h3>Integrating OPAQUE with an AKE</h3>
      <a href="#integrating-opaque-with-an-ake">
        
      </a>
    </div>
    <p>An important question to ask here is: what AKE is suitable for OPAQUE? The <a href="https://tools.ietf.org/html/draft-irtf-cfrg-opaque-01">emerging CFRG specification</a> outlines several options, including 3DH and SIGMA-I. However, on the web, we already have an AKE at our disposal: TLS!</p><p>Recall that TLS is an AKE because it provides unilateral (and mutual) authentication with shared secret derivation. The core of TLS is a Diffie-Hellman key exchange, which by itself is <i>unauthenticated</i>, meaning that the parties running it have no way to verify who they are running it with. (This is a problem because when you log into your bank, or any other website that stores your private data, you want to be sure that they are who they say they are). Authentication primarily uses certificates, which are issued by trusted entities through a system called <a href="/how-to-build-your-own-public-key-infrastructure/">Public Key Infrastructure (PKI)</a>. Each certificate is associated with a secret key. To prove its identity, the server presents its certificate to the client, and signs the TLS handshake with its secret key.</p><p>Modifying this ubiquitous certificate-based authentication on the web is perhaps not the best place to start. Instead, an improvement would be to authenticate the TLS shared secret, <i>using</i> OPAQUE, after the TLS handshake completes. In other words, once a server is authenticated with its typical WebPKI certificate, clients could subsequently authenticate to the server. This authentication could take place “post handshake” in the TLS connection using OPAQUE.</p><p><a href="https://datatracker.ietf.org/doc/draft-ietf-tls-exported-authenticator/">Exported Authenticators</a> are one mechanism for “post-handshake” authentication in TLS. They allow a server or client to provide proof of an identity without setting up a new TLS connection. Recall that in the standard web case, the server establishes their identity with a certificate (proving, for example, that they are “cloudflare.com”). But if the same server also holds alternate identities, they must run TLS again to prove who they are.</p><p>The basic Exported Authenticator flow works resembles a classical challenge-response protocol, and works as follows. (We’ll consider the server authentication case only, as the client case is symmetric).</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3eYv5LQOx1cD9iTFxqfkAC/3231d07f2a1b4a140b345454dc2ca2e0/OPAQUE-diagram-3_3x.png" />
            
            </figure><p>At any point after a TLS connection is established, Alice (the client) sends an <i>authenticator request</i> to indicate that she would like Bob (the server) to prove an additional identity. This request includes a context (an unpredictable string — think of this as a challenge), and extensions which include information about what identity the client wants to be provided. For example, the client could include the SNI extension to ask the server for a certificate associated with a certain domain name other than the one initially used in the TLS connection.</p><p>On receipt of the client message, if the server has a valid certificate corresponding to the request, it sends back an <i>exported authenticator</i> which proves that it has the secret key for the certificate. (This message has the same format as an Auth message from the client in TLS 1.3 handshake - it contains a Certificate, a CertificateVerify and a Finished message). If the server cannot or does not wish to authenticate with the requested certificate, it replies with an empty authenticator which contains only a well formed Finished message.</p><p>The client then checks that the Exported Authenticator it receives is well-formed, and then verifies that the certificate presented is valid, and if so, accepts the new identity.</p><p>In sum, Exported Authenticators provide authentication in a higher layer (such as the application layer) safely by leveraging the well-vetted cryptography and message formats of TLS. Furthermore, it is tied to the TLS session so that authentication messages can't be copied and pasted from one TLS connection into another. In other words, Exported Authenticators provide exactly the right hooks needed to add OPAQUE-based authentication into TLS.</p>
    <div>
      <h3>OPAQUE with Exported Authenticators (OPAQUE-EA)</h3>
      <a href="#opaque-with-exported-authenticators-opaque-ea">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/13SUbsSrju6qTw13hFBhoh/8a41eefa575f8661b6c0b821d4516b72/OPAQUE-diagram-2_3x-1.png" />
            
            </figure><p><a href="https://datatracker.ietf.org/doc/html/draft-sullivan-tls-opaque-00">OPAQUE-EA</a> allows OPAQUE to run at any point after a TLS connection has already been set up. Recall that Bob (the server) will store his OPAQUE identity, in this case a signing key and verification key, and Alice will store her identity — encrypted — on Bob’s server. (The registration flow where Alice stores her encrypted keys is the same as in regular OPAQUE, except she stores a signing key, so we will skip straight to the login flow). Alice and Bob run two request-authenticate EA flows, one for each party, and OPAQUE protocol messages ride along in the extensions section of the EAs. Let’s look in detail how this works.</p><p>First, Alice generates her OPRF message based on her password. She creates an Authenticator Request asking for Bob’s OPAQUE identity, and includes (in the extensions field) her username and her OPRF message, and sends this to Bob over their established TLS connection.</p><p>Bob receives the message and looks up Alice’s username in his database. He retrieves her OPAQUE record containing her verification key and encrypted envelope, and his OPRF key. He uses the OPRF key on the OPRF message, and creates an Exported Authenticator proving ownership of his OPAQUE signing key, with an extension containing his OPRF message and the encrypted envelope. Additionally, he sends a new Authenticator Request asking Alice to prove ownership of her OPAQUE signing key.</p><p>Alice parses the message and completes the OPRF evaluation using Bob’s message to get output <i>rwd</i>, and uses <i>rwd</i> to decrypt the envelope. This reveals her signing key and Bob’s public key. She uses Bob’s public key to validate his Authenticator Response proof, and, if it checks out, she creates and sends an Exported Authenticator proving that she holds the newly decrypted signing key. Bob checks the validity of her Exported Authenticator, and if it checks out, he accepts her login.</p>
    <div>
      <h3>My project: OPAQUE-EA over HTTPS</h3>
      <a href="#my-project-opaque-ea-over-https">
        
      </a>
    </div>
    <p>Everything described above is supported by lots and lots of theory that has yet to find its way into practice. My project was to turn the theory into reality. I started with written descriptions of <a href="https://tools.ietf.org/html/draft-ietf-tls-exported-authenticator-13">Exported Authenticators</a>, <a href="https://tools.ietf.org/html/draft-irtf-cfrg-opaque-01">OPAQUE</a>, and a preliminary draft of <a href="https://tools.ietf.org/html/draft-sullivan-tls-opaque-00">OPAQUE-in-TLS</a>. My goal was to get from those to a working prototype.</p><p>My demo shows the feasibility of implementing OPAQUE-EA on the web, completely removing plaintext passwords from the wire, even encrypted. This provides a possible alternative to the current password-over-TLS flow with better security properties, but no visible change to the user.</p><p>A few of the implementation details are worth knowing. In computer science, abstraction is a powerful tool. It means that we can often rely on existing tools and APIs to avoid duplication of effort. In my project I relied heavily on <a href="https://github.com/bifurcation/mint">mint</a>, an open-source implementation of TLS 1.3 in Go that is great for prototyping. I also used <a href="https://github.com/cloudflare/circl/tree/master/oprf">CIRCL’s OPRF API</a>. I built libraries for Exported Authenticators, the core of OPAQUE, and OPAQUE-EA (which ties together the two).</p><p>I made the web demo by wrapping the OPAQUE-EA functionality in a simple HTTP server and client that pass messages to each other over HTTPS. Since a browser can’t run Go, I compiled from Go to WebAssembly (WASM) to get the Go functionality in the browser, and wrote a simple script in JavaScript to call the WASM functions needed.</p><p>Since current browsers do not give access to the underlying TLS connection on the client side, I had to implement a work-around to allow the client to access the exporter keys, namely, that the server simply computes the keys and sends them to the client over HTTPS. This workaround reduces the security of the resulting demo — it means that trust is placed in the server to provide the right keys. Even so, the user’s password is still safe, even if a malicious server provided bad keys— they just don’t have assurance that they actually previously registered with that server. However, in the future, browsers could include a mechanism to support exported keys and allow OPAQUE-EA to run with its full security properties.</p><p>You can explore my implementation <a href="https://github.com/cloudflare/opaque-ea">on Github</a>, and even follow the instructions to spin up your own OPAQUE-EA test server and client. I’d like to stress, however, that the implementation is meant as a proof-of-concept only, and must not be used for production systems without significant further review.</p>
    <div>
      <h3>OPAQUE-EA Limitations</h3>
      <a href="#opaque-ea-limitations">
        
      </a>
    </div>
    <p>Despite its great properties, there will definitely be some hurdles in bringing OPAQUE-EA from a proof-of-concept to a fully fledged authentication mechanism.</p><p><b>Browser support for TLS exporter keys.</b> As mentioned briefly before, to run OPAQUE-EA in a browser, you need to access secrets from the TLS connection called <i>exporter keys</i>. There is no way to do this in the current most popular browsers, so support for this functionality will need to be added.</p><p><b>Overhauling password databases.</b> To adopt OPAQUE-EA, servers need not only to update their password-checking logic, but also completely overhaul their password databases. Because OPAQUE relies on special password representations that can only be generated interactively, existing salted hashed passwords cannot be automatically updated to OPAQUE records. Servers will likely need to run a special OPAQUE registration flow on a user-by-user basis. Because OPAQUE relies on buy-in from both the client and the server, servers may need to support the old method for a while before all clients catch up.</p><p><b>Reliance on emerging standards.</b> OPAQUE-EA relies on OPRFs, which is in the process of standardization, and Exported Authenticators, a proposed standard. This means that support for these dependencies is not yet available in most existing cryptographic libraries, so early adopters may need to implement these tools themselves.</p>
    <div>
      <h3>Summary</h3>
      <a href="#summary">
        
      </a>
    </div>
    <p>As long as people still use passwords, we’d like to make the process as secure as possible. Current methods rely on the risky practice of handling plaintext passwords on the server side while checking their correctness. PAKEs, and (specifically aPAKEs) allow secure password login without ever letting the server see the passwords.</p><p>OPAQUE is also being explored within other companies. According to Kevin Lewi, a research scientist from the Novi Research team at Facebook, they are “excited by the strong cryptographic guarantees provided by OPAQUE and are actively exploring OPAQUE as a method for further safeguarding credential-protected fields that are stored server-side.”</p><p>OPAQUE is one of the best aPAKEs out there, and can be fully integrated into TLS. You can check out the core OPAQUE implementation <a href="https://github.com/cloudflare/opaque-core">here</a> and the demo TLS integration <a href="https://github.com/cloudflare/opaque-ea">here</a>. A running version of the demo is also available <a href="https://opaque.research.cloudflare.com/">here</a>. A Typescript client implementation of OPAQUE is coming soon. If you're interested in implementing the protocol, or encounter any bugs with the current implementation, please drop us a line at <a href="#">ask-research@cloudflare.com</a>! Consider also subscribing to the <a href="https://irtf.org/cfrg">IRTF CFRG mailing list</a> to track discussion about the OPAQUE specification and its standardization.</p><p>[1] Bellovin, S. M., and Merritt, M. “Encrypted key exchange: Password-based protocols secure against dictionary attacks.” In Proc. IEEE Computer Society Symposium on Research in Security and Privacy (Oakland, May 1992), pp. 72–84.</p> ]]></content:encoded>
            <category><![CDATA[Privacy Week]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Passwords]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[Security]]></category>
            <category><![CDATA[Salt]]></category>
            <guid isPermaLink="false">7daEt3ab6jwAnizdsMzbfl</guid>
            <dc:creator>Tatiana Bradley</dc:creator>
        </item>
        <item>
            <title><![CDATA[Good-bye ESNI, hello ECH!]]></title>
            <link>https://blog.cloudflare.com/encrypted-client-hello/</link>
            <pubDate>Tue, 08 Dec 2020 12:00:00 GMT</pubDate>
            <description><![CDATA[ A deep dive into the Encrypted Client Hello, a standard that encrypts privacy-sensitive parameters sent by the client, as part of the TLS handshake. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>Most communication on the modern Internet is encrypted to ensure that its content is intelligible only to the endpoints, i.e., client and server. Encryption, however, requires a key and so the endpoints must agree on an encryption key without revealing the key to would-be attackers. The most widely used cryptographic protocol for this task, called <i>key exchange,</i> is the <a href="https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/"><i>Transport Layer Security</i> (TLS)</a> handshake.</p><p>In this post we'll dive into <a href="https://tools.ietf.org/html/draft-ietf-tls-esni-08"><i>Encrypted Client Hello</i> (ECH)</a>, a new extension for TLS that promises to significantly enhance the privacy of this critical Internet protocol. Today, a number of privacy-sensitive parameters of the TLS connection are negotiated in the clear. This leaves a trove of metadata available to network observers, including the endpoints' identities, how they use the connection, and so on.</p><p>ECH encrypts the full handshake so that this metadata is kept secret. Crucially, this closes <a href="/esni/">a long-standing privacy leak</a> by protecting the <a href="https://www.cloudflare.com/learning/ssl/what-is-sni/"><i>Server Name Indication</i> (SNI)</a> from eavesdroppers on the network. Encrypting the SNI is important because it is the clearest signal of which server a given client is communicating with. However, and perhaps more significantly, ECH also lays the groundwork for adding future security features and performance enhancements to TLS while minimizing their impact on the privacy of end users.</p><p>ECH is the product of close collaboration, facilitated by the IETF, between academics and the tech industry leaders, including Cloudflare, our friends at Fastly and Mozilla (both of whom are the affiliations of co-authors of the standard), and many others. This feature represents a significant upgrade to the TLS protocol, one that builds on bleeding edge technologies, like <a href="/dns-encryption-explained/">DNS-over-HTTPS</a>, that are only now coming into their own. As such, the protocol is not yet ready for Internet-scale deployment. This article is intended as a sign post on the road to full handshake encryption.</p>
    <div>
      <h2>Background</h2>
      <a href="#background">
        
      </a>
    </div>
    <p>The story of TLS is the story of the Internet. As our reliance on the Internet has grown, so the protocol has evolved to address ever-changing operational requirements, use cases, and threat models. The client and server don't just exchange a key. They negotiate a wide variety of features and parameters: the exact method of key exchange; the encryption algorithm; who is authenticated and how; which application layer protocol to use after the handshake; and much, much more. All of these parameters impact the security properties of the communication channel in one way or another.</p><p>SNI is a prime example of a parameter that impacts the channel's security. <a href="https://tools.ietf.org/html/rfc6066">The SNI extension</a> is used by the client to indicate to the server the website it wants to reach. This is essential for the modern Internet, as it's common nowadays for many origin servers to sit behind a single TLS operator. In this setting, the operator uses the SNI to determine who will authenticate the connection: without it, there would be no way of knowing which <a href="https://www.cloudflare.com/application-services/products/ssl/">TLS certificate</a> to present to the client. The problem is that SNI leaks to the network the identity of the origin server the client wants to connect to, potentially allowing eavesdroppers to infer a lot of information about their communication. (Of course, there are other ways for a network observer to identify the origin — the origin's IP address, for example. But co-locating with other origins on the same IP address makes it much harder to use this metric to determine the origin than it is to simply inspect the SNI.)</p><p>Although protecting SNI is the impetus for ECH, it is by no means the only privacy-sensitive handshake parameter that the client and server negotiate. Another is the <a href="https://tools.ietf.org/html/rfc7301">ALPN extension</a>, which is used to decide which application-layer protocol to use once the TLS connection is established. The client sends the list of applications it supports — whether it's HTTPS, email, instant messaging, or the myriad other applications that use TLS for transport security — and the server selects one from this list, and sends its selection to the client. By doing so, the client and server leak to the network a clear signal of their capabilities and what the connection might be used for.</p><p>Some features are so privacy-sensitive that their inclusion in the handshake is a non-starter. <a href="https://tools.ietf.org/html/draft-barnes-tls-pake-04">One idea that has been floated</a> is to replace the key exchange at the heart of TLS with <a href="/opaque-oblivious-passwords"><i>password-authenticated</i> key-exchange (PAKE)</a>. This would allow password-based authentication to be used alongside (or in lieu of) certificate-based authentication, making TLS more robust and suitable for a wider range of applications. The privacy issue here is analogous to SNI: servers typically associate a unique identifier to each client (e.g., a username or email address) that is used to retrieve the client's credentials; and the client must, somehow, convey this identity to the server during the course of the handshake. If sent in the clear, then this personally identifiable information would be easily accessible to any network observer.</p><p>A necessary ingredient for addressing all of these privacy leaks is <i>handshake encryption</i>, i.e., the encryption of handshake messages in addition to application data. Sounds simple enough, but this solution presents another problem: how do the client and server pick an encryption key if, after all, the handshake is itself a means of exchanging a key? Some parameters <i>must</i> be sent in the clear, of course, so the goal of ECH is to encrypt all handshake parameters except those that are essential to completing the key exchange.</p><p>In order to understand ECH and the design decisions underpinning it, it helps to understand a little bit about the history of handshake encryption in TLS.</p>
    <div>
      <h3>Handshake encryption in TLS</h3>
      <a href="#handshake-encryption-in-tls">
        
      </a>
    </div>
    <p>TLS had no handshake encryption at all prior to the latest version, <a href="https://tools.ietf.org/html/rfc8446">TLS 1.3</a>. In the wake of the Snowden revelations in 2013, the IETF community <a href="https://tools.ietf.org/html/rfc7258">began to consider ways</a> of countering the threat that mass surveillance posed to the open Internet. When the process of standardizing TLS 1.3 began in 2014, one of its design goals was to encrypt as much of the handshake as possible. Unfortunately, the final standard falls short of full handshake encryption, and several parameters, including SNI, are still sent in the clear. Let's take a closer look to see why.</p><p>The TLS 1.3 protocol flow is illustrated in Figure 1. Handshake encryption begins as soon as the client and server compute a fresh shared secret. To do this, the client sends a <i>key share</i> in its ClientHello message, and the server responds in its ServerHello with its own key share. Having exchanged these shares, the client and server can derive a shared secret. Each subsequent handshake message is encrypted using the <i>handshake traffic key</i> derived from the shared secret. Application data is encrypted using a different key, called the <i>application traffic key</i>, which is also derived from the shared secret. These derived keys have different security properties: to emphasize this, they are illustrated with different colors.</p><p>The first handshake message that is encrypted is the server's EncryptedExtensions. The purpose of this message is to protect the server's sensitive handshake parameters, including the server's ALPN extension, which contains the application selected from the client's ALPN list. Key-exchange parameters are sent unencrypted in the ClientHello and ServerHello.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2Dya9l0Am8pUE5Ii0u58az/7eed911113649bdb11d583be8629795c/image4-11.png" />
            
            </figure><p><b>Figure 1:</b> The TLS 1.3 handshake.</p><p>All of the client's handshake parameters, sensitive or not, are sent in the ClientHello. Looking at Figure 1, you might be able to think of ways of reworking the handshake so that some of them can be encrypted, perhaps at the cost of additional latency (i.e., more <a href="https://www.cloudflare.com/learning/cdn/glossary/round-trip-time-rtt/">round trips</a> over the network). However, extensions like SNI create a kind of "chicken-and-egg" problem.</p><p>The client doesn't encrypt anything until it has verified the server's identity (this is the job of the Certificate and CertificateVerify messages) and the server has confirmed that it knows the shared secret (the job of the Finished message). These measures ensure the key exchange is <i>authenticated</i>, thereby preventing <a href="/monsters-in-the-middleboxes/">monster-in-the-middle (MITM)</a> attacks in which the adversary impersonates the server to the client in a way that allows it to decrypt messages sent by the client.  Because SNI is needed by the server to select the certificate, it needs to be transmitted before the key exchange is authenticated.</p><p>In general, ensuring confidentiality of handshake parameters used for authentication is only possible if the client and server <i>already share an encryption key</i>. But where might this key come from?</p><p><b>Full handshake encryption in the early days of TLS 1.3.</b> Interestingly, full handshake encryption was once proposed as a core feature of TLS 1.3. In early versions of the protocol (<a href="https://tools.ietf.org/html/draft-ietf-tls-tls13-10#section-6.2.2">draft-10</a>, circa 2015), the server would offer the client a long-lived public key during the handshake, which the client would use for encryption in subsequent handshakes. (This design came from a protocol called <a href="https://eprint.iacr.org/2015/978">OPTLS</a>, which in turn was borrowed from <a href="https://docs.google.com/document/d/1g5nIXAIkN_Y-7XJW5K45IblHd_L2f5LTaDUDwvZ5L6g/edit#heading=h.s0zksnx7d9oi">the original QUIC proposal</a>.) Called "0-RTT", the primary purpose of this mode was to allow the client to begin sending application data prior to completing a handshake. In addition, it would have allowed the client to encrypt its first flight of handshake messages following the ClientHello, including its own EncryptedExtensions, which might have been used to protect the client's sensitive handshake parameters.</p><p>Ultimately this feature was not included in the final standard (<a href="https://tools.ietf.org/html/rfc8446">RFC 8446</a>, published in 2018), mainly because its usefulness was outweighed by its added complexity. In particular, it does nothing to protect the initial handshake in which the client learns the server's public key. Parameters that are required for server authentication of the initial handshake, like SNI, would still be transmitted in the clear.</p><p>Nevertheless, this scheme is notable as the forerunner of other handshake encryption mechanisms, like ECH, that use public key encryption to protect sensitive ClientHello parameters. The main problem these mechanisms must solve is <i>key distribution</i>.</p>
    <div>
      <h3>Before ECH there was (and is!) ESNI</h3>
      <a href="#before-ech-there-was-and-is-esni">
        
      </a>
    </div>
    <p>The immediate predecessor of ECH was the <a href="https://tools.ietf.org/html/draft-ietf-tls-esni-02"><i>Encrypted SNI</i> (ESNI)</a> extension. As its name implies, the goal of ESNI was to provide confidentiality of the SNI. To do so, the client would encrypt its SNI extension under the server's public key and send the ciphertext to the server. The server would attempt to decrypt the ciphertext using the secret key corresponding to its public key. If decryption were to succeed, then the server would proceed with the connection using the decrypted SNI. Otherwise, it would simply abort the handshake. The high-level flow of this simple protocol is illustrated in Figure 2.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/24LqleKycQgsXAe0qKK6Yk/1bab0083757f0dab8e049f9bd0dbed45/image9-1.png" />
            
            </figure><p><b>Figure 2:</b> The TLS 1.3 handshake with the ESNI extension. It is identical to the TLS 1.3 handshake, except the SNI extension has been replaced with ESNI.</p><p>For key distribution, ESNI relied on another critical protocol: <a href="https://www.cloudflare.com/learning/dns/what-is-dns/"><i>Domain Name Service</i> (DNS)</a>. In order to use ESNI to connect to a website, the client would piggy-back on its standard A/AAAA queries a request for a TXT record with the ESNI public key. For example, to get the key for crypto.dance, the client would request the TXT record of _esni.crypto.dance:</p>
            <pre><code>$ dig _esni.crypto.dance TXT +short
"/wGuNThxACQAHQAgXzyda0XSJRQWzDG7lk/r01r1ZQy+MdNxKg/mAqSnt0EAAhMBAQQAAAAAX67XsAAAAABftsCwAAA="</code></pre>
            <p>The base64-encoded blob contains an ESNI public key and related parameters such as the encryption algorithm.</p><p>But what's the point of encrypting SNI if we're just going to leak the server name to network observers via a plaintext DNS query? Deploying ESNI this way became feasible with the introduction of <a href="/dns-encryption-explained/"><i>DNS-over-HTTPS</i></a> (DoH), which enables encryption of DNS queries to resolvers that provide the DoH service (1.1.1.1 is an example of such a service.). Another crucial feature of DoH is that it provides an authenticated channel for transmitting the ESNI public key from the DoH server to the client. This prevents <a href="/sad-dns-explained/">cache-poisoning attacks</a> that originate from the client's local network: in the absence of DoH, a local attacker could prevent the client from offering the ESNI extension by returning an empty TXT record, or coerce the client into using ESNI with a key it controls.</p><p>While ESNI took a significant step forward, it falls short of our goal of achieving full handshake encryption. Apart from being incomplete — it only protects SNI — it is vulnerable to <a href="https://tools.ietf.org/html/draft-ietf-tls-esni-08#section-10.10">a handful of sophisticated attacks</a>, which, while hard to pull off, point to theoretical weaknesses in the protocol's design that need to be addressed.</p><p>ESNI was <a href="/encrypted-sni/">deployed by Cloudflare</a> and <a href="https://blog.mozilla.org/security/2018/10/18/encrypted-sni-comes-to-firefox-nightly/">enabled by Firefox</a>, on an opt-in basis, in 2018, an  experience that laid bare some of the challenges with relying on DNS for key distribution. Cloudflare rotates its ESNI key every hour in order to minimize the collateral damage in case a key ever gets compromised. DNS artifacts are sometimes cached for much longer, the result of which is that there is a decent chance of a client having a stale public key. While Cloudflare's ESNI service tolerates this to a degree, every key must eventually expire. The question that the ESNI protocol left open is how the client should proceed if decryption fails <i>and</i> it can't access the current public key, via DNS or otherwise.</p><p>Another problem with relying on DNS for key distribution is that several endpoints might be authoritative for the same origin server, but have different capabilities. For example, a request for the A record of "example.com" might return one of two different IP addresses, each operated by a different <a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/">CDN</a>. The TXT record for "_esni.example.com" would contain the public key for one of these CDNs, but certainly not both. The DNS protocol does not provide a way of atomically tying together resource records that correspond to the same endpoint. In particular, it's possible for a client to inadvertently offer the ESNI extension to an endpoint that doesn't support it, causing the handshake to fail. Fixing this problem requires changes to the DNS protocol. (More on this below.)</p><p><b>The future of ESNI.</b> In the next section, we'll describe the ECH specification and how it addresses the shortcomings of ESNI. Despite its limitations, however, the practical privacy benefit that ESNI provides is significant. Cloudflare intends to continue its support for ESNI until ECH is production-ready.</p>
    <div>
      <h2>The ins and outs of ECH</h2>
      <a href="#the-ins-and-outs-of-ech">
        
      </a>
    </div>
    <p>The goal of ECH is to encrypt the entire ClientHello, thereby closing the gap left in TLS 1.3 and ESNI by protecting all privacy-sensitive handshake-parameters. Similar to ESNI, the protocol uses a public key, distributed via DNS and obtained using DoH, for encryption during the client's first flight. But ECH has improvements to key distribution that make the protocol more robust to DNS cache inconsistencies. Whereas the ESNI server aborts the connection if decryption fails, the ECH server attempts to complete the handshake and supply the client with a public key it can use to retry the connection.</p><p>But how can the server complete the handshake if it's unable to decrypt the ClientHello? As illustrated in Figure 3, the ECH protocol actually involves <i>two</i> ClientHello messages: the ClientHelloOuter, which is sent in the clear, as usual; and the ClientHelloInner, which is encrypted and sent as an extension of the ClientHelloOuter. The server completes the handshake with just one of these ClientHellos: if decryption succeeds, then it proceeds with the ClientHelloInner; otherwise, it proceeds with the ClientHelloOuter.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3C9ceBTx5AQXu8tS0lgzdF/55ea89f5a56843db15296b2b47f7b1c2/image3-17.png" />
            
            </figure><p><b>Figure 3:</b> The TLS 1.3 handshake with the ECH extension.</p><p>The ClientHelloInner is composed of the handshake parameters the client wants to use for the connection. This includes sensitive values, like the SNI of the origin server it wants to reach (called the <i>backend server</i> in ECH parlance), the ALPN list, and so on. The ClientHelloOuter, while also a fully-fledged ClientHello message, is not used for the intended connection. Instead, the handshake is completed by the ECH service provider itself (called the <i>client-facing server</i>), signaling to the client that its intended destination couldn't be reached due to decryption failure. In this case, the service provider also sends along the correct ECH public key with which the client can retry handshake, thereby "correcting" the client's configuration. (This mechanism is similar to how the server distributed its public key for 0-RTT mode in the early days of TLS 1.3.)</p><p>At a minimum, both ClientHellos must contain the handshake parameters that are required for a server-authenticated key-exchange. In particular, while the ClientHelloInner contains the real SNI, the ClientHelloOuter also contains an SNI value, which the client expects to verify in case of ECH decryption failure (i.e., the client-facing server). If the connection is established using the ClientHelloOuter, then the client is expected to immediately abort the connection and retry the handshake with the public key provided by the server. It's not necessary that the client specify an ALPN list in the ClientHelloOuter, nor any other extension used to guide post-handshake behavior. All of these parameters are encapsulated by the encrypted ClientHelloInner.</p><p>This design resolves — quite elegantly, I think — most of the challenges for securely deploying handshake encryption encountered by earlier mechanisms. Importantly, the design of ECH was not conceived in a vacuum. The protocol reflects the diverse perspectives of the IETF community, and its development dovetails with other IETF standards that are crucial to the success of ECH.</p><p>The first is an important new DNS feature known as the <a href="https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-02">HTTPS resource record type</a>. At a high level, this record type is intended to allow multiple HTTPS endpoints that are authoritative for the same <a href="https://www.cloudflare.com/learning/dns/glossary/what-is-a-domain-name/">domain name</a> to advertise different capabilities for TLS. This makes it possible to rely on DNS for key distribution, resolving one of the deployment challenges uncovered by the initial ESNI deployment. For a deep dive into this new record type and what it means for the Internet more broadly, check out Alessandro Ghedini's recent blog post on <a href="/speeding-up-https-and-http-3-negotiation-with-dns/">speeding up HTTPS with DNS</a>.</p><p>The second is the CFRG's <a href="https://tools.ietf.org/html/draft-irtf-cfrg-hpke-06"><i>Hybrid Public Key Encryption</i> (HPKE)</a> standard, which specifies an extensible framework for building public key encryption schemes suitable for a wide variety of applications. In particular, ECH delegates all of the details of its handshake encryption mechanism to HPKE, resulting in a much simpler and easier-to-analyze specification. (Incidentally, HPKE is also one of the main ingredients of <a href="/oblivious-dns">Oblivious DNS-over-HTTPS</a>.)</p>
    <div>
      <h2>The road ahead</h2>
      <a href="#the-road-ahead">
        
      </a>
    </div>
    <p>The current ECH specification is the culmination of a multi-year collaboration. At this point, the overall design of the protocol is fairly stable. In fact, the next draft of the specification will be the first to be targeted for interop testing among implementations. Still, there remain a number of details that need to be sorted out. Let's end this post with a brief overview of the road ahead.</p>
    <div>
      <h3>Resistance to traffic analysis</h3>
      <a href="#resistance-to-traffic-analysis">
        
      </a>
    </div>
    <p>Ultimately, the goal of ECH is to ensure that TLS connections made to different origin servers behind the same ECH service provider are indistinguishable from one another. In other words, when you connect to an origin behind, say, Cloudflare, no one on the network between you and Cloudflare should be able to discern which origin you reached, or which privacy-sensitive handshake-parameters you and the origin negotiated. Apart from an immediate privacy boost, this property, if achieved, paves the way for the deployment of new features for TLS without compromising privacy.</p><p>Encrypting the ClientHello is an important step towards achieving this goal, but we need to do a bit more. An important attack vector we haven't discussed yet is <a href="https://tools.ietf.org/html/draft-irtf-pearg-website-fingerprinting-01"><i>traffic analysis</i></a>. This refers to the collection and analysis of properties of the communication channel that betray part of the ciphertext's contents, but without cracking the underlying encryption scheme. For example, the <i>length</i> of the encrypted ClientHello might leak enough information about the SNI for the adversary to make an educated guess as to its value (this risk is especially high for domain names that are either particularly short or particularly long). It is therefore crucial that the length of each ciphertext is independent of the values of privacy-sensitive parameters. The current ECH specification provides some mitigations, but their coverage is incomplete. Thus, improving ECH's resistance to traffic analysis is an important direction for future work.</p>
    <div>
      <h3>The spectre of ossification</h3>
      <a href="#the-spectre-of-ossification">
        
      </a>
    </div>
    <p>An important open question for ECH is the impact it will have on network operations.</p><p>One of the lessons learned from the deployment of TLS 1.3 is that upgrading a core Internet protocol can trigger unexpected network behavior. Cloudflare was one of the first major TLS operators <a href="/introducing-tls-1-3/">to deploy TLS 1.3 at scale</a>; when browsers like Firefox and Chrome began to enable it on an experimental basis, <a href="/why-tls-1-3-isnt-in-browsers-yet/">they observed</a> a significantly higher rate of connection failures compared to TLS 1.2. The root cause of these failures was network <i>ossification</i>, i.e., the tendency of <i>middleboxes</i> — network appliances between clients and servers that monitor and sometimes intercept traffic — to write software that expects traffic to look and behave a certain way. Changing the protocol before middleboxes had the chance to update their software led to middleboxes trying to parse packets they didn't recognize, triggering software bugs that, in some instances, caused connections to be dropped completely.</p><p>This problem was so widespread that, instead of waiting for network operators to update their software, the design of TLS 1.3 was altered in order to mitigate the impact of network ossification. The ingenious solution was to make TLS 1.3 "look like" another protocol that middleboxes are known to tolerate. Specifically, the wire format and even the contents of handshake messages were made to resemble TLS 1.2. These two protocols aren't identical, of course — a curious network observer can still distinguish between them — but they look and behave similar enough to ensure that the majority of existing middleboxes don't treat them differently. Empirically, <a href="https://datatracker.ietf.org/meeting/100/materials/slides-100-tls-sessa-tls13/">it was found</a> that this strategy reduced the connection failure rate enough to make deployment of TLS 1.3 viable.</p><p>Once again, ECH represents a significant upgrade for TLS for which the spectre of network ossification looms large. The ClientHello contains parameters, like SNI, that have existed in the handshake for a long time, and we don't yet know what the impact will be of encrypting them. In anticipation of the deployment issues ossification might cause, the ECH protocol has been designed to look as much like a standard TLS 1.3 handshake as possible. The most notable difference is the ECH extension itself: if middleboxes ignore it — as they should, if they are compliant with the TLS 1.3 standard — then the rest of the handshake will look and behave very much as usual.</p><p>It remains to be seen whether this strategy will be enough to ensure the wide-scale deployment of ECH. If so, it is notable that this new feature will help to mitigate the impact of future TLS upgrades on network operations. Encrypting the full handshake reduces the risk of ossification since it means that there are less visible protocol features for software to ossify on. We believe this will be good for the health of the Internet overall.</p>
    <div>
      <h2>Conclusion</h2>
      <a href="#conclusion">
        
      </a>
    </div>
    <p>The old TLS handshake is (unintentionally) leaky. Operational requirements of both the client and server have led to privacy-sensitive parameters, like SNI, being negotiated completely in the clear and available to network observers. The ECH extension aims to close this gap by enabling encryption of the full handshake. This represents a significant upgrade to TLS, one that will help preserve end-user privacy as the protocol continues to evolve.</p><p>The ECH standard is a work-in-progress. As this work continues, Cloudflare is committed to doing its part to ensure this important upgrade for TLS reaches Internet-scale deployment.</p> ]]></content:encoded>
            <category><![CDATA[Privacy]]></category>
            <category><![CDATA[Privacy Week]]></category>
            <category><![CDATA[Research]]></category>
            <category><![CDATA[Protocols]]></category>
            <category><![CDATA[DNS]]></category>
            <category><![CDATA[TLS]]></category>
            <guid isPermaLink="false">7niJq6DaoM1Up9qzRLkwDQ</guid>
            <dc:creator>Christopher Patton</dc:creator>
        </item>
    </channel>
</rss>