本文使用nginx和QuicTLS建立支持HTTP/3的web服务器,nginx 1.27.2 可以通过stream模块支持oscp stapling。
安装依赖
apt update apt install build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config libjemalloc-dev
编译 QuicTLS
选择一个你喜欢的位置存放源代码,如 /usr/local/src/等
cd /usr/local/src/ wget https://github.com/quictls/openssl/archive/refs/tags/openssl-3.3.0-quic1.zip unzip -q openssl-3.3.0-quic1.zip cd openssl-openssl-3.3.0-quic1 ./config --prefix=$(pwd)/build no-shared make make install_sw cd ../
编译brotli 压缩
brotli 由Google的工程师Jyrki Alakuijala和Zoltán Szabadka开发
可以帮我们更高效的压缩网页中的各类文件大小及脚本,从而提高加载速度
不需要请跳过,并在编译nginx时,删除./auto/configure
中的--add-module=../ngx_brotli
参数。
cd /usr/local/src/ git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli cd ngx_brotli/deps/brotli mkdir out && cd out cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. cmake --build . --config Release --target brotlienc cd ../../../..
编译 Nginx
–user=www –group=www #程序运行的用户,默认为www-data,按需修改
–prefix= #程序和配置文件安装的位置,如/usr/local/share,/usr/sbin,本文安装在/www/nginx下
–with #需要的各种模块,包含在nginx源代码中,按需选择
–pid-path= #pid文件位置,默认为<prefix>/logs/nginx.pid
cd /usr/local/src/ hg clone https://hg.nginx.org/nginx cd nginx ./auto/configure --user=www --group=www --prefix=/www/nginx --pid-path=/run/nginx.pid --with-pcre-jit --add-module=/root/ngx_brotli --with-http_v2_module --with-stream --with-stream_ssl_module --with-http_ssl_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-http_v3_module --with-cc-opt="-I../openssl-openssl-3.3.0-quic1/build/include" --with-ld-opt="-L../openssl-openssl-3.3.0-quic1/build/lib64" make make install ln -s /www/nginx/sbin/nginx /usr/sbin/nginx
–with-cc-opt 这个选项用于指定传递给 C 编译器(通常是 gcc 或 clang)的额外参数,如需要的头文件。你可以通过这个选项添加优化标志、指定特定的包含路径或定义宏等。这些参数会直接影响编译过程中的代码编译阶段。
–with-ld-opt 与 --with-cc-opt
类似,--with-ld-opt
用于指定在链接阶段传递给链接器的额外参数,如库文件。这包括指定库的链接路径或添加特定的链接选项,这些都是在将编译好的对象文件组合成最终可执行文件或库时使用。
你还可以自定义这些配置
- –prefix=/usr/local/share/nginx
- –sbin-path=/usr/sbin/nginx ,你可以通过设置这个路径将可执行文件安装到/usr/sbin,否则你需要软连接到/usr/sbin,如:ln -s /usr/local/share/nginx /usr/sbin/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
添加程序使用的用户
通过源安装的nginx和php默认使用的用户可能是www-data
,如果你需要自定义它们使用的用户,需要 注意 文件的权限。
groupadd useradd -g www -s /sbin/nologin www
使用 systemd守护进程
创建nginx服务
nano /usr/lib/systemd/system/nginx.service
输入以下内容:
[Unit] Description=A high performance web server and a reverse proxy server After=network.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed [Install] WantedBy=multi-user.target
使用systemd启动程序
systemctl daemon-reload # 启动nginx systemctl start nginx # 开机自启 systemctl enable nginx
修改配置后重启nginx
systemctl reload nginx # 或者 service nginx reload
脚本:
#!/bin/bash # Exit on errors set -e # Update and install dependencies apt update apt install -y build-essential ca-certificates zlib1g-dev libpcre3 libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial libunwind-dev pkg-config libjemalloc-dev # Remove existing ngx_brotli if present if [ -d "/usr/local/src/openssl-openssl-3.3.0-quic1" ]; then echo "Removing existing openssl-openssl-3.3.0-quic1 installation..." rm -rf /usr/local/src/openssl-openssl-3.3.0-quic1 fi # Compile QuicTLS cd /usr/local/src wget https://github.com/quictls/openssl/archive/refs/tags/openssl-3.3.0-quic1.zip tar -xzf openssl-3.3.0-quic1.tar.gz cd openssl-openssl-3.3.0-quic1 ./config --prefix=$(pwd)/build no-shared make make install_sw # Remove existing ngx_brotli if present if [ -d "/usr/local/src/ngx_brotli" ]; then echo "Removing existing ngx_brotli installation..." rm -rf /usr/local/src/ngx_brotli fi # Install Brotli compression cd /usr/local/src git clone --recurse-submodules -j8 https://github.com/google/ngx_brotli cd ngx_brotli/deps/brotli mkdir out && cd out cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -flto -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed .. cmake --build . --config Release --target brotlienc # Remove existing Nginx if present if [ -d "/usr/local/src/nginx" ]; then echo "Removing existing Nginx installation..." rm -rf /usr/local/src/nginx fi # Clone Nginx and configure with QuicTLS and Brotli cd /usr/local/src hg clone https://hg.nginx.org/nginx cd nginx ./auto/configure --user=www --group=www --prefix=/www/nginx --pid-path=/run/nginx.pid --with-pcre-jit --add-module=/root/ngx_brotli --with-http_v2_module --with-stream --with-stream_ssl_module --with-http_ssl_module --with-http_gzip_static_module --with-http_gunzip_module --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --with-http_v3_module --with-cc-opt="-I../openssl-openssl-3.3.0-quic1/build/include" --with-ld-opt="-L../openssl-openssl-3.3.0-quic1/build/lib64" make make install ln -s /www/nginx/sbin/nginx /usr/sbin/nginx # Create systemd service file for Nginx cat <<EOF > /usr/lib/systemd/system/nginx.service [Unit] Description=A high performance web server and a reverse proxy server After=network.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid TimeoutStopSec=5 KillMode=mixed [Install] WantedBy=multi-user.target EOF # Reload systemd daemon and enable Nginx service systemctl daemon-reload systemctl enable nginx.service echo "Nginx installed and service created. Use 'systemctl start nginx' to start Nginx."
从旧版本升级
在编译完成后,将原本的bin文件命名为nginx.old,将编译好的新bin文件复制到目录,如:
mv "/www/nginx/sbin/nginx" "/www/nginx/sbin/nginx.old-1.25.5" cp "/usr/local/src/nginx/objs/nginx" /www/nginx/sbin/nginx
在nginx源代码目录下执行 make upgrade
nginx.conf示例
如果你需要反向代理一些其它东西,可以参考chika
listen 443 quic reuseport; #目前只能有一个虚拟server开启quic reuseport
#user www-data; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #brotli on; #启用brotli #brotli_comp_level 6; #压缩等级,默认6,最高11,太高的压缩水平可能需要更多的CPU #brotli_buffers 16 8k; #请求缓冲区的数量和大小 #brotli_min_length 20; #指定压缩数据的最小长度,只有大于或等于最小长度才会对其压缩。这里指定20字节 #brotli_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml text/html application/json image/svg application/font-woff application/vnd.ms-fontobject application/vnd.apple.mpegurl image/x-icon image/jpeg image/gif image/png image/bmp; #指定允许进行压缩类型 #brotli_static on; #是否允许查找预处理好的、以.br结尾的压缩文件,可选值为on、off、always #brotli_window 512k; #窗口值,默认值为512k #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 logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { # Listen on ipv4 listen 80 default; listen [::]:80; # Redirect all insecure http:// requests to https:// # 重定向 return 301 https://$host$request_uri; # root /www/nginx/html/; #return 403; } # HTTPS server # REJECT HANDSHAKE 拒绝没有host名的握手请求 server { listen 443 ssl default_server; http2 on; listen [::]:443 ssl default_server; listen 443 quic reuseport; ssl_reject_handshake on; ssl_protocols TLSv1.2 TLSv1.3; ssl_session_timeout 10m; ssl_session_cache shared:SSL_cache:10m; } # YOUR server START HERE server { listen 443 ssl; # listen [::]:443 ssl; #可选ipv6 # listen 443 quic reuseport; # listen [::]:443 quic reuseport; http2 on; server_name your_domain.tld; #你的域名 # add_header Alt-Svc 'h3=":443"; ma=86400'; #可选倾向的cipher #ssl_prefer_server_ciphers on; #ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; # QUIC-specific settings 开启QUIC #ssl_early_data on; #ssl_session_tickets on; #quic_retry on; #证书位置 ssl_certificate /path/to/your_domain.tld.cer; ssl_certificate_key /path/to/your_domain.tld.key; ssl_session_timeout 5m; ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; # HSTS (ngx_http_headers_module is required) (63072000 seconds) # 强制https:浏览器收到之后,设定时间内不会尝试使用http连接 # add_header Strict-Transport-Security max-age=63072000; #或者包含子域名 add_header Strict-Transport-Security "max-age=63072000;includeSubDomains" always; # OCSP Stapling # ssl_stapling on; # ssl_stapling_verify on; # ssl_trusted_certificate /path/to/origin_ca_ecc_root.cer; # resolver 8.8.8.8 8.8.4.4 valid=300s; # resolver_timeout 5s; # 如果你使用cloudflare的CDN,可以添加这段,只允许CF访问,否则删除 allow 127.0.0.1; allow 10.0.0.0/20; allow 173.245.48.0/20; allow 103.21.244.0/22; allow 103.22.200.0/22; allow 103.31.4.0/22; allow 141.101.64.0/18; allow 108.162.192.0/18; allow 190.93.240.0/20; allow 188.114.96.0/20; allow 197.234.240.0/22; allow 198.41.128.0/17; allow 162.158.0.0/15; allow 104.16.0.0/13; allow 104.24.0.0/14; allow 172.64.0.0/13; allow 131.0.72.0/22; deny all; index index.html; location / { index index.html; } } ########### HTTP END HERE ################# }
Reference:
- 使用 QuicTLS 编译 Nginx 并开启 Quic 或 HTTP/3 归去如风-小泽
- 使用 BoringSSL 编译 Nginx 并开启 Quic 或 HTTP/3 归去如风-小泽
- Nginx 开启Brotli压缩 infvie envoy
- chika