本文使用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 www 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