ubuntu18.04 Nginx配置quic支持(碰到的问题以及解决的步骤)

安装boringSSL:

git clone https://boringssl.googlesource.com/boringssl
cd boringssl
mkdir build
cd build
cmake ..

碰到的问题是cmake版本过低

卸载旧版本的CMake

如果通过包管理器安装了CMake,可以先卸载旧版本:

sudo apt remove cmake

然后安装更新版本的CMake,从CMake官网安装

  1. 下载CMake最新版本: 打开CMake官网并下载适合您系统的二进制文件。例如:

    wget https://github.com/Kitware/CMake/releases/download/v3.27.0/cmake-3.27.0-linux-x86_64.sh

  2. 安装CMake

    • 为安装文件添加执行权限:

      chmod +x cmake-3.27.0-linux-x86_64.sh

    • 运行安装脚本:

      sudo ./cmake-3.27.0-linux-x86_64.sh --prefix=/usr/local --skip-license

然后更新环境变量

~/.bashrc 中添加

export PATH=/usr/local/bin:$PATH

保存后重新加载配置文件

source ~/.bashrc  # 如果使用 Bash

再次验证CMake 版本,cmake —version

接下来接着构建boringssl

cmake ..
make

碰到这个报错

/boringssl/ssl/internal.h:3549:39: error: ‘bssl::DTLS1_STATE::queued_key_update’ is too small to hold all values of ‘enum class bssl::QueuedKeyUpdate’ [-Werror]
   QueuedKeyUpdate queued_key_update : 2;
                                       ^

查看枚举类型:

enum class QueuedKeyUpdate {
kNone,
kUpdateNotRequested,
kUpdateRequested,
};

最后boringssl安装参考这篇文章:

https://blog.csdn.net/liulilittle/article/details/141298738

不过这一步要在build中进行

cmake . &&  make

nginx-quic配置排查错误过程:

首先需要配置自签名证书:

  • 生成 CA
openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=My CA" -days 3650 -out ca.crt
  • 生成服务器密钥和 CSR
#video.local是本地域名
openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr -subj "/CN=video.local"
  • 创建扩展文件:
echo "subjectAltName = DNS:video.local,IP:192.168.2.2" > server.ext
  • 签署证书:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -extfile server.ext
  • 生成证书链:
cat server.crt ca.crt > chain.crt
  • 验证:
openssl x509 -in server.crt -text -noout

确认 Subject: CN=video.local, X509v3 Subject Alternative Name: DNS:video.local, IP Address:192.168.2.2.

cat chain.crt

确认包含两段 -----BEGIN CERTIFICATE-----
配置了自签名证书后更新nginx设置:

server {
        listen       443 ssl;
	listen	     443 quic reuseport;
    	listen  [::]:443  ssl;
    	listen  [::]:443 quic reuseport;
	http2 on;
	http3 on;
	
        server_name  video.local;
    	add_header Alt-Svc 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000';
        error_log /var/log/nginx/video.local.error.log debug; # 指定一个文件并设置级别为 info

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
            add_header Alt-Svc 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000';

 	    add_header Access-Control-Allow-Methods "GET,OPTIONS,POST,HEAD,PUT,DELETE";
	    add_header Accept-Ranges "bytes";
	    add_header Access-Control-Allow-Origin "*";
	    add_header Access-Control-Expose-Headers "Content-Lengrh,Content-Range,Date,Server,Transfer-Encoding,origin,range,x-goog-meta-foo1";
        }
	ssl_certificate     path/key/chain.crt;
	ssl_certificate_key path/key/server.key;
        #error_page  404              /404.html;
        ssl_protocols       TLSv1.3;
        ssl_prefer_server_ciphers off;

	    # 添加QUIC特定配置
    	ssl_early_data on;
    	quic_retry on;
    	quic_gso on;

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

重载 nginx:

sudo /usr/local/nginx/sbin/nginx -s stop
sudo /usr/local/nginx/sbin/nginx

复制证书到客户端(macos):

scp -P 22 cc@<ip addr>:path/ca.crt /Users/desktop

复制了后将ca.crt导入钥匙链中。
在配置好这些后,nginx-quic的基本配置就结束了,但是启动chrome或者firefox访问网页发现仍然是http2连接,下面是发现错误并步步排查错误并解决的过程:

启用http3连接

  • 使用wireshark抓包:
    查找条件:udp.port == 443
    可以看到有quic尝试握手的报文
CONNECTION_CLOSE (Transport) Error code: CRYPTO_ERROR (Certificate Unknown)

主要到这提到了Certificate Unknown

  • 使用 curl访问
#在docker中验证
cris@Cris % docker exec -u root -it <镜像id> sh -c 'echo "192.168.2.2 video.local" >> /etc/hosts'

curl -v --http3 https://video.local

可以看到:

SSL certificate problem: self signed certificate in certificate chain

* connect to 192.168.2.2 port 443 failed: SSL peer certificate or SSH remote key was not OK
  curl: (60) SSL certificate problem: self signed certificate in certificate chain

This indicates that the certificate is either self-signed or signed by an untrusted Certificate Authority (CA), in this case, CN=My CA. The -k flag allows curl to ignore this issue, but other clients (like browsers) typically enforce stricter validation, leading to a CERTIFICATE_VERIFY_FAILED error during the QUIC handshake.也就是说证书是自签名证书,浏览器可能执行更严格的验证导致无法握手。

  • 查看nginx错误日志
[info] 32575#0: *47 SSL_do_handshake() failed (SSL: error:10000418:SSL routines:OPENSSL_internal:TLSV1_ALERT_UNKNOWN_CA:SSL alert number 48) while SSL handshaking, client: 192.168.2.1, server: 0.0.0.0:443`

通过上述三点可以确问题:SSL/TLS 证书验证问题

解决问题方法

在寻找多种解决问题方法后,找到了最简单的解决方法:
google文档中说明了(Playing with QUIC):
Note that the server’s certificate must be trusted by a default CA for Chrome/Chromium to accept it for QUIC. If you are using a self-signed certificate or a certificate that is signed by a custom CA, you need to use the --ignore-certificate-errors-spki-list command line flag to trust an individual certificate based on its SPKI. It is not possible to trust a custom CA using this flag. If you wish to deploy a MITM proxy that intercepts traffic, you need to block QUIC entirely and intercept TLS instead.
最后使用这行命令打开chrome成功完成了http3连接:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \ --user-data-dir=/tmp/chrome-profile \ --no-proxy-server \ --enable-quic \ --origin-to-force-quic-on=video.local:443 \ --ignore-certificate-errors-spki-list=<指纹id> \ <要打开的网页链接>

其中这个指纹id的获取方式是:

`openssl x509 -in /path/to/server.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值