0%

Nginx+V2ray+Trojan-Go

前言

目前常用的xx协议有:

  1. shadowsocks
  2. VMESS
  3. VLESS(VMESS的改进版)
  4. Trojan

shadowsocks和VMESS目前使用依旧广泛。VLESS是为了解决“总结近期发现的V2ray的弱点”中提出的问题而重新设计的一种协议,相比VMESS更加轻量、安全、高效。目前VMESS和VLESS最常用的组合为WebSocket+TLS+VMESS/VLESS的形式,这种形式在安全性上可以说和“主打”安全的Trojan基本相同(基本原理相同)。但是前者的配置相对来说更加复杂,而且前者性能相比后者差了很多(单机测试)。

本文主要介绍在同一台机器上配置V2ray+Trojan-Go并且二者共同使用443端口方法。整个网络流量流向图如下

网络流量流向图

配置基础环境

本文基于ubuntu 18.04进行配置

准备工作

  1. 一个能正常访问的vps
  2. 一个域名
  3. 解决基本依赖问题的能力

安装docker

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

sudo apt-get update

sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

安装Nginx

使用lnmp一键安装包进行安装

1
2
3
4
5
6
7
wget http://soft.vpser.net/lnmp/lnmp1.7.tar.gz -cO lnmp1.7.tar.gz && tar zxf lnmp1.7.tar.gz && cd lnmp1.7

# 修改nginx模块选项
vim lnmp.conf

# 修改Nginx_Modules_Options=''为Nginx_Modules_Options='--with-stream_ssl_preread_module',用来进行四层转发
./install.sh nginx

申请证书

申请证书前需要先将域名解析到vps的ip上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安装包管理工具snap
sudo apt install snapd
sudo snap install core; sudo snap refresh core

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# 配置证书
# 这个阶段申请证书时添加两个域名,一个域名用来连接v2ray,另外一个用来连接trojan-go
# 这种直接修改nginx配置文件(推荐使用这种方法,后面配置会少些工作)
sudo certbot --nginx --nginx-server-root /usr/local/nginx/conf/
# 这种没有直接修改nginx配置文件,只是申请证书
sudo certbot certonly --standalone

# 证书生成后会提示出certificate和chain以及key文件的存储目录,需要记录下来,后面配置v2ray和trojan需要用到

V2ray

安装

1
2
3
4
# 安装主体程序
bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)
# 安装最新发行的 geoip.dat 和 geosite.dat
bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-dat-release.sh)

配置

这部分参照终极配置添加了适当的注释说明,强烈建议使用vless+xtls的方式。VMESS已经不是很安全了。实际使用需要去掉注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"listen": "127.0.0.1", // 增加这一行是因为我们最终会使用nginx进行分流,实现443同时用于V2ray和Trojan的效果
"port": 10000, // 与上同理,不需要监听443端口了
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // 填写你的 UUID
"flow": "xtls-rprx-origin",
"level": 0,
"email": "love@v2fly.org"
}
],
"decryption": "none",
"fallbacks": [
{
"dest": 80 // 这里是为了回落到一个正常的网站,防止被嗅探
},
{
"path": "/websocket", // 回落到websocket,如果不使用该配置可以去掉这部分
"dest": 1234, // 端口
"xver": 1
},
{
"path": "/vmesstcp", // 回落到vmess+tcp,如果不使用该配置可以去掉这部分
"dest": 2345,
"xver": 1
},
{
"path": "/vmessws", // 回落到vmess+ws
"dest": 3456,
"xver": 1
}
]
},
"streamSettings": {
"network": "tcp",
"security": "xtls",
"xtlsSettings": {
"alpn": [
"http/1.1"
],
"certificates": [
{
"certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径
"keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径
}
]
}
}
},
{
"port": 1234,
"listen": "127.0.0.1",
"protocol": "vless",
"settings": {
"clients": [
{
"id": "", // ID可以与上面的不同,也可以相同
"level": 0,
"email": "love@v2fly.org"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行
"path": "/websocket" // 必须换成自定义的 PATH,需要和分流的一致
}
}
},
{
"port": 2345,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // ID可以与上面的不同,也可以相同
"level": 0,
"email": "love@v2fly.org"
}
]
},
"streamSettings": {
"network": "tcp",
"security": "none",
"tcpSettings": {
"acceptProxyProtocol": true,
"header": {
"type": "http",
"request": {
"path": [
"/vmesstcp" // 必须换成自定义的 PATH,需要和分流的一致
]
}
}
}
}
},
{
"port": 3456,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "", // ID可以与上面的不同,也可以相同
"level": 0,
"email": "love@v2fly.org"
}
]
},
"streamSettings": {
"network": "ws",
"security": "none",
"wsSettings": {
"acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行
"path": "/vmessws" // 必须换成自定义的 PATH,需要和分流的一致
}
}
}
],
"outbounds": [
{
"protocol": "freedom"
}
]
}

运行

1
2
3
4
5
6
7
8
9
sudo service v2ray start
# 使用下面命令查看是否运行成功
sudo service v2ray status

# 这里可能会无法运行成功,因为v2ray没有权限去读取证书文件,可以修改运行v2ray的运行权限
# 改为使用root用户运行
sudo vim /etc/systemd/system/v2ray.service
sudo systemctl daemon-reload
sudo service v2ray start

Trojan

安装

使用docker的方式部署trojan

