当远端服务器的443与80端口已经运行着Http Server后, 如何复用端口以允许trojan同样监听443呢?
配置需求
-
Web Server
-
两套SSL证书签名
基本原理
trojan的基本原理大概如下图, 但好像不完全正确:
实际上在我们的实现中, 是利用SSL SNI(Server Name Indication)技术在nginx上实现分流转发…
Nginx开放80与443端口, 接收外来请求, 通过stream设置为: 当请求443端口且SSL SNI选择某个特定子域名后, 则转发给后台的trojan服务端口, 而其余情况下则默认发往Web服务端口.
而在trojan的配置中, remote addr则设置为专门为trojan启用的另一个Nginx Web服务端口, 该端口不需要SSL认证, 认证的证书和密钥存放在trojan配置文件中, trojan会为我们进行认证.
nginx配置如下:
Text
1#user http;
2worker_processes 1;
3
4#error_log logs/error.log;
5error_log /var/log/nginx/error.log notice;
6# error_log logs/error.log info;
7
8#pid logs/nginx.pid;
9
10
11events {
12 worker_connections 1024;
13}
14
15stream{
16 map $ssl_preread_server_name $backend_name {
17 magic.rqdmap.top trojan;
18 default web;
19 }
20
21 upstream web {
22 server 127.0.0.1:4433;
23 }
24
25 upstream trojan {
26 server 127.0.0.1:60012;
27 }
28
29 server {
30 listen 443 reuseport;
31 listen [::]:443 reuseport;
32 proxy_pass $backend_name;
33 ssl_preread on;
34 }
35}
36
37http {
38 include mime.types;
39 default_type application/octet-stream;
40
41 log_format main '$remote_addr - $remote_user [$time_local] "$request" '
42 '$status $body_bytes_sent "$http_referer" '
43 '"$http_user_agent" "$http_x_forwarded_for"';
44
45 access_log /var/log/nginx/accessWeb.log main;
46
47 sendfile on;
48 #tcp_nopush on;
49
50 #keepalive_timeout 0;
51 keepalive_timeout 65;
52
53 #gzip on;
54
55 server {
56 listen 80;
57 server_name localhost;
58 rewrite ^(.*)$ https://$host$1;
59 }
60
61 server {
62 listen 127.0.0.1:4433 ssl;
63 server_name localhost;
64
65 ssl_certificate /usr/local/nginx/key/rqdmap.top.pem;
66 ssl_certificate_key /usr/local/nginx/key/rqdmap.top.key;
67
68 ssl_session_cache shared:SSL:1m;
69 ssl_session_timeout 5m;
70
71 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
72 ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
73 ssl_prefer_server_ciphers on;
74
75 location / {
76 root /usr/share/nginx/html;
77 index index.html index.htm;
78 }
79
80 #error_page 404 /404.html;
81
82 # redirect server error pages to the static page /50x.html
83 #
84 error_page 500 502 503 504 /50x.html;
85 location = /50x.html {
86 root /usr/share/nginx/html;
87 }
88
89 }
90
91 server {
92 listen 127.0.0.1:4434;
93 server_name localhost;
94
95 location / {
96 root /usr/share/nginx/html;
97 index index.html index.htm;
98 }
99
100 #error_page 404 /404.html;
101
102 # redirect server error pages to the static page /50x.html
103 #
104 error_page 500 502 503 504 /50x.html;
105 location = /50x.html {
106 root /usr/share/nginx/html;
107 }
108 }
109}
trojan配置:
Text
1{
2 "run_type": "server",
3 "local_addr": "127.0.0.1",
4 "local_port": 60012,
5 "remote_addr": "127.0.0.1",
6 "remote_port": 4434,
7 "password": [
8 "..."
9 ],
10 "log_level": 1,
11 "ssl": {
12 "verify_hostname": true,
13 "cert": "/usr/local/nginx/key/magic.rqdmap.top.pem",
14 "key": "/usr/local/nginx/key/magic.rqdmap.top.key",
15 "sni": "magic.rqdmap.top",
16 "key_password": "",
17 "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",
18 "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
19 "prefer_server_cipher": true,
20 "alpn": [
21 "http/1.1"
22 ],
23 "alpn_port_override": {
24 "h2": 81
25 },
26 "reuse_session": true,
27 "session_ticket": false,
28 "session_timeout": 600,
29 "plain_http_response": "",
30 "curves": "",
31 "dhparam": ""
32 }
33}
后记
没几天就G了, 效果甚至不如v2ray + ws + tls的组合…….一个猜测是因为子域名用了比较简单的字符串, 另一个原因是传统的trojan报文头已经能被检测(大概率)
暂时不主力用自建了, 只能当备用感觉, 而且感觉不够一劳永逸…..