从官方源安装 nginx 最新版本
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/debian $(cat /etc/os-release | grep VERSION_CODENAME | cut -d'=' -f2) nginx" | tee /etc/apt/sources.list.d/nginx.list
apt update
apt install nginx -y
默认 Stream 模块只能根据 SNI 分流,如果要通过 HTTP Header 中的 Host 分流需要自定义脚本才能实现
安装 nginx-module-njs 模块,以运行自定义脚本
apt install nginx-module-njs -y
保存以下内容到 /etc/nginx/http_server_name.js
var server_name = '-';
function read_server_name(s) {
s.on('upload', function (data, flags) {
if (data.length || flags.last) {
s.done();
}
var n = data.indexOf('\r\nHost: ');
if (n != -1) {
var start_host = n + 8;
var next_header = data.indexOf('\r\n', start_host);
server_name = data.substr(start_host, next_header - start_host);
var port_start = server_name.indexOf(':');
if (port_start != -1) {
server_name = server_name.substr(0, port_start);
}
}
});
}
function get_server_name(s) {
return server_name;
}
export default {read_server_name, get_server_name}
修改 /etc/nginx/nginx.conf 配置文件
示例
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
# 加载 nginx-module-njs 模块
load_module modules/ngx_stream_js_module.so;
events {
worker_connections 1024;
}
stream {
# 加载自定义脚本
js_import main from http_server_name.js;
js_set $preread_server_name main.get_server_name;
# 根据 TLS SNI 分流
map $ssl_preread_server_name $upstream_443 {
example1.com 127.0.0.1:12345;
example2.com 127.0.0.1:23456;
default 127.0.0.1:8443;
}
# 根据 HTTP Host 分流
map $preread_server_name $upstream_80 {
example1.com 127.0.0.1:34567;
example2.com 127.0.0.1:45678;
default 127.0.0.1:8080;
}
# 需要复用的 HTTPS 端口
server {
listen [::]:443 ipv6only=off;
ssl_preread on;
proxy_pass $upstream_443;
}
# 需要复用的 HTTP 端口
server {
listen [::]:80 ipv6only=off;
js_preread main.read_server_name;
proxy_pass $upstream_80;
}
}
# 正常建站配置文件在 /etc/nginx/conf.d 目录下
# HTTP 模块监听端口不能与 Stream 模块重复
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
}
重启 nginx
systemctl restart nginx.service
如遇启动失败可使用 nginx -t 命令检查配置 排查错误