1
2
3
4
5
git clone https://github.com/p4gefau1t/trojan-go.git && cd trojan-go/
# 创建镜像
cat Dockerfile | sudo docker build -t trojan -
# 下面的命令中注意两个-v后面的参数中引号部分都需要根据实际情况进行替换
sudo docker run -it --net=host --rm --name trojan -v “宿主机trojan配置文件地址”:/etc/trojan-go/config.json -v /etc/letsencrypt/archive/"domain.com"/:/ssl/ trojan

配置

参照官方的完整配置文件进行修改说明,实际使用需要去掉注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
"run_type": "server", // 运行模式,服务器端为server
"local_addr": "127.0.0.1", // 监听地址,如果仅使用trojan,这里设置为0.0.0.0
"local_port": 20000, // 监听端口
"remote_addr": "127.0.0.1", // 回落地址,当访问流量为非trojan时重定向的位置
"remote_port": 80, // 回落端口,当访问流量为非trojan时重定向的端口
"log_level": 1,
"log_file": "",
"password": [], // 密码,可以有多个
"disable_http_check": false,
"udp_timeout": 60,
"ssl": {
"verify": true,
"verify_hostname": true,
"cert": "/ssl/fullchain1.pem", // certificate和chain文件地址
"key": "/ssl/privkey1.pem", // key文件地址
"key_password": "",
"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",
"cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
"curves": "",
"prefer_server_cipher": true,
"sni": "",
"alpn": [
"http/1.1"
],
"session_ticket": true,
"reuse_session": true,
"plain_http_response": "",
"fallback_addr": "127.0.0.1", // tls握手失败是回落地址,必须有,运行trojan时会检测该地址,检测不通过无法启动
"fallback_port": 80, // tls握手失败是回落端口,必须有,运行trojan时会检测该端口,检测不通过无法启动
"fingerprint": "firefox"
},
"tcp": {
"no_delay": true,
"keep_alive": true,
"prefer_ipv4": false
},
"mux": {
"enabled": true, // 是否开启多路复用
"concurrency": 8,
"idle_timeout": 60
},
"router": {
"enabled": false,
"bypass": [],
"proxy": [],
"block": [],
"default_policy": "proxy",
"domain_strategy": "as_is",
"geoip": "$PROGRAM_DIR$/geoip.dat",
"geosite": "$PROGRAM_DIR$/geosite.dat"
},
"websocket": {
"enabled": false,
"path": "",
"host": ""
},
"shadowsocks": {
"enabled": false,
"method": "AES-128-GCM",
"password": ""
},
"transport_plugin": {
"enabled": false,
"type": "",
"command": "",
"option": "",
"arg": [],
"env": []
},
"forward_proxy": {
"enabled": false,
"proxy_addr": "",
"proxy_port": 0,
"username": "",
"password": ""
},
"mysql": {
"enabled": false,
"server_addr": "localhost",
"server_port": 3306,
"database": "",
"username": "",
"password": "",
"check_rate": 60
},
"api": {
"enabled": false,
"api_addr": "",
"api_port": 0,
"ssl": {
"enabled": false,
"key": "",
"cert": "",
"verify_client": false,
"client_cert": []
}
}
}

运行

1
2
# 注意下面的映射地址需要根据实际情况填写
sudo docker run -idt --net=host --rm --name trojan -v "宿主机trojan配置文件绝对地址":/etc/trojan-go/config.json -v "宿主机证书文件绝对地址,不能是链接文件地址":/ssl/ trojan

Nginx配置

Nginx配置是实现443端口复用的关键,因此作为单独一部分进行介绍,如果仅使用v2ray或者trojan,那么这部分可以跳过。

直接上配置文件部分,基于程小白博客中的内容进行修改,在此感谢。使用lnmp安装的nginx的配置文件在/usr/local/nginx/conf/目录下。

修改好配置文件后使用nginx -s reload命令重新加载配置文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
user  nginx;

pid /var/run/nginx.pid;

# 其他配置保持默认即可

# 流量转发核心配置
stream {
# 这里就是 SNI 识别,将域名映射成一个配置名
map $ssl_preread_server_name $backend_name {
域名1 vless;
域名2 trojan;
# 域名都不匹配情况下的默认值
default trojan;
}

# vless,配置转发详情,端口为上述vless配置文件中的第一个端口,这里为10000
upstream vless {
server 127.0.0.1:10000;
}

# trojan,配置转发详情,端口为上述trojan配置文件中的第一个端口,这里为20000
upstream trojan {
server 127.0.0.1:20000;
}

# 监听 443 并开启 ssl_preread
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $backend_name;
ssl_preread on;
}
}

http {
# 这块保持不变即可
}

注意事项

上面生成证书时如果已经直接修改了nginx,那这里我们需要去掉server中已经配置好的对443端口的监听。

其他注意事项

证书问题

更新

免费的证书有效期为3个月,因此每三个月需要更新一次,可以使用crontab进行自动调度。

1
0 3 * * * certbot renew >> /dev/null

VMESS+WS+TLS兼容问题

笔者在配置的过程中遇到过始终无法兼容旧版VMESS+WS+TLS的问题。通过实测,感觉应该是服务器v2ray-core与客户端版本不兼容导致的。因此当出现不兼容问题时,建议先升级客户端的v2ray-core版本。

参考

Install Docker Engine on Ubuntu

Building nginx from Sources

安装 - LNMP一键安装包

Trojan 共用 443 端口方案

Certbot

v2fly/fhs-install-v2ray

v2fly/v2ray-examples

简介

请作者喝咖啡