trojan-go
trojan-go copied to clipboard
[QUESTION] trojan-go + nginx + sni转发 + cloudflare非完全CDN代理
背景描述: 主域名: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正常网站的功能了...
It was blocked by the GFW