网络上的教程众说纷纭,大部分都是使用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; #} }