p4gefau1t / trojan-go

Go实现的Trojan代理,支持多路复用/路由功能/CDN中转/Shadowsocks混淆插件,多平台,无依赖。A Trojan proxy written in Go. An unidentifiable mechanism that helps you bypass GFW. https://p4gefau1t.github.io/trojan-go/
GNU General Public License v3.0
7.54k stars 1.64k forks source link

[QUESTION] trojan-go + nginx + sni转发 + cloudflare非完全CDN代理 #484

Open prprDog opened 1 year ago

prprDog commented 1 year ago

背景描述: 主域名:xxxx.com 二级域名:trojan.xxxx.com, api.xxxx.com, www.xxxx.com 使用nginx的stream模块在传输层对不同情况的二级域名进行流量转发: trojan.xxxx.com -> trojan-go服务 api.xxxx.com -> 个人网站后台服务 www.xxxx.com、xxxx.com以及其他->个人网站

在cloudflare中,对api.xxxx.com, www.xxxx.com开启CDN,而特意关闭trojan.xxxx.com的CDN,在cloudflare仅改为DNS模式。 证书有两个:*.xxxx.com 泛域名证书, xxxx.com主域名证书,均为lets encrypt签发。

问题: 当为trojan.xxxx.com开启CDN时且trojan服务端开启对应websocket支持后,客户端可正常连接代理。 发现代理流量开启CDN后,延迟过高,于是将其关闭,仅在cloudflare将trojan.xxxx.com改为DNS模式,其他保持CDN开启不变: 当在cludflare中将trojan.xxxx.com改为DNS模式时且trojan服务端开启对应websocket支持后,客户端不可正常连接。 以为是websocket的原因,于是在上面的基础上,在服务端将trojan的websocket关闭,并在客户端将传输协议改为tcp——客户端仍然不可正常连接 以为是cloudflare部分二级域名开了CDN的原因,于是在关闭ws的基础上,在cloadlflare中把所有域名改成DNS模式,不走CDN流量——客户端仍然不可正常连接

是什么原因呢?为什么在stream中通过443转发代理流量除了在开启CDN的基础上使用ws可正常连接外,其他均不可以?

nginx配置文件——————

load_module /usr/lib64/nginx/modules/ngx_stream_module.so;
# user  www-data www-data;
user root;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

stream {
    map $ssl_preread_server_name $filtered_sni_name {
        api.xxx.com api;
        trojan.xxx.com trojan;
        xxx.com main;
        default web;

    }

    upstream trojan {
        server 127.0.0.1:37437;
    }

    upstream main {
        server 127.0.0.1:8002;
    }

    upstream web {
        server 127.0.0.1:8000;
    }

    upstream api {
        server 127.0.0.1:8001;
    }

    server {
        listen 443;
        listen [::]:443;
        resolver 8.8.8.8;
        ssl_preread on;
        proxy_pass $filtered_sni_name;
    }
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent  '
                      '"$http_referer" "$http_user_agent" "$http_x_forwarded_for"';
    access_log  /nginxweb/nginx-access.log  main;
    error_log /nginxweb/nginx-error.log;

    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  120;
    client_max_body_size 20m;
    gzip  on;

    include /etc/nginx/conf.d/*.conf; 
}

nginx虚拟服务配置文件——————

    server {
        listen       80;
        server_name  trojan.xxxx.com;
        return 301 https://www.xxxx.com$request_uri;

    }

    server {
        listen 8000 ssl http2;
        listen [::]:8000 http2;
        server_name  www.xxxx.com;

        ssl_certificate        /nginxweb/cert/fullchain.cer;
        ssl_certificate_key   /nginxweb/cert/private.key;
        ssl_protocols         TLSv1.2 TLSv1.3;
        ssl_ciphers           TLS-AES-256-GCM-SHA384:TLS-CHACHA20-POLY1305-SHA256:TLS-AES-128-GCM-SHA256:TLS-AES-128-CCM-8-SHA256:TLS-AES-128-CCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;

        # Config for 0-RTT in TLSv1.3
        ssl_early_data on;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security "max-age=31536000";

        root /nginxweb/myweb;
        index index.php index.html index.htm;

    }

    server {
        listen 8001 ssl http2;
        listen [::]:8001 http2;
        server_name  api.xxxx.com;

        #个人web后台服务
        ssl_certificate        /nginxweb/cert/fullchain.cer;
        ssl_certificate_key   /nginxweb/cert/private.key;
        ssl_protocols         TLSv1.2 TLSv1.3;
        ssl_ciphers           TLS-AES-256-GCM-SHA384:TLS-CHACHA20-POLY1305-SHA256:TLS-AES-128-GCM-SHA256:TLS-AES-128-CCM-8-SHA256:TLS-AES-128-CCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;

        # Config for 0-RTT in TLSv1.3
        ssl_early_data on;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security "max-age=31536000";
        location / {
          proxy_pass http://0.0.0.0:8081/;  
        } 

    }

    server {
        listen 8002 ssl http2;
        listen [::]:8002 http2;
        server_name  xxxx.com;
        # 第二个主域名证书
        ssl_certificate        /nginxweb/cert/another/fullchain.cer;
        ssl_certificate_key   /nginxweb/cert/another/private.key;
        ssl_protocols         TLSv1.2 TLSv1.3;
        ssl_ciphers           TLS-AES-256-GCM-SHA384:TLS-CHACHA20-POLY1305-SHA256:TLS-AES-128-GCM-SHA256:TLS-AES-128-CCM-8-SHA256:TLS-AES-128-CCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;

        # Config for 0-RTT in TLSv1.3
        ssl_early_data on;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security "max-age=31536000";
        root /nginxweb/myweb;
        index index.php index.html index.htm; 
    }

    server {
        listen 80;
        listen [::]:80;
        server_name  www.xxxx.com;
        return 301 https://www.xxxx.com$request_uri;
    }

trojan-go配置——————

{
    "run_type": "server",
    "local_addr": "0.0.0.0",
    "local_port": 37437,
    "remote_addr": "127.0.0.1",
    "remote_port": 80,
    "password": [
       一些密码
    ],
    "log_level": 1,
    "log_file": "/root/trojan-go-access.log",
    "ssl": {
        "verify": true,
        "verify_hostname": true,
        "cert": "/nginxweb/cert/fullchain.cer",
        "key": "/nginxweb/cert/private.key",
        "sni": "trojan.xxxx.com",
        "fallback_addr": "127.0.0.1",
        "fallback_port": 80, 
        "fingerprint": "chrome"
    },
  "tcp": {
    "no_delay": true,
    "keep_alive": true,
    "prefer_ipv4": false
  },
    "websocket": {
        "enabled": false,
        "path": "/346de536",
        "host": "trojan.xxxx.com"
    }
}

顺便一提,当为trojan.xxxx.com二级域名关闭cdn时,如果直接在客户端填上服务端trojan的端口(没走443),此时无论是tcp还是ws均可正常连接。当然这样trojan就失去了伪装443正常网站的功能了...

hannius commented 8 months ago

It was blocked by the GFW