1

An ERR_CONNECTION_REFUSED error occurs in Google Chrome v.120 while trying to leverage HTTP/3 via Nginx 1.25.3 + BoringSSL. No errors, neither debug messages are found in logs while nginx-debug is on, http2 works well with this config and https://cloudflare-quic.com/ says HTTP/3 can be used by the browser.

/etc/nginx/nginx.conf:

user  www-data;
worker_processes  1;

pid /var/run/nginx.pid;

events { worker_connections 1024; }

http { include mime.types; default_type application/octet-stream;

sendfile       on;
tcp_nopush     on;
tcp_nodelay    on;
types_hash_max_size 2048;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;


##
# Access/Error Log Settings
##

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;
error_log /var/log/nginx/error.log;

##
# SSL Configuration
##

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;


##
# FastCGI Cache Settings
##

fastcgi_cache_path /etc/nginx-cache levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_ignore_headers Cache-Control Expires;

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;

}

/etc/nginx/sites-enabled/website.conf:

server {
  server_name website.site;

root /var/www/website/public_html/develop; index index.html;

listen 443 quic reuseport; listen 443 ssl;

http2 on; http3 on;

quic_retry on; ssl_early_data on;

add_header alt-svc 'h3=":443"; quic=":443"; ma=2592000;';

ssl_protocols TLSv1.3;

ssl_certificate /etc/ssl/website.site.pem; ssl_certificate_key /etc/ssl/website.site-key.pem; }

UPD: Another interesting behavior I noticed is that the connection is redirected to another available nginx vhost (looks like the listen is ignored if quiche service is used)

My Solution: The problem turned to be that Google Chrome does not switch to HTTP/3 protocol if certificate is not publicly trusted (the solution was found here). Nevertheless, possible causes described here help to troubleshoot other errors

2 Answers2

1

Your web browser first establishes a http/1 or a http/2 connection. So you need to keep 2 listen directives. You should uncomment:

    # listen 443 ssl http2;

and replace by:

    listen 443 ssl;
    http2 on;

as http2 is not accepted anymore in the listen directive. It is a new directive disabled by default, see https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2

Syntax: http2 on | off;
Default:    
http2 off;
Context:    http, server
This directive appeared in version 1.25.1.

and https://nginx.org/en/docs/http/ngx_http_core_module.html#listen

"The parameter is deprecated, the http2 directive should be used instead."

See also this working example at https://nginx.org/en/docs/quic.html#example

http {
    log_format quic '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" "$http3"';
access_log logs/access.log quic;

server {
    # for better compatibility it's recommended
    # to use the same port for quic and https
    listen 8443 quic reuseport;
    listen 8443 ssl;

    ssl_certificate     certs/example.com.crt;
    ssl_certificate_key certs/example.com.key;

    location / {
        # required for browsers to direct them to quic port
        add_header Alt-Svc 'h3=":8443"; ma=86400';
    }
}

}

0

I found an example config and you need some more things in the vhost

server{
    listen 443 http3 quic reuseport;
    listen 443 ssl http2;
quic_retry on;
ssl_early_data on;

http3_max_field_size 5000;
http3_max_table_capacity 50;
http3_max_blocked_streams 30;
http3_max_concurrent_pushes 30;
http3_push 10;
http3_push_preload on;

add_header alt-svc '$quic=":443"; ma=3600';

index index.html index.nginx-debian.html; server_name yourdomain.com www.yourdomain.com

root /var/www/yourdomain.com;

ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; 

} server{ if ($host = http3.codefaq.org) { return 301 https://$host$request_uri; } # managed by Certbot

listen 80;

server_name yourdomain.com;
return 404; # managed by Certbot


}

See here https://codefaq.org/server/how-to-install-http-3-quic-on-nginx-server-for-ubuntu/#adding-boringssl-and-http3

Turdie
  • 2,945