Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
prprDog opened this issue Jan 17, 2023 · 1 comment
Open

Comments

@prprDog
Copy link

prprDog commented Jan 17, 2023

背景描述:
主域名: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
Copy link

hannius commented Oct 27, 2023

It was blocked by the GFW

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants