使用Doprax搭建免费的Shadowsocks服务。

有现成的V2ray for Doprax方案。但是我一直是用Shadowsocks的,也不想换客户端。而且一看v2ray,和Shadowsocks相比,真的太复杂了,配置一大堆,看了文档也非常混乱,一比较就完全放弃。于是想研究ss能不能也整一个。

先说结论:使用v2ray-plugin插件将shadowsocks流量伪装成http协议,穿透Cloudflare网关,使用隧道转发到服务端。客户端使用安装了对应插件的客户端连接到服务端。并且可以支持v2ray客户端例如V2rayU连接

本来想尝试使用simple-obfs,因为ios的免费客户端上基本上内置这个,后来在成功实现v2ray-plugin方式之后,又继续研究了很久,发现由于Cloudflare的影响,导致没办法实现这个方案。

使用后感受:不好用。

套了Cloudflare隧道之后也非常慢,巨慢无比,几乎没法用。另外iOS里也没找到支持V2ray-plugin的好用的Shadowsocks客户端(付费的除外。我现在用的是Potatso只支持simple-obfs插件。也没找到v2ray好用的客户端(付费版除外。 所以本文更多的是学习性质。

避免滥用Doprax,人人有责。

关于Doprax

Doprax目前每个注册用户可以运行一个容器,1CPU256MB的资源,没有限制带宽。

容器创建之后会提供一个dopraxrocks.com的三级域名,可以使用https访问。网关会将流量转发到容器内部的的http80端口上。

当然了,也可以使用自己的域名设置指向dopraxrocks的记录,使用自己的域名访问服务。

又有人问,系统赠送的域名国内访问速度堪忧,于是,就再用cloudflare套一层转发。

很明显,不管cloudflare还是doprax,都是只能将http(s)转发到容器。

因此Shadowsocks原始的协议肯定是无法转发的,为了能够正常使用,需要在协议上套一层http(s)

这不就是现成的v2ray-pluginsimple-obfs插件。这两个插件都是将Shadowsocks协议伪装成http,利用这个,就可以实现穿透cloudflaredoprax的网关。

放弃SIMPLE-OBFS方案

随着进一步的测试,以及simple-obfs源码阅读,发现这个方案行不通,主要有几点问题。

  1. obfs最后的版本0.0.5支持的TLS不是真正的https。解决方法:cloudflare隧道方案要改用http转发。
  2. obfs实现的websocket也不是真正的websocketcloudflarewebsocket的处理会对数据进行重写。解决方法:在cloudflare网络设置中,关闭对websocket的支持。
  3. cloudflarehttp(s)请求转发时会删改与增加cf-平台方的头部,导致obfs-server不能正确解析数据。解决方法:在obfs-server前再增加一个Nginx对请求头重写,包括修改http版本号。
  4. cloudflarehttp(s)响应返回时,也会增加额外cf-平台方的头部,导致obfs-client不能正确解析数据。在cloudflareRules菜单配置响应头时,提示不能删除cf-等平台方头部。

上述的前3点是已经解决,主要是第4点,对响应头修改问题,无法解决。官方在文档也明确说了平台方加的头部是无法去除的。而obfs方面,源码里有对http头部的hard code,对头部的字段固定限制。

由于不可能在客户端部署其他服务重写响应头,所以在不修改obfs-client的情况下,是没法正确解析数据。但是这个项目后续也不会维护了。

因此如果要使用这个插件,通过cloudflare是做不了了,需要换一家隧道服务,不会对内容进行修改的那种,应该是有的,但是我也不想找了。

因此放弃SIMPLE-OBFS方案,整体结构如下。

Cloudflare域名与Tunnel创建

域名

使用Cloudflare加速的话是必须要配置的。

登录到Cloudflare后先添加域名,按提示一步步操作就可以。主要就是到域名提供商处修改DNS服务器。

默认是强制启用https重定向的,可以关,但是不重要,后续我们也都直接用https就好了。

隧道

Cloudflare Tunnel可以将内网端口穿透到公网域名,主要是免费,是比较方便的一个内网穿透工具。

菜单进入 Cloudflare Zero Trust页面,在菜单Access里的tunnels创建新的隧道。

创建完成之后,设置公网域名,将提供服务的域名绑定上,并配置需要转发的协议与端口。为了方便,我们直接绑定到ss服务默认端口http://localhost:8388。 另外也可以绑定路径,对应的客户端也需要配置对应的参数,默认就是根路径/

设置完成之后,访问上面域名就可以直接请求到http://localhost:8388了。

然后在隧道概述页,下面随便一个安装命令里面,得到隧道对应的token,这个token后面需要用到

Doprax服务创建与启动

域名、转发等一堆事情弄好了,终于开始正文了。

创建应用

注册登录Doprax,然后新建一个应用。

进入应用之后,首先是导入源码。

可以 fork Shadowsocks-with-v2ray-plugin-for-Doprax项目后, 账号绑定Github账号,从代码仓库里导入。

也可以手动创建dockerfile文件,把Shadowsocks-with-v2ray-plugin-for-Doprax项目里的dockerifile复制进去。

需要修改里面的环境变量参数,也可以在页面下面添加,加密方式,密码,隧道的token与端口四个环境变量,配置比较简洁的。一般情况下配置个密码和隧道token就能用了。端口和加密方式一般也不用修改。

启动容器

添加完代码后,到Deploy界面,可以看到当前的容器运行情况,直接运行就可以了。这里提供的域名会把请求转发到80端口上,所以我们用不上。

启动完成之后,到Cloudflare隧道页面看到状态是healthy说明隧道启动成功。访问绑定的域名如果是400 Bad Request说明v2ray-plugin也启动成功了。

客户端配置

shadowsocks客户端

端口填443, 插件填入v2ray-plugin, 插件参数填入tls;host=域名地址;

如果用的是http:80端口,参数需要对应修改。

Mac上如果是用的ShadowsocksX-NG,自带v2ray-plugin插件,对应写一个配置就可以。

Windows上如果是用的shadowsocks-windows,需要手动下载v2ray-plugin插件,下载后放到小飞机同一个文件夹,文件名改成v2ray-plugin.exe。其他参数一样填写。

v2ray客户端

众所周知,v2ray-plugin是可以使用v2ray客户端连接的,所以这里提供了对应的连接配置。

参考了v2ray-plugin/issues/49这个回答,是有一点点复杂,给我我是写不来。

具体的参数含义可以查看v2ray官网

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
{
"inbounds": [{
"port": 1081,
"listen": "127.0.0.1",
"protocol": "socks"
}],
"outbounds": [{
"tag": "protocol_layer",
"protocol": "shadowsocks",
"settings":{
"servers": [{
"address": "ss.example.com",
"port": 443,
"method": "aes-256-gcm",
"password": "password"
}]
},
"proxySettings": {
"tag": "transport_layer"
}
},
{
"tag": "transport_layer",
"protocol": "freedom",
"settings": {
"redirect": "ss.example.com:443"
},
"streamSettings": {
"network": "ws",
"security": "tls"
},
"mux": {
"enabled": true
}
}]
}

Docker

v2fly-core镜像

1
docker run --rm -p1081:1081 -v `pwd`/v2ray_client_for_ss.json:/etc/v2fly/config.json v2fly/v2fly-core run -c /etc/v2fly/config.json

shadowsocks-libev镜像

1
docker run --rm -p1081:1081 -v/path/to/v2ray-plugin:/usr/bin/v2ray-plugin shadowsocks/shadowsocks-libev ss-local -sss.example.com -p443 -b0.0.0.0 -l1081 '-kpassword' -maes-256-gcm --plugin v2ray-plugin --plugin-opts "tls;host=ss.example.com;"