trojan+nginx共用443端口

 Linux  nginx  trojan 󰈭 906字

当远端服务器的443与80端口已经运行着Http Server后, 如何复用端口以允许trojan同样监听443呢?

配置需求

  • Web Server

  • 两套SSL证书签名

基本原理

trojan的基本原理大概如下图, 但好像不完全正确:


图片来源: 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配置如下:

  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配置:

 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报文头已经能被检测(大概率)

暂时不主力用自建了, 只能当备用感觉, 而且感觉不够一劳永逸…..

嗨! 这里是 rqdmap 的个人博客, 我正关注 GNU/Linux 桌面系统, Linux 内核, 后端开发, Python, Rust 以及一切有趣的计算机技术! 希望我的内容能对你有所帮助~
如果你遇到了任何问题, 包括但不限于: 博客内容说明不清楚或错误; 样式版面混乱等问题, 请通过邮箱 rqdmap@gmail.com 联系我!
修改记录:
  • 2023-05-29 23:05:14大幅重构了python脚本的目录结构,实现了若干操作博客内容、sqlite的助手函数;修改原本的文本数 据库(ok)为sqlite数据库,通过嵌入front-matter的page_id将源文件与网页文件相关联
  • 2023-05-08 21:44:36博客架构修改升级
  • 2023-05-05 01:21:43取消trojan+nginx端口复用的隐藏
  • 2022-12-12 15:41:18更新了trojan的使用结果
  • 2022-12-08 20:28:04trojan+nginx共用443端口
trojan+nginx共用443端口