[HTTP3/QUIC] Debian 编译 NGINX_QUIC ,支持 HTTP3 QUIC
[HTTP3/QUIC] Debian 编译 NGINX_QUIC ,支持 HTTP3 QUIC
1. 准备 golang 环境(编译 BoringSSL 需要)
卸载旧环境 golang
apt-get remove golang
apt-get autoremove
环境准备 golang
cd /usr/local/src/
wget https://golang.google.cn/dl/go1.19.1.linux-amd64.tar.gz
tar -zxvf go1.19.1.linux-amd64.tar.gz
mv go /usr/local/
ln -s /usr/local/go/bin/go /usr/bin/go
2. 编译 BoringSSL (NGINX-QUIC/HTTP3 需要)
BoringSSL
Centos 编译不过,编译完从 Debian 复制过去也能用
cd /usr/local/src/
apt install git cmake gcc g++
git clone https://github.com/google/boringssl.git
mkdir /usr/local/src/boringssl/build
cd /usr/local/src/boringssl/build
cmake ..
gmake
gmake install
3. 编译 NGINX
准备编译环境
cd /usr/local/src/
wget https://zlib.net/zlib-1.2.13.tar.gz
tar -zxvf zlib-1.2.13.tar.gz
apt install libpcre3 libpcre3-dev mercurial
hg clone -b quic https://hg.nginx.org/nginx-quic
cd /usr/local/src/nginx-quic
编译 HTTP3
./auto/configure \
--with-debug \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-stream_quic_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_addition_module \
--with-http_sub_module \
--with-threads \
--with-openssl-opt='enable-tls1_3' \
--prefix=/usr/local/nginx \
--with-zlib=../zlib-1.2.13 \
--with-cc-opt="-I../boringssl/include" \
--with-ld-opt="-L../boringssl/build/ssl -L../boringssl/build/crypto"
make
make install HTTP2 (已经不使用)
./configure \
--with-pcre \
--with-stream \
--with-stream_ssl_module \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_addition_module \
--with-http_sub_module \
--with-threads \
--with-openssl-opt='enable-tls1_3' \
--prefix=/usr/local/nginx \
--with-openssl=../openssl-1.1.1q \
--with-zlib=../zlib-1.2.13
make
make install
4. 配置使用 systemctl
vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
5. 提供一个简化的NGINX 配置
# 缺少某些目录或者文件导致无法写入,导致启动报错的
mkdir -p /etc/nginx/conf/logs/
# 自行解决: dhparam.pem ssl_certificate、ssl_certificate_key 等文件
# 这个文件主要是写一些通用的配置,通过 include 来统一引入。看起来简洁一些
vim /etc/nginx/public.conf
# 重要: 必须要在 include vim /usr/local/nginx/conf/nginx.conf 才能生效
include /etc/nginx/*.conf;
vim /etc/nginx/zhuihoude.cn.conf
server { #if ($host !~* "(zhuihoude)") { return 444;}
listen 80;
return 302 https://$host$request_uri?http;
}
################ zhiuhoude.cn ################
server {
include /etc/nginx/conf/public.conf;
ssl_trusted_certificate /etc/nginx/conf/certificate/cn.crt;
ssl_certificate /etc/nginx/conf/certificate/cn.crt;
ssl_certificate_key /etc/nginx/conf/certificate/cn.key;
server_name zhuihoude.cn;
listen 443 http2 reuseport fastopen=3 ssl;
listen 443 http3 reuseport;
location / {
if (
$host !~* "(zhuihoude)") { return 302 http://zhuihoude.cn; }
proxy_pass https://127.0.0.1:8080/;
proxy_redirect default;
# proxy_set_header 写在 server 下似乎会失效
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
access_log /etc/nginx/conf/logs/today_zhdcn.json log_json;
}
vim /etc/nginx/public.conf
## SSL Config
ssl_dhparam /etc/nginx/conf/certificate/dhparam.pem;
ssl_protocols TLSv1.2 TLSv1.3; # SSLv2 SSLv3 TLSv1 TLSv1.1
ssl_session_cache shared:SSL:10m; #缓存大小
ssl_session_tickets on; #浏览器缓存
ssl_session_timeout 10m; #缓存超时
ssl_prefer_server_ciphers on; #使用服务器密码
ssl_ciphers ECDHE:!CBC:!NULL:!aNULL:!eNULL:!MD5:!ADH:!RC4:!DH:!DHE;
ssl_early_data on; #开启 1.3 o-RTT
keepalive_timeout 120s; #TCP 保持
keepalive_requests 1000;
#ssl_stapling on; ## OCSP Stapling 用于在线查询证书吊销情况 BoringSLL 暂不支持
ssl_stapling_verify on;
# ssl_stapling_file /etc/nginx/conf/certificate/stapling_file.ocsp;
resolver 114.114.114.114 8.8.8.8 valid=240s;
resolver_timeout 5s;
## HTTP3
quic_retry on;
quic_gso on;
quic_mtu 1350;
## 升级站内 HTTP 为 HTTPS 连接
proxy_hide_header Content-Security-Policy;
add_header Content-Security-Policy upgrade-insecure-requests;
## HTTP3 开启常用端口
proxy_hide_header Alt-Svc;
add_header Alt-Svc 'h3=":443"; ma=86400';
add_header Alt-Svc 'h3=":1443"; ma=86400';
## Hsts
proxy_hide_header Strict-Transport-Security;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
## DENY:不能iframe;SAMEORIGIN:本站iframe;ALLOW-FROM:允许frame
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options SAMEORIGIN;
## 防止 MIME 类型混淆攻击
proxy_hide_header X-Content-Type-Options;
add_header X-Content-Type-Options nosniff;
## 跨域
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin *;
proxy_hide_header Access-Control-Allow-Credentials;
add_header Access-Control-Allow-Credentials true;
proxy_hide_header Access-Control-Allow-Methods;
add_header Access-Control-Allow-Methods *; #'GET, POST, OPTIONS';
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers *; #'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
## Error Page
error_page 400 /page/400.html;
error_page 401 /page/401.html;
error_page 403 /page/403.html;
error_page 404 /page/404.html;
error_page 502 /page/502.html;
error_page 504 /page/504.html;
error_page 506 /page/506.html;
error_page 497 https://$host:$Server_port$request_uri?error=$host:$Server_port;
vim /usr/local/nginx/conf/nginx.conf
worker_processes 2;
worker_cpu_affinity 01 10;
worker_rlimit_nofile 65535;
events{
use epoll;
multi_accept on;
accept_mutex on;
worker_connections 512;
}
http{
include /etc/nginx/conf/page/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 50m;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
index index.html;
charset utf-8;
proxy_connect_timeout 3s;
proxy_read_timeout 10s;
proxy_send_timeout 30s;
keepalive_timeout 60;
keepalive_requests 1000;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 64 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
gzip on;
gzip_comp_level 6;
gzip_min_length 1k;
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;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;
gzip_proxied any;
log_format log_json
'{"timestamp":"$time_iso8601",\n'
'"response_time": "$upstream_response_time",\n'
'"remote_addr":"$remote_addr",\n'
'"http_x_forwarded_for":"$http_x_forwarded_for",\n'
'"request_status":"$request_method-$status-$http3",\n'
'"request_url":"$scheme://$host:$Server_port$request_uri",\n'
'"referer":"$http_referer",\n'
'"user_agent":"$http_user_agent",\n'
'"request_body":"$request_body"\n'
'},';
# log_format log_quic '$remote_addr - $remote_user [$time_local] '
# '"$request" $status $body_bytes_sent '
# '"$http_referer" "$http_user_agent" "$http3"';
access_log /etc/nginx/conf/logs/today_nginx.json log_json;
include /etc/nginx/*.conf;
}
其他: 在编译之前可以修改自定义服务器名称
修改Nginx 内部名称
vim src/core/nginx.h
修改 HTTP Response Header
vim src/http/ngx_http_header_filter_module.c
static u_char ngx_http_server_string[] = "Server: iOS" CRLF;
修改错误页的底部 Footer
vim src/http/ngx_http_special_response.c
static u_char ngx_http_error_tail[] =
"<hr><center>iOS 16.3 (20D47)</center>" CRLF
"</body>" CRLF
"</html>" CRLF
;
其他: 每日自动日志分割
vim /etc/nginx/conf/shell/cutlog.sh
# 使用 /etc/crontab 每天零点切割日志并重启
# 0 0 * * * root /etc/nginx/conf/shell/cutlog.sh
systemctl stop nginx
touch "/usr/local/nginx/logs/error.log"
touch "/etc/nginx/conf/logs/today_nginx.json"
touch "/etc/nginx/conf/logs/today_zhuihoude.json"
mv "/usr/local/nginx/logs/error.log" "/etc/nginx/conf/logs/$(date -d "yesterday" +%G.%m.%d)_error.log"
mv "/etc/nginx/conf/logs/today_nginx.json" "/etc/nginx/conf/logs/$(date -d "yesterday" +%G.%m.%d)_nginx.json"
mv "/etc/nginx/conf/logs/today_zhuihoude.json" "/etc/nginx/conf/logs/$(date -d "yesterday" +%G.%m.%d)_zhuihoude.json"
systemctl start nginx
其他: acme.sh 申请证书 (腾讯云 DNSPOD)
Git安装 #其他方法参阅 https://github.com/acmesh-official/acme.sh
git clone https://github.com/acmesh-official/acme.sh.git
cd ~/.acme.sh/
./acme.sh --install -m justroylau@gmail.com
# #DNSPOD 颁发证书
# 设定密钥 获取方法(头像 - 我的账号 - 账号中心 - API密钥 - DNSPod Token - 创建密钥)
export DP_Id="123456"
export DP_Key="自己去查看吧"
# 其他 DNS 供应商查询 https://github.com/acmesh-official/acme.sh/wiki/dnsapi
# 可以申请泛域名(*)证书哦
./acme.sh --issue --dns dns_dp -d zhuihoude.cn -d zhuihoude.com -d *.zhuihoude.cn -d *.zhuihoude.com
# 等待大约两分钟后…
cd ~/.acme.sh/zhuihoude.cn/
# 两个文件就到手啦~ 建议直接使用 fullchain.cer 包含了完整的证书链
~/.acme.sh/zhuihoude.cn/fullchain.cer
~/.acme.sh/zhuihoude.cn/zhuihoude.cn.key
其他: 群晖动态 DDNS
群晖自带 DDNS 支持泛域名
但是前端限制了 * 符号的无法提交,可以直接 POST 到后台 (GET好像也行)。
Post 接口 https://zhuihoude.synology.me:5001/webapi/entry.cgi
## 首先获取浏览器 F12 的 Request Headers 三个就够
x-requested-with:XMLHttpRequest
x-syno-hash:GrkQhxoP31TF4g-1ii_6Qzz-oYc2_g.MTY0
x-syno-token:xYlNn9NhDQgtA
#### Post 的 Form Data,(具体参数可以直接浏览器 F12 去复制 只需要改域名就行)
#### 可以用 Chrome 插件 Postwoman 来发送请求
stop_when_error:true
mode:"sequential"
compound:[{"api":"SYNO.Core.DDNS.Record","method":"set","version":1,"id":"DNSPod.cn","enable":true,"provider":"DNSPod.cn","hostname":"这个是域名*.zhuihoude.com","username":"这个也是 腾讯云 DNS POD的","net":"DEFAULT","ip":"124.227.92.77","ipv6":"0:0:0:0:0:0:0:0","heartbeat":false,"passwd":"这个是腾讯云DNS POD 的"},{"api":"SYNO.Core.DDNS.Record","method":"update_ip_address","version":1,"id":"DNSPod.cn"}]
api:SYNO.Entry.Request
method:request
version:1