HTTP v3 and HTTP v2 on a Citrix ADC / NetScaler
last update: February 28th 2022
HTTP/1.0 and HTTP/1.1 are dead. They are inefficient plain text protocols. The amount of data to be transferred is huge and latency is a big problem, mostly for intercontinental connections. But what alternatives do we have?
Are there alternatives?
A view on the history of HTTP
HTTP/0.9 – The one-line protocol
The initial version of HTTP had no version number; it was later called 0.9 on to differentiate it from later versions. HTTP/0.9 was extremely simple: requests consisted of a single line and started with the only possible method
GET followed by the path to the resource. The full URL wasn’t included as the protocol, server, and port weren’t necessary once connected to the server. Headers didn’t exist.
The response was extremely simple, too: it only consisted of the file itself. No
A very simple HTML page
Unlike subsequent evolutions, there were no HTTP headers. This meant that only HTML files could be transmitted. There were no status or error codes. If there was a problem, a specific HTML file was generated and included a description of the problem for human consumption.
HTTP/1.0 (RFC 1945) had been published as a standard in 1996. It is still there, but hardly ever used, as it had been replaced by HTTP/1.1 in 1997 almost immediately.
The HTTP protocol was standardized as HTTP/1.1 in 1997 (RFC 2616). Back then, in the late 1990s, we had plain text pages, not comparable with the current web pages. So the content, we transfer, is way more sophisticated nowadays. For a long time, there was a “grey” development about HTTP page definition features, driven by the competition for the best browser, mainly between Microsoft and Netscape. CERN in Geneva, the inventor of HTTP, either stayed out of it or refused to include the new extensions in the official standard. HTTP/1.1, the transport protocol, however, stayed the same over years.
HTTP/1.1 is based on TCP. A TCP connection has to be established first before the files can be loaded.
Google tried to create a new standard for its Chrome browsers called SPEEDY. The effort was adopted by the IESG 2014/2015 as HTTP/2 in RFC 2068.
HTTP/2 should solve the latency problem, but, at the same time, offer maximum compatibility with HTTP/1.1. Browsers should be able to “upgrade” connections from HTTP/1.1 to HTTP/2 if they are able to use it. Quoting from Wipipedia:
There are several approaches to achieving these goals:
- Create a negotiation mechanism that allows clients and servers to elect to use HTTP/1.1, 2.0 (or potentially other non-HTTP protocols).
- Maintain high-level compatibility with HTTP/1.1 (for example with methods, status codes, URIs, and most header fields).
- Decrease latency to improve page load speed in web browsers by considering:
- data compression of HTTP headers
- HTTP/2 Server Push
- >pipelining of requests
- fixing the head-of-line blocking problem in HTTP 1.x
- multiplexing multiple requests over a single TCP connection
- Support common existing use cases of HTTP, such as desktop web browsers, mobile web browsers, web APIs, web servers at various scales, proxy servers, reverse proxy servers, firewalls, and content delivery networks.
Unlike HTTP/1.1, HTTP/2 uses a single TCP connection and uses multiplexing. That means, data from multiple simultaneous requests is sent over the same connection. There is also the option of using server push: the server can send data to the client, which the client has not (yet) requested. For this reason, HTTP/2 is less expensive in terms of wasted resources on the server-side and, at the same time, more performant.
While HTTP/2 addressed several problems in HTTP/1.1, it also added a new one, “head-of-line blocking”: because the parallel nature of HTTP/2’s multiplexing is not visible to TCP’s loss recovery mechanisms, a lost or reordered packet causes all active transactions to experience a stall regardless of whether that transaction was impacted by the lost packet.
HTTP/2 can be used both unencrypted (h2c) and encrypted (h2). However, there is hardly any need for plain text HTML these days, so I’m focusing on HTTP/2 over SSL only.
HTTP/3 (introduced by Chrome browsers in 2019) brings a paradigm shift. No longer TCP, but UDP is used as the carrier protocol. The effects on the network are massive: We not only need new servers, but also new rules for firewalls, updates for proxy servers, and of course new protocols on the Citrix ADC. The new carrier protocol now is called QUIC (RFC 9000). The switch to QUIC aims to fix a major problem of HTTP/2: “head-of-line blocking”. Because QUIC provides native multiplexing, lost packets only impact the streams where data has been lost. On layer 7 in contrast, HTTP/3 is not very different from HTTP/2. HTTP/3 is a big step forward, and the IETF is proud of it.
HTTP / 3 is also much faster during the connection establishment phase. With HTTP / 2 we need to set up the TCP connection (3 packets) and then the SSL connection (at least 4 packets) before we actually send the request. In HTTP / 3 we don’t have a TCP session, SSL (TLS 1.3) is built into the protocol, so we end up in 4 UDP packets, the last one already contains the request.
In addition to the mentioned advantages of HTTP/3, there is also a very banal one: UDP can be routed faster than TCP. In contrast to TCP, the TTL for the recognition of loops is not protected by the header checksum. A router can therefore decrement it without having to calculate a new checksum. In fact, a router does not even need to check the checksum (and nowadays, most routers don’t do). That’s why UDP packets may overtake TCP packets on a router. So we can expect HTTP/3 to outperform HTTP/2 on long pipes (high latency connections).
Almost all current browsers benefit from HTTP/3, even though, there is still no RFC for HTTP/3 (9/21: A draft exists). Safari, however, still got no real support for HTTP/3, HTTP/3 is disabled by default (way to go, Apple!).
|Browser||Version implemented (disabled by default)||Version shipped (enabled by def.)|
|Chrome||Stable build (79)||December 2019||87||April 2020|
|Firefox||Stable build (72.0.1)||January 2020||88||April 2021|
Safari Tech. Preview 104
HTTP/3 is stable. It’s aready used by GGoogle, Cloudflare, and many others. The main reason for moving to HTTP/3 is speed. That’s what chromium.org found out:
We’ve found that IETF QUIC significantly outperforms HTTP over TLS 1.3 over TCP. In particular, Google search latency decreases by over 2%. YouTube rebuffer time decreased by over 9%, while client throughput increased by over 3% on desktop and over 7% on mobile. We’re happy to announce that Chrome is rolling out support for IETF QUIC (specifically, draft version h3-29). Today 25% of Chrome Stable users are using h3-29, and we plan on increasing that number over the coming weeks as we continue to monitor performance data. Chrome will actively support both IETF QUIC h3-29 and Google QUIC Q050 to provide servers that support Q050 with time to update to IETF QUIC.
The Citrix ADC / NetScaler implementation
Because the HTTP/2 protocol is technically very similar to HTTP/1.1, you don’t have to do any changes to the existing vServer. It is enough to turn on the protocol. To do this, you have to create an HTTP profile and activate HTTP/2.
I usually create a new HTTP profile by copying the built-in profile nshttp_default_strict_validation, and simply turn on HTTP/2. It is irrelevant, whether your server supports HTTP/2 or not: Citrix ADC is a proxy, so it can speak HTTP/1.1 to the backend, and – at the same time – HTTP/2 to the client.
add ns httpProfile nshttp_default_strict_validation_HTTP2 -dropInvalReqs ENABLED -markHttp09Inval ENABLED -markConnReqInval ENABLED -markTraceReqInval ENABLED -markRfc7230NonCompliantInval ENABLED -markHTTPHeaderExtraWSError ENABLED -webLog DISABLED -http2 ENABLED -http2Direct ENABLED
or, if you want to change the settings of an existing profile:
set ns httpProfile nshttp_default_strict_validation_HTTP2 -http2 ENABLED -http2Direct ENABLED
Enable HTTP/2: allow use of HTTP/2
Direct HTTP/2: allow a client to start the conversation using HTTP/2 (instead of upgrading from HTTP/1.1)
Alternate Service: The vServer advertises that it supports HTTP/2 to a client by including an Alternative Service (ALT-SVC) field in its HTTP/1.1 response.
In practical life, it’s sufficient to turn on the first two options. Leave the rest of the HTTP/2 settings alone (there is good documentation from Citrix). Bind this profile to your vServer, and you will see all connections using HTTP/2. We are done: Your server is now responding using HTTP/2. Your far away visitors will be
Attention: Currently (13.1 build 4.43), HTTP/3 is still experimental, experimental is the Citrix implementation as well. Don’t use it together with content-switching vServers. There are some GUI bugs, so some of the configurations have to be done from the command line.
There are hardly any requirements beyond the usual TLS 1.3 requirements: A trusted Certificate (2k or stronger), a proper Cipher group (the built-in TLS 1.3 cipher group is perfect, but you may create your own. Mine consists of TLS1.3-CHACHA20-POLY1305-SHA256, TLS1.3-AES256-GCM-SHA384 und TLS1.3-AES128-GCM-SHA256 in this order. Don’t use the CHACHA ciphers with physical appliances!). UDP port 443 has to be opened on your firewalls. A traditional TCP-based vServer with the same hostname. Firmware version 13 or above. That’s all you need.
I have a ns.conf for 13 available for download.
- copy the ns.conf file to /flash/nsconfig
- copy the two certificate files to /flash/nsconfig/ssl
Using the environment:
- NSIP: 192.168.229.10
- SNIP: 192.168.229.15
- VIP: 192.168.229.100
- Hostname: colors.training.lab
- nsroot-password: Password1
You may adapt IPs to your need by editing the ns.conf file prior to uploading it to your ADC. The environment uses my test and training environment (red/220.127.116.11, blue/18.104.22.168 and green/22.214.171.124 servers hosted by Wonderkitchen)
HTTP is a – by far – bigger step. As I wrote above, HTTP/3 is no longer based on TCP, but on UDP. Therefore you have to create a new vServer of the type HTTP_QUIC for HTTP/3 (in the unlikely event that your server already supports HTTP/3, please do not read any further, but follow these instructions). Similar to HTTP/2, the Citrix ADC / NetScaler also functions as an HTTP/3 proxy in the brave new HTTP/3 world: The connections into the data center still remain traditional HTTP/1.1 or HTTP/2 connections, while connections to the clients will be upgraded to HTTP/3.
Create a new vServer of type HTTP_QUICK with the same IP and port as used by your traditional SSL vServer. Apart from the HTTP profile, bind the same services, policies, and profiles as with the HTTP/1.1 oder HTTP/2 vServer. Bind the profile nshttp_default_http_quic_profile (or a profile you derived from it) to your new HTTP_QUIC vServer (if it’s not already bound). Your HTTP/3 vServer is ready for the action.
Wait. The vServer is not up? That’s strange. Let’s think. In order to create an SSL vServer, we also have to bind a certificate. Did we bind it? An SSL profile? No. We didn’t do so. But binding SSL settings is not in the GUI either (13.0 Build 83.27, 13.1 Build 4.43)! So we have to go to the command line.
bind ssl vserver lb_vs_colors_http3 -certkeyName training.lab
Great. Almost there. This SSL vServer has to support TLS 1.3, as TLS 1.3 is a requirement for HTTP/3. Unfortunately, the visitors of your website are not yet aware of it, so he/she would still use HTTP/2 or even HTTP/1.1. So you need to tell them about this great innovation. And this is done by adapting an HTTP profile.
I copy the existing profile nshttp_default_strict_validation. Then I turn on HTTP/2. I would now like to switch on “Alternative Service” and specify an alternative service string, but again this does not work in the GUI. Therefore I have to use the command line again. Citrix uses the following settings:
set httpProfile http_prof_strict_validation_http3 -altsvc ENABLED -altSvcValue "h3-29=\":443\"; ma=3600; persist=1"
This worked fine for me. It has to be bound to your existing SSL- vServer (TCP/443)
I did a little research to find out which alt-service values are used in practice. On Google today (October 25, 2021) the value is
"h3 =": 443 "; ma = 2592000, h3-29 =": 443 "; ma = 2592000, h3-Q050 =": 443 "; ma = 2592000, h3-Q046 = ": 443"; ma = 2592000, h3-Q043 = ": 443"; ma = 2592000".
What does that mean? :443 means, same server-name, UDP port 443. “h3” means HTTP/3, the final version. “h3-29” (32) IETF QUIC draft 29, h3-Q050 (46,43) Google QUIC draft 50 (46,43). Citrix ADC / NetScaler currently supports IETF QUIC version 29, 30, 31 and 32 (13.1 build 4.43). ma is the time in seconds a client is asked to use HTTP/3. 2,592,000 is 30 days sharp.
Therefore, I use the following command:
set httpProfile http_prof_strict_validation_http3 -altsvc ENABLED -altSvcValue "h3=\":443\"; ma=2592000, h3-29=\":443\"; ma=2592000, h3-30=\":443\"; ma=2592000, h3-31=\":443\"; ma=2592000, h3-32=\":443\"; ma=2592000"
There are many reasons why HTTP/3 won’t work. Starting with the most simple one:
- A firewall is blocking UDP/443
- Are connections via UDP/443 possible? Check using http3check.net. You could probably do a network trace during this test to see what’s going on. This works, independent of your altsvc settings.
- Your Citrix ADC is crashing? Currently, it does not work with content switching cServers (13.1 Build 4.43). At least, I could not make it work (that’s why this site does not utilize HTTP/3).
- The newly created HTTP profile is not bound to the traditional SSL vServer (TCP/443)
- The HTTP profile is broken (check the command line whether “-altsvc ENABLED” is activated and the altSvcValue is OK.
As always, I’d be curious about your ideas and concerns. Just drop me a message!