网络上的教程众说纷纭,大部分都是使用quiche补丁的方式,这里给出一份使用nginx官方quic版本的方式,nginx 1.25版本后,quic分支已经合并进入主线,编译过程简单很多
安装编译工具
dnf install gcc gcc-c++ perl-IPC-Cmd git wget make tar autoconf #如果是AlmaLinux9需安装FindBin dnf install perl-FindBin
下载编译程序
wget https://nginx.org/download/nginx-1.25.0.tar.gz wget https://github.com/jemalloc/jemalloc/archive/refs/tags/5.3.0.tar.gz -O jemalloc-5.3.0.tar.gz wget https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz wget https://github.com/quictls/openssl/archive/refs/tags/openssl-3.0.12-quic1.tar.gz git clone https://github.com/google/ngx_brotli.git && cd ngx_brotli && git submodule update --init && cd ../ git clone https://github.com/cloudflare/zlib && cd zlib && make -f Makefile.in distclean && cd ../
安装jemalloc
jemalloc是比glibc中的malloc高效很多的内存管理方案,这里使用jemalloc对nginx进行优化
tar zxvf jemalloc-5.3.0.tar.gz cd jemalloc-5.3.0 ./autogen.sh make make install ln -s /usr/local/lib/libjemalloc.so.2 /usr/lib64/libjemalloc.so.2 cd ../ rm -rf jemalloc-5.3.0
注:部分系统还需在/usr/lib目录下增加一条软链接,否则编译nginx时会报错
ln -s /usr/local/lib/libjemalloc.so.2 /usr/lib/libjemalloc.so.2
安装nginx
开始编译nginx
/usr/sbin/groupadd www && /usr/sbin/useradd -g www www tar zxvf openssl-3.0.12-quic1.tar.gz tar zxvf pcre-8.45.tar.gz tar zxvf nginx-1.25.0.tar.gz cd nginx-1.25.0 ./configure --prefix=/usr/local/nginx \ --user=www --group=www \ --with-http_stub_status_module \ --with-http_sub_module \ --with-http_v2_module \ --with-http_v3_module \ --with-http_ssl_module \ --with-stream \ --with-stream_ssl_preread_module \ --with-stream_ssl_module \ --with-http_realip_module \ --with-zlib=../zlib \ --with-http_gzip_static_module \ --with-pcre=../pcre-8.45 \ --with-pcre-jit \ --with-openssl=../openssl-openssl-3.0.12-quic1 \ --with-ld-opt=-ljemalloc \ --add-module=../ngx_brotli make make install make clean cd ../
如果系统内核支持KTLS可使用如下编译参数
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-http_ssl_module --with-stream --with-stream_ssl_preread_module --with-stream_ssl_module --with-stream_realip_module --with-http_realip_module --with-http_gzip_static_module --with-zlib=../zlib --with-pcre=../pcre-8.45 --with-pcre-jit --with-openssl=../openssl-openssl-3.0.12-quic1 --with-openssl-opt=enable-ktls --with-ld-opt=-ljemalloc --add-module=../ngx_brotli
编译完成后创建站点与日志目录
mkdir -p /data/htdocs/conf/ mkdir -p /data/htdocs/ssl/ mkdir -p /data/htdocs/wwwroot/ chmod +w /data/htdocs/ chown -R www:www /data/htdocs/ mkdir -p /data/wwwlogs/ chmod +w /data/wwwlogs/ chown -R www:www /data/wwwlogs/
使系统自动切割日志
vi /etc/logrotate.d/nginx
#输入以下内容
/data/wwwlogs/*nginx.log {
daily
rotate 7
missingok
dateext
compress
notifempty
sharedscripts
postrotate
[ -e /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
配置nginx
创建默认证书
#使nginx.conf的default_server不报错 openssl genrsa -out /data/htdocs/ssl/default.key openssl req -new -x509 -key /data/htdocs/ssl/default.key -out /data/htdocs/ssl/default.pem -days 3650
生成 session_ticket.key
#安全考虑应不定期更换session_ticket.key秘钥 openssl rand 48 > /data0/htdocs/ssl/session_ticket.key
创建配置文件
mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.old vi /usr/local/nginx/conf/nginx.conf
输入以下内容后保存
user www www;
worker_processes auto;
error_log /data/wwwlogs/error_nginx.log crit;
pid /var/run/nginx.pid;
worker_rlimit_nofile 51200;
events {
use epoll;
worker_connections 51200;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 1024m;
client_body_buffer_size 10m;
server_tokens off;
tcp_nodelay on;
sendfile on;
tcp_nopush on;
keepalive_timeout 120;
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_min_length 1k;
brotli_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
log_format http '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
log_format https '$remote_addr - $remote_user [$time_local] '
'$ssl_protocol/$ssl_cipher $ssl_early_data '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
server {
listen 80 default_server reuseport;
listen 443 ssl http2 default_server reuseport;
listen 443 quic default_server reuseport;
server_name localhost;
access_log /data/wwwlogs/access_nginx.log combined;
ssl_certificate /data/htdocs/ssl/default.pem;
ssl_certificate_key /data/htdocs/ssl/default.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:secp384r1;
ssl_conf_command Options PrioritizeChaCha;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_early_data off;
#proxy_set_header Early-Data $ssl_early_data;
add_header Alt-Svc 'h3=":443"; ma=86400';
return 444;
}
include /data/htdocs/conf/*.conf;
}
创建用户和组
/usr/sbin/groupadd www /usr/sbin/useradd -g www www
创建系统服务
vi /usr/lib/systemd/system/nginx.service #输入以下内容后保存 [Unit] Description=nginx Documentation=http://nginx.org/en/docs/ After=network.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStartPost=/bin/sleep 0.1 ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID TimeoutStartSec=120 LimitNOFILE=65535 LimitNPROC=65535 LimitCORE=65535 [Install] WantedBy=multi-user.target
启动系统服务
systemctl start nginx systemctl enable nginx
添加web站点
在 /data/htdocs/conf 目录中添加站点配置文件
在 /data/htdocs/ssl 目录中添加站点绑定域名的证书
完成以上步骤后,执行
#检测配置文件正确性 /usr/local/nginx/sbin/nginx -t #重新加载配置 systemctl reload nginx
这里以wwwroot为站点目录示例,给出一个同时支持http3与http2的配置:
(如启用KTLS则去掉 ssl_conf_command Options KTLS 前的注释)
server {
listen 80;
listen 443 ssl http2;
listen 443 quic;
server_name sitename.com;
root /data/htdocs/wwwroot;
index index.html index.htm;
access_log /data/wwwlogs/sitename.com_nginx.log https;
resolver 223.5.5.5 8.8.8.8 valid=300s;
resolver_timeout 5s;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /data/htdocs/ssl/sitename.pem;
ssl_certificate /data/htdocs/ssl/sitename.pem;
ssl_certificate_key /data/htdocs/ssl/sitename.key;
ssl_session_tickets on;
ssl_session_ticket_key /data0/htdocs/ssl/session_ticket.key;
ssl_session_timeout 1440m;
ssl_session_cache shared:SSL:32m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:secp384r1;
#ssl_conf_command Options KTLS;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_early_data off;
#proxy_set_header Early-Data $ssl_early_data;
add_header Alt-Svc 'h3=":443"; ma=86400';
add_header Strict-Transport-Security "max-age=63072000; preload";
#add_header X-Content-Type-Options "nosniff";
#add_header X-Frame-Options "SAMEORIGIN";
#add_header X-XSS-Protection "1; mode=block";
client_max_body_size 0;
location ~* \.(jpg|jpeg|gif|png|bmp|swf|ico|rar|zip|7z|tgz|tar.gz|txt|flv|mid|doc|docx|pptx|ppt|xlsx|xls|pdf|mp3|wma)$ {
valid_referers none blocked sitename.com *.sitename.com *.baidu.com *.baiducontent.com;
if ($invalid_referer) {
return 412;
}
expires 30d;
access_log off;
break;
}
location ~* \.(js|css)?$ {
expires 7d;
access_log off;
}
location ~* \.(eot|ttf|woff|woff2|svg)$ {
expires max;
access_log off;
#add_header Access-Control-Allow-Origin *;
#add_header Access-Control-Allow-Headers X-Requested-With;
#add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}
location = /favicon.ico {
log_not_found off;
}
location = /robots.txt {
#deny all;
log_not_found off;
}
location ~ /\.(?!well-known).* {
deny all;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
}