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.82k stars 1.69k forks source link

[Question] Trojan-go through CDN #240

Open buttbuddy2020 opened 3 years ago

buttbuddy2020 commented 3 years ago

I know this is possible. I found some tutorials for cloudflare. The problem is you need to register a domain name and get a cert signed by a CA for this domain. This is not always feasible and you can't change registered domains as quick as IP addresses and some providers are picky on what they will sign. Most CDN's strip off https. When you get a signed cert you can connect to the origin by TLS (like in the cloudflare tutorials) but if you only have a self signed cert the connection will break in case of aws cloudfront. It also looks like in case of Azure you don't even get a successful handshake to the CDN ("server selected unsupported group" error ) I guess you can't really do anything about the CDN. Would it be possible for trojan-go to do a successful handshake to the CDN, TLS gets stripped off, but the http connection to the origin is still encrypted by some other method?

DuckSoft commented 3 years ago

Use transport_plugin of "plaintext".

buttbuddy2020 commented 3 years ago

This seems to send everything in clear and not over https. Can't the initial handshake be TLS and an underlying layer (either created by trojan-go or some external tool) does additional encryption? Like:

trojan-go client --> HTTPS connection --> CDN --> (encrypted) HTTP connection --> trojan-go server

buttbuddy2020 commented 3 years ago

I think I have made some progress, but not 100% yet. At least trojan-go client hits the websocket on the remote end. You can see it from the server logs and tcpdump that the file is fetched. The trojan-go remote server is listening on port 80 because currently cloudfront starts connections from the CDN to the origin only via HTTP. I have seen some mention of DoubleTLS but it is not in the official docs so I don't know if it is required in some way. From the error on the server it seems like trojan-go websocket expects a TLS handshake (which won't happen from CDN to origin). Additionally enabling shadowsocks does not seem to make a difference. When I use plaintext transport plugin just on the server I guess the trojan-go would not expect any TLS (I'm not sure though) but it also does not work in this case.

Trojan-go 0.8.2 linux amd64 + nginx

server:

{ "run_type": "server", "local_addr": "0.0.0.0", "local_port": 80, "remote_addr": "127.0.0.1", "remote_port": 8080, "log_level": 0, "log_file": "/var/log/trojan_server.log", "password": [ "supersecure" ], "disable_http_check": false, "udp_timeout": 60, "ssl": { "cert": "/etc/server.crt", "key": "/etc/server.key", "fallback_port": 8443 }, "router": { "enabled": true, "bypass": [], "proxy": [], "block": [], "default_policy": "proxy", "domain_strategy": "as_is" }, "websocket": { "enabled": true, "host": "something.cloudfront.net", "path": "/websocketurl", "DoubleTLS": false }, "transport_plugin": { "enabled": false, "type": "plaintext", "command": "", "plugin_option": "", "arg": [], "env": [] }, "shadowsocks": { "enabled": false, "method": "AES-128-GCM", "password": "shadowsocks" } }

server log:

router client created [INFO] 2020/12/15 18:04:35 tcp connection from 64.252.177.134:12252 [ERROR] 2020/12/15 18:04:35 github.com/p4gefau1t/trojan-go/tunnel/tls.(Server).acceptLoop .func1:server.go:120 failed to perform tls handshake with 64.252.177.134:12252, redirectin g | tls: first record does not look like a TLS handshake [DEBUG] 2020/12/15 18:04:35 github.com/p4gefau1t/trojan-go/redirector.(Redirector).Redire ct:redirector.go:33 redirect request [WARN] 2020/12/15 18:04:35 redirecting connection from 64.252.177.134:12252 to 127.0.0.1: 8443 [INFO] 2020/12/15 18:04:40 redirection done

nginx:

server { listen 127.0.0.1:8080 default_server; listen 127.0.0.1:8443 default_server; root /var/www/something.amazonaws.com; index index.html index.htm index.nginx-debian.html; server_name something.amazonaws.com; location / { try_files $uri $uri/ =404; }

nginx access log:

127.0.0.1 - - [15/Dec/2020:18:04:35 +0000] "GET /websocketurl HTTP/1.1" 200 524 "-" "Amazon CloudFront"

client:

{ "run_type": "client", "local_addr": "127.0.0.1", "local_port": 80, "remote_addr": "something.cloudfront.net", "remote_port": 443, "log_level": 0, "log_file": "/var/log/trojan_client.log", "password": [ "supersecure" ], "ssl": { "verify": true, "verify_hostname": true, "sni": "something.cloudfront.net", "prefer_server_cipher": false, "fingerprint": "firefox" }, "transport_plugin": { "enabled": false, "type": "shadowsocks", "command": "", "option": "", "arg": [], "env": [] }, "websocket": { "enabled": true, "host": "something.cloudfront.net", "DoubleTLS": false, "path": "/websocketurl" }, "shadowsocks": { "enabled": false, "method": "AES-128-GCM", "password": "shadowsocks" } }

client log:

18:27:08 adapter listening on tcp/udp: 127.0.0.1:80 [DEBUG] 2020/12/15 18:27:08 github.com/p4gefau1t/trojan-go/tunnel/socks.NewServer:server.g o:261 socks server created [DEBUG] 2020/12/15 18:27:08 github.com/p4gefau1t/trojan-go/tunnel/tls/fingerprint.GetClien tHelloSpec:tls.go:229 websocket http/1.1 [INFO] 2020/12/15 18:27:08 tls fingerprint firefox applied [INFO] 2020/12/15 18:27:08 cert is unspecified, using default ca list [DEBUG] 2020/12/15 18:27:08 github.com/p4gefau1t/trojan-go/tunnel/tls.NewClient:client.go: 155 tls client created [DEBUG] 2020/12/15 18:27:08 github.com/p4gefau1t/trojan-go/tunnel/websocket.NewClient:clie nt.go:58 websocket client created [DEBUG] 2020/12/15 18:27:08 github.com/p4gefau1t/trojan-go/statistic/memory.NewAuthenticat or:memory.go:240 memory authenticator created [DEBUG] 2020/12/15 18:27:08 github.com/p4gefau1t/trojan-go/tunnel/trojan.NewClient:client. go:170 trojan client created [DEBUG] 2020/12/15 18:27:31 github.com/p4gefau1t/trojan-go/tunnel/adapter.(Server).accept ConnLoop:server.go:49 socks5 connection [INFO] 2020/12/15 18:27:31 socks connection from 127.0.0.1:56134 metadata 34.193.116.2:44 3 [DEBUG] 2020/12/15 18:27:31 github.com/p4gefau1t/trojan-go/tunnel/tls/fingerprint.GetClien tHelloSpec:tls.go:229 websocket http/1.1 [ERROR] 2020/12/15 18:27:31 github.com/p4gefau1t/trojan-go/proxy.(Proxy).relayConnLoop.fu nc1.1:proxy.go:66 proxy failed to dial connection | websocket failed to handshake with ser ver | bad status

DrKenther commented 2 years ago

trojan.conf in server ... "transport_plugin": { "enabled": true, "type": "plaintext", "command": "", "plugin_option": "", "arg": [], "env": [] }, ...