CentOS7 启用 Nginx HTTP3.0/QUIC、TLS1.3、Brotli 支持

HTTP 3.0,也称作 HTTP over QUIC。核心是 QUIC (读音quick)协议,由 Google 在 2015 年提出的 SPDY v3 演化而来的新协议,传统的 HTTP 协议是基于传输层 TCP 的协议,而 QUIC 是基于传输层 UDP 上的协议,可以定义成:HTTP3.0 基于 UDP 的安全可靠的 HTTP2.0 协议,提供比 TCP 和 TLS 更高的加密和性能,主要有以下特性:

  • 基于 UDP 减少了 TCP 三次握手及 TLS 握手时间
  • 解决多路复用丢包时的线头阻塞问题
  • 优化重传策略
  • 流量控制
  • 连接迁移

Nginx-Quic 官方自述:https://quic.nginx.org/readme.html

安装依赖

yum install -y git openssl-devel libunwind-devel libxslt-devel gd-devel

安装GCC 10

# 安装 Software Collections 软件源
yum install -y centos-release-scl-rh centos-release-scl

# 安装 GCC 10
yum install -y devtoolset-10-gcc devtoolset-10-gcc-c++ devtoolset-10-make

# 生效临时变量
source /opt/rh/devtoolset-10/enable

安装 cmake3

# 安装 epel 源
yum install -y epel-release

# 安装cmake3
yum install -y cmake3

源码准备

nginx-quic 源码可通过 https://hg.nginx.org/nginx-quic/shortlog/quic 站点下载

创建源码目录

mkdir -p ~/src/ext && cd ~/src

下载 nginx-quic 源码

wget https://hg.nginx.org/nginx-quic/archive/quic.tar.gz
tar xf quic.tar.gz

下载 ngx_brotli 源码

cd ~/src/ext
git clone https://github.com/google/ngx_brotli --depth=1 && cd ngx_brotli
git submodule update --init

下载 pcre-8.44.tar.gz 源码

cd ~/src/ext
wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
tar xf pcre-8.44.tar.gz

下载 zlib-1.2.11 源码

wget https://zlib.net/zlib-1.2.11.tar.gz
tar xf zlib-1.2.11.tar.gz

下载 go (编译 boringssl 需要)

wget https://golang.org/dl/go1.16.5.linux-amd64.tar.gz
tar xf go1.16.5.linux-amd64.tar.gz

# 设置临时变量
export PATH="~/src/ext/go/bin:$PATH"

下载 boringssl 源码 & 编译

# 下载源码
cd ~/src/ext
git clone https://github.com/google/boringssl --depth=1
mkdir -p boringssl/out && cd boringssl/out

# 编译
cmake3 ..
make -j$(nproc --all)

编译 Nginx

# 进入nginx 源码目录
cd ~/src/nginx-quic-quic

# 编译参数(根据自己需求修改)
./auto/configure \
  --prefix=/opt/nginx \
  --user=nginx \
  --group=nginx \
  --with-file-aio \
  --with-threads \
  --with-http_addition_module \
  --with-http_auth_request_module \
  --with-http_dav_module \
  --with-http_degradation_module \
  --with-http_flv_module \
  --with-http_gunzip_module \
  --with-http_gzip_static_module \
  --with-http_image_filter_module \
  --with-http_mp4_module \
  --with-http_random_index_module \
  --with-http_realip_module \
  --with-http_secure_link_module \
  --with-http_slice_module \
  --with-http_ssl_module \
  --with-http_stub_status_module \
  --with-http_sub_module \
  --with-http_xslt_module \
  --with-http_v2_module \
  --with-http_v3_module \
  --with-http_quic_module \
  --with-mail \
  --with-mail_ssl_module \
  --with-stream  \
  --with-stream_realip_module  \
  --with-stream_ssl_module  \
  --with-stream_ssl_preread_module \
  --with-openssl-opt='enable-tls1_3' \
  --with-zlib=../ext/zlib-1.2.11 \
  --with-pcre=../ext/pcre-8.44 \
  --add-module=../ext/ngx_brotli \
  --with-cc-opt="-I../ext/boringssl/include" \
  --with-ld-opt="-L../ext/boringssl/out/ssl \
                 -L../ext/boringssl/out/crypto"

# 编译安装
make -j$(nproc --all)
make install

添加 systemd 脚本

cat > /lib/systemd/system/nginx.service <<"EOF"
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/opt/nginx/logs/nginx.pid
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStart=/opt/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

Nginx QUIC 完整配置举例

主配置:/opt/nginx/conf/nginx.conf

user  root;
worker_processes  auto;
error_log         logs/error.log;

events {
    worker_connections  4096;
}

http {
    include                        mime.types;
    default_type                   application/octet-stream;
    sendfile                       on;
    keepalive_timeout              65s;

    # quic 日志格式
    log_format quic '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" "$quic" "$http3"';

    # 启用 gzip 压缩
    gzip                           on;
    gzip_comp_level                6;
    gzip_min_length                1k;
    gzip_disable                   msie6;
    gzip_buffers                   4 16k;
    gzip_http_version              1.1;
    gzip_proxied                   any;
    gzip_vary                      on;
    gzip_types                     text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;

    # 启用 brotli 压缩
    brotli                         on;
    brotli_types                   text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;
    brotli_static                  on;
    brotli_comp_level              6;
    brotli_buffers                 16 10k;
    brotli_window                  512k;
    brotli_min_length              20;

    client_max_body_size           2048m;
    fastcgi_intercept_errors       on;
    fastcgi_cache_key              $scheme$request_method$host$request_uri;
    fastcgi_cache_use_stale        error timeout invalid_header http_500;
    fastcgi_ignore_headers         Cache-Control Expires Set-Cookie;

    include                        conf.d/*.conf;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504 /50x.html;

        location = /50x.html {
            root  html;
        }
    }

    server_names_hash_max_size     512;
    server_names_hash_bucket_size  128;
    client_header_buffer_size      32k;
    large_client_header_buffers    4 32k;
    fastcgi_buffer_size            64k;
    fastcgi_buffers                4 64k;
    fastcgi_busy_buffers_size      128k;
    fastcgi_temp_file_write_size   256k;
    server_tokens                  on;
    access_log                     off;
}

主机配置(举例):/opt/nginx/conf/conf.d/example.conf

更多quic相关配置可参考Nginx官方文档:https://quic.nginx.org/readme.html

server {
    listen                     80;
    listen                     443 ssl http2;
    listen                     443 http3 quic reuseport; # 注意:reuseport 参数只需(能)在任意主机中配置一次
    server_name                example.com www.example.com; # 域名绑定
    root                       www/example; # 站点目录

    # SSL
    ssl_certificate            ssl/example.crt; # 证书路径
    ssl_certificate_key        ssl/example.key; # 私钥路径
    ssl_session_timeout        1d;
    ssl_session_tickets        on; # TLS会话恢复(Ticket),0-RTT 支持需要
    ssl_protocols              TLSv1.2 TLSv1.3; # 启用 tls1.2 & 1.3
    ssl_prefer_server_ciphers  on;
    ssl_ciphers                ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE:!DES-CBC3-SHA:!AES128-SHA:!AES256-SHA:!AES128-GCM-SHA256:!AES256-GCM-SHA384; # 禁用弱密码套件

    # quic
    add_header                 Alt-Svc 'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"';  # 兼容不支持QUIC的浏览器
    add_header                 QUIC-Status $quic; # QUIC 握手成功状态显示
    quic_retry                 on;
    ssl_early_data             on; # 启用 0-RTT

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header                 Strict-Transport-Security "max-age=63072000" always;

    # 自动跳转 https
    if ($scheme = http) {
        return  301 https://$host$request_uri;
    }
}

检查 HTTP/3 QUIC 是否配置成功

可以通过 HTTP/3 Check 网站检查

最后修改:2021 年 09 月 23 日 04 : 21 AM
如果觉得我的文章对你有用,请随意赞赏