Nginx+https+Trojan

Nginx对Https的反向代理

使用Nginx进行反向代理的时候,对于正常的http;流量使用 location 块并且配置 proxy_pass 转发即可,但是如果是https的流量,使用Nginx进行反向代理的时候,直接使用 proxy_pass 会出现各种报错的情况,包括不限于:

  • 502 Bad Getway
  • ERR_SSL_PROTOCOL_ERROR
  • ERR_CONNECTION_RESET
  • ERR_CONNECTION_CLOSED
    我本身遇到的ERR_SSL_PROTOCOL_ERROR错误比较多,这是因为在配置Nginx的时候,对于443端口本身的侦听没有带上 ssl 关键字,所以会报SSL协议错误,但是如果加上ssl,没有给证书位置,也是不行;
    对于转发到8080端口,如果配置不对,会出现502 Bad Getway:
  1. proxy_pass后边的要写IP地址,不能写域名,否则还要解决域名解析的问题,有据称如果写localhost的,访问速度会变慢,是因为需要访问host文件解析localhost
  2. 响应8080端口的server块,也要注意,也要写成侦听ssl,配置好证书位置

P.S. 如果因为反向代理,日志内部都是127.0.0.1的访问,可以把日志设置写到反向代理的那个server块中,这样日志就会是正常ip了。

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name ***.com;
    ssl_certificate ***.pem;
    ssl_certificate_key ***.pem;

    location / {
        proxy_pass https://127.0.0.1:8080$request_uri;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

对于 location 代码块中,如果反向代理的服务有上传业务,需要注意的是需要在location代码块中,或者需要的限定域中填写上

client_max_body_size 64M;

这样nextcloud上传大文件就不会莫名报错。

Nginx与Trojan共用443端口

这个部分主要是摘自Trojan 共用 443 端口方案
首先是为什么Nginx可以同时在443侦听多个https服务?因为是通过不同的SNI(TLS 服务器名称指示)来区分不同的域名的。

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

这是原文的流量图
流量图

首先得明确,Trojan 是无法通过 Nginx 在 7 层进行代理的,所以它设定必须在流量入口,Nginx 都只能挂在它的后面。

所以总的来说,就是所有流量都是通过443先打到Nginx,再由Nginx负责分发,转到相应的端口。

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

P.S. 下面的Nginx配置和Trojan配置都是摘自原文

Nginx配置如下
user  nginx;

pid   /var/run/nginx.pid;

# 其他配置保持默认即可

# 流量转发核心配置
stream {
    # 这里就是 SNI 识别,将域名映射成一个配置名
    map $ssl_preread_server_name $backend_name {
        web.cn.chengxiaobai web;
        vmess.cn.chengxiaobai vmess;
        trojan.cn.chengxiaobai trojan;
    # 域名都不匹配情况下的默认值
        default web;
    }

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

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

    # vmess,配置转发详情
    upstream vmess {
        server 127.0.0.1:10242;
    }

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

http {
  # 这块保持不变即可
}
Trojan配置如下
{
  "run_type": "server",
  "local_addr": "127.0.0.1",
  "local_port": 10241,
  "remote_addr": "127.0.0.1",//转发回 nginx 默认页面
  "remote_port": 80,
  "password": [
    "密码"
  ],
  "log_level": 3,
  "ssl": {
    "cert": "证书地址.crt",
    "key": "证书地址.key",
    "key_password": "",
    "cipher": "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:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384",
    "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
    "prefer_server_cipher": true,
    "alpn": [
      "http/1.1"
    ],
    "alpn_port_override": {
      "h2": 81
    },
    "reuse_session": true,
    "session_ticket": false,
    "session_timeout": 600,
    "plain_http_response": "",
    "curves": "",
    "dhparam": ""
  },
  "tcp": {
    "prefer_ipv4": false,
    "no_delay": true,
    "keep_alive": true,
    "reuse_port": false,
    "fast_open": false,
    "fast_open_qlen": 20
  },
  "mysql": {
    "enabled": false,
    "server_addr": "127.0.0.1",
    "server_port": 3306,
    "database": "trojan",
    "username": "trojan",
    "password": "",
    "cafile": ""
  }
}

Nginx 层统一管理收敛流量入口,整个主机只用开启 443 和 SSH 端口即可,同时各个模块都做了伪装,「非标请求」看到的都是正常的页面,而且 WS 协议的 CDN 大法完美支持。

同时得益于 Nginx 的优秀性能和对 HTTP 协议的支持力度,全部请求都可以 HTTP2。

Ref

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值