解决Nginx443端口被占用问题

原理

  • 主要的工作就是在 dispatch 阶段的流量分发。因为都是 HTTPS 流量,所以在确定分发策略前得有一点相关知识。
    在虚拟主机流行前,一个服务 IP 只会有一个 TLS 服务站点,只会有一张 SSL 证书,所以请求来了就只有一张证书,没得选直接用就好了。
    后面虚拟主机流行起来,一个服务 IP 可以有多个 TLS 服务站点,那就有多个 SSL 证书,那怎么明确这次请求用哪张证书呢?
    于是就有了 SNI(TLS 服务器名称指示),它要求在一个 IP 有多个 TLS 服务站点的情况下,客户端在初始 TLS 握手期间指定要连接到哪个站点,数据上的实现就是在 Client Hello 阶段里面新增一个 server_name 字段。

  • http 模块的 proxy_pass 是在七层做的转发,但是七层做的转发,有些程序可能不支持,需要在第四层进行转发。

  • Nginx 支持基于 SNI 的 4 层转发。简单说就是:识别 SNI 信息,然后直接转发 TCP/UDP 数据流。这个可以比 7 层的虚拟主机转发厉害太多了,该功能由 ngx_stream_ssl_preread_module 模块提供,但是 Nginx 默认不启用该模块,配置起来也很简单,需要注意的是该模块属于 stream ,不是大家常用的 http。

解决

修改nginx主配置文件

  • 注意 nginx需要启动stream模块, 配置如下:
vim /etc/nginx/nginx.conf
load_module /usr/lib/nginx/modules/ngx_stream_module.so;
  
user  root;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
# 流量转发核心配置
stream {
    # 这里就是 SNI 识别,将域名映射成一个配置名
    map $ssl_preread_server_name $backend_name {
        www.wenknow.com web;
        nothing.wenknow.com yourProgram;
    # 域名都不匹配情况下的默认值
        default web;
    }

    # web,配置转发详情
    upstream web {
        server 127.0.0.1:10240;
    }

    # trojan,配置转发详情
    upstream yourProgram {
        server 127.0.0.1:10241;
    }

    # 监听 443 并开启 ssl_preread
    server {
        listen 443 reuseport;
        listen [::]:443 reuseport;
        proxy_pass  $backend_name;
        ssl_preread on;
    }
}

http {
  # 这块保持不变即可
}

修改之前占有端口的程序

  • 将之前占有端口的程序的监听端口 修改为 127.0.0.1:10241

修改Web的Nginx配置

  • 将Web监听的端口修改为上面配置的端口:
  • 注意,要加上最下面的配置,让都有请求都强制转到https,不然会监听不到。
server {
    listen 10240;
    server_name wenknow.com www.wenknow.com;

    index index.html index.htm;

    ssl on;
    ssl_certificate cert/www.wenknow.com.pem;
    ssl_certificate_key cert/www.wenknow.com.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    #表示使用的加密套件的类型。
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; #表示使用的TLS协议的类型,您需要自行评估是否配置TLSv1.1协议。
    ssl_prefer_server_ciphers on;

    location / {
                proxy_redirect off;
                proxy_set_header Host               $host;
                proxy_set_header X-Real-IP          $remote_addr;
                proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto  $scheme;
                proxy_read_timeout          1m;
                proxy_connect_timeout       1m;
                proxy_pass                          http://127.0.0.1:3000;
    }

    access_log /var/log/nginx/wenknow/access.log;
    error_log /var/log/nginx/wenknow/error.log;


    error_page   500 502 503 504  index.html;
}

server {
    listen 80;
    server_name wenknow.com www.wenknow.com; 
    rewrite ^(.*)$ https://$host$1; 
    location / {
        index index.html index.htm;
    }
}
# https://github.com/p4gefau1t/trojan-go/releases
# http://www.toseemore.top/0sfs7xds7lang669/hosteons182.yaml
评论