Search code examples
nginxnginx-reverse-proxycockpit

Reverse proxy with Cockpit uses HTTP2 when its server block doesn't, but main server block does


I have a main server block:

conf.d/mydomain.conf

server {
    listen      80;
    listen      [::]:80;
    server_name mydomain.com;
    return 301 https://$host$request_uri;
    }

server {
    listen       443 ssl;
    listen       [::]:443 ssl;
    server_name  mydomain.com;
    root         /var/www/mydomain.com;
    index       index.html index.php;

    include     modules/ssl.conf;

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

    location /           {
        try_files $uri $uri/ =404; autoindex on;
        }

    }

As well as a server block for a Cockpit reverse proxy:

conf.d/system.mydomain.com.conf

server {
    listen         80;
    listen         443 ssl;
    server_name    system.mydomain.com;

    location / {
        # Required to proxy the connection to Cockpit
        proxy_pass https://127.0.0.1:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Required for web sockets to function
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Pass ETag header from Cockpit to clients.
        # See: https://github.com/cockpit-project/cockpit/issues/5239
        gzip off;
    }
}

I also have a CNAME record from system.mydomain.com to mydomain.com.

This works well unless I want to make the main server block use HTTP2:

    listen       443 ssl http2;
    listen       [::]:443 ssl http2;

Then, logging into Cockpit at system.mydomain.com returns a page that only says protocol-error and the connection to system.mydomain.com returns a status code 500.

It there any way I can configure nginx to handle the Cockpit requests using HTTP 1.1 and all other traffic on HTTP2?


Solution

  • Unfortunately, you cannot run HTTP/1.1 and h2 on the same port (443). If you are able to choose a different port, you can of course work around the problem.

    If you make one server block http2, all other blocks with the same port implicitly also run on h2.

    I am of course only referring to Nginx here. I don't know how it is with Apache or HAProxy.