Opened 19 months ago
Closed 19 months ago
#2502 closed defect (duplicate)
HTTP2 with non SSL causing downgrade to HTTP0.9 for HTTP1.0/HTTP1.1 clients
Reported by: | Óscar Vidaković | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | nginx-module | Version: | 1.22.x |
Keywords: | http2 http2 | Cc: | |
uname -a: | Linux ip-10-130-71-76 5.19.0-1025-aws #26~22.04.1-Ubuntu SMP Mon Apr 24 01:58:03 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.22.1
built with OpenSSL 3.0.2 15 Mar 2022 TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -ffile-prefix-map=/build/nginx-xFgJUM/nginx-1.22.1=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-compat --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_sub_module |
Description (last modified by )
I have an nginx installation with 2 servers, one listening HTTPS and one listening HTTP, both of them with http2 enabled in the listen directive. The HTTP server is quite simple and it's just used by an AWS ALB to perform healthchecks:
server {
listen 81 http2 default_server;
access_log off;
location /ping {
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}
The HTTPS is working just fine, but I cannot stablish successful connections to the HTTP server with non HTTP2 capable clients:
$ curl -v http://127.0.0.1:81 --http1.1
- Trying 127.0.0.1:81...
- Connected to 127.0.0.1 (127.0.0.1) port 81 (#0)
GET / HTTP/1.1
Host: 127.0.0.1:81
User-Agent: curl/7.81.0
Accept: */*
- Received HTTP/0.9 when not allowed
- Closing connection 0
curl: (1) Received HTTP/0.9 when not allowed
As you can see, even forcing curl to send HTTP1.1 headers, nginx is downgrading it to HTTP0.9, causing curl to reject the protocol and disconecting. Performing the same test in https works fine:
$ curl -o test -k -v https://127.0.0.1 --http1.1
- Trying 127.0.0.1:443...
Connected to 127.0.0.1 (127.0.0.1) port 443 (#0)
- ALPN, offering http/1.1
- SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
- ALPN, server accepted to use http/1.1
- Server certificate:
- subject: [NONE]
- start date: May 22 13:02:37 2023 GMT
- expire date: May 19 13:02:37 2033 GMT
- Server auth using Basic with user 'xxx'
GET / HTTP/1.1
Host: 127.0.0.1
Authorization: Basic <redacted>
User-Agent: curl/7.81.0
Accept: */*
- Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 30 May 2023 11:53:48 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: <redacted>
< Set-Cookie: <redacted>
<
As far as I understand, as long as the client is sending a HTTP protocol header, nginx should honour this header and try to serve this protocol instead of forcing to use the oldest one, specially when it's a protocol from begining 90s which now is considered ineficient.Also this is the behaviour being observed in HTTPS connections. The current behaviours leaves the HTTP servers with HTTP2 enabled in an almost non-funciontal state as most of the HTTP clients doesn't support HTTP0.9. For example AWS ALB is not capable to perform the healthchecks, curl is not working, nor wget, etc.
Change History (2)
comment:1 by , 19 months ago
Description: | modified (diff) |
---|
comment:2 by , 19 months ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
The
line in your configuration configures the listening socket on port 81 to use HTTP/2 with prior knowledge, see here. Attempts to use it with anything but HTTP/2 are rejected with appropriate HTTP/2 error.
If you want to use such socket in curl, consider
curl --http2-prior-knowledge
.Duplicate of #808.