蹭个热度–V2ray的websocket+tls+webproxy+CDN的配置
继续上次topic,这次我来具体说下我在做v2ray的web+tls+cdn的配置的时候遇到的坑。
废话不说,先贴配置,看的明白的估计就不用看我废话了:
路由透明代理部分:
{
"inbounds": [
{
"tag": "ipsetin",
"port": 1188,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
}
}
],
"outbounds": [
{
"tag": "proxykcp",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "vps IP",
"port": 64662,
"users": [
{
"id": "UUID",
"alterId": 64,
"security": "auto"
}
]
}
]
},
"streamSettings": {
"network": "kcp",
"kcpSettings": {
"mtu": 1350,
"tti": 50,
"uplinkCapacity": 100,
"downlinkCapacity": 100,
"congestion": true,
"readBufferSize": 2,
"writeBufferSize": 2,
"header": {
"type": "srtp"
}
}
},
"mux": {
"enabled": true
}
},
{
"tag": "proxywstls",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "web domain",
"port": 443,
"users": [
{
"id": "uuid",
"alterId": 64,
"security": "aes-128-gcm"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"allowInsecure": true,
"serverName": null
},
"tcpSettings": null,
"kcpSettings": null,
"wsSettings": {
"connectionReuse": true,
"path": "path info",
"headers": {
"Host": "web domain, maybe no need"
}
}
},
"mux": {
"enabled": true
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {},
"streamSettings": {
"sockopt": {
"mark": 255
}
}
},
{
"protocol": "dns",
"tag": "dns-out"
}
],
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"inboundTag": [
"ipsetin"
],
"balancerTag": "my-balance"
}
],
"balancers": [
{
"tag": "my-balance",
"selector": [
"proxykcp"
]
}
]
}
}
VPS服务器端:
{
"inbounds":
[
{
"port": 1443,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "uuid",
"alterId": 64
}
]
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "path info"
}
}
},
{
"port": 64662,
"protocol": "vmess",
"settings":
{
"clients":
[
{
"id": "uuid",
"level": 1,
"alterId": 64
}
],
"detour":
{ //绕行配置,即指示客户端使用 dynamicPort 的配置通信
"to": "dynamicPort"
}
},
"streamSettings":
{
"network": "kcp",
"kcpSettings":
{
"mtu": 1350,
"tti": 50,
"uplinkCapacity": 100,
"downlinkCapacity": 100,
"congestion": true,
"readBufferSize": 2,
"writeBufferSize": 2,
"header":
{
"type": "srtp"
}
}
},
"sniffing":
{
"enabled": true,
"destOverride":
[
"http",
"tls"
]
}
},
{
"protocol": "vmess",
"port": "63000-65000",
"tag": "dynamicPort",
"settings":
{
"default":
{
"alterId": 64
}
},
"allocate":
{
"strategy": "random",
"concurrency": 2,
"refresh": 3
}
}
],
"outbounds":
[
{
"protocol": "freedom",
"settings": {}
},
{
"protocol": "blackhole",
"settings": {},
"tag": "blocked"
}
],
"routing":
{
"rules":
[
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "blocked"
}
]
}
}
希望不是很太影响阅读,毕竟我的Blog似乎对代码支持不是很好。毕竟我实在不是个会写代码的人。
首先来说服务器端。
这里实际上是3个大的部分,1个inbound的,KCP+动态端口配置, 一个是inbound的websocket入口配置。然后剩下就是直接freedom的outbound的配置。
事实上并不复杂, websocket入口在v2ray的服务器端,其实就是把network的类型改成ws, 并且把path配置写上对应的参数,v2ray服务器端其实就完事了。并没什么特殊。
然后我们来看透明代理端,我的配置里是1个inbound+2个outbound+load balance,其实一般只用一个,但是我为了自己方便,所以把个outbound都留着,这样我只要用一个load balance参数就可以直接切换了。
这中间呢,inbound使用的是v2ray官方推荐的dokodemo-door协议,基本也不用研究照抄就是了。
而跟websocket相关的其实只有第二个outbound配置,就是把目标设定为域名地址,然后再steam里配置了ws跟tls的那些。记得path的参数要能匹配的起来。以及端口一般用443去访问服务器端的webproxy.
然后就是重头戏了,我们怎么来处理我们的tls并且伪装成一个合法的https网页。
首先,到现在为止,我们的配置都是为了让我们自己这边的client端直接去访问我们在海外的VPS。所以,理论上,如果我们不管tls啥的,那么2端的端口号匹配的情况下,其实是就能直接通信的,我配置上KCP其实就是这样工作的。
但是,你们这样的思想很危险啊胸带。。。
因为实践证明,GFW是无所不能的,DPI下几乎完全无所遁形,各种特征指认都给你安排的明明白白,不是封端口就是封IP.
所以,从某种角度来说,我们需要tls封装来隐藏自己流量的特指。而tls最常见的情况就是https端口的网页。
所以,最容易实现的,就是在海外vps上再搭建一个简单的webproxy,把我们的流量伪装到https的网页流量用tls加密然而再由proxy转发到服务器端的v2ray。
所以这中间我们需要一个可以实现https的代理。
v2ray的手册上推荐的是Nginx, Apache和caddy.
我选了caddy,因为够简单,不用我自己管理域名。
不过如果你的域名还想加载cloudflare的cdn,那么谨慎选择,中间有个坑,带我详细说来。
caddy的安装配置不复杂,配置文件如下:
domain.name
{
log /var/log/caddy/caddy.log
tls {
dns cloudflare
}
proxy / https://website.com
proxy /v2ray/web localhost:1443 {
websocket
header_upstream -Origin
}
}
我选caddy是因为caddy会自动向letsencrypt 申请证书维护证书,所以省去了我去管这个东西的事情。
但是,因为我的域名用的是我blog的这个网站。所以我早就在cloudflare上有证书了。所以我是起了个二级域名挂在caddy上,想着让caddy自己去管吧。我在cloudflare上写个cname直接指向我vps的DNS名字就完事了(以为封IP端口的问题,我改用DNS名字而不是IP地址了这样我就可以随便改IP了)。然后caddy就各种申请证书出错。
然后一顿搜索以后,发现问题是可能因为已经有证书?所以要用caddy的一个cloudflare dns插件来引导caddy直接去cloudflare拉证书。
然而还是不行,懵了。
后来github上搜索到有人说用cloud dns插件的话,cname是不行的,要用A记录。似乎跟我一样,试试看,改了cloudflare的DNS记录。舒服了。
caddy可以起来了。
所以,要用caddy的,要么来个新的域名直接上。要么就做好可能处问题的准备。
你们会看到我的caddy的配置是有2条proxy的。
直接访问“/”根目录的会直接转发到你现在看的这个blog。这样就不会出现一直有巨大流量到这个IP但是却是个404页面的尴尬逻辑了。
然而下面,写了更加具体的“/wspath”的path参数的这条,才会把流量导入到local host的一个特殊端口,而这个端口就是vps上v2ray ws用的inbound端的端口号。
记住不要用443在这里,虽然我们的client端写的是443,因为我们从client端出来的目标是web proxy,而caddy一起来就会占用443跟80..所以从proxy到v2ray的端口需要用另外的,反正一般是同一台服务器所以可以随意别跟其他的重复就可以。我一开始没注意这个都用443然后就把自己坑了。唉..
到这里了,我们为tls准备的从客户端到服务器端的链路就基本打通了:
PC—路由器—路由器v2ray透明代理—vps web代理—vps v2ray—目标网站
这样的情况下,我们从本地到远端VPS的流量会被TLS包裹所以内容被加密了。
但是,GFW不care你加密啊。。。他可以直接把你IP封了啊。。。然后你号就没了。。。没了。。。没了。。。
所以,我们还是不够安全。
但是,既然从路由到vps这段我们走的是网页流量。。所以理论上,我们是可以使用CDN加速的。而CDN一加速,DNS记录上给出的IP就不是我们VPS真正的IP而是CDN服务的edge server IP. 那我们实际的VPS岂不是美滋滋?
所以,在前面的都可用的条件下,我们可以把我们的域名找个CDN加速服务弄上,然后确认下证书tls没问题以后。我们就可以通过CDN加速来隐藏我们真实的IP来保护我们的VPS服务器。
这就是使用V2ray完整的Websocket+tls+webproxy+CDN的故事了。
好吧,我写东西一般都比较乱所以要是看不明白….可以先看看官方文档啥的。就这样拉.
在彻底失去知情权之前再挣扎一把___花了一个周末把V2ray搞清楚了
为了保持自己那么一点点信息权力。
为了在彻底失去知情权之前再挣扎一把,这个周末,我花了2天,把现在当红的V2ray给折腾了一遍。
总的来说,v2ray在综合能力上确实要比ss或者ssr来得强大不少,毕竟本体就结合了多入口,多出口,DNS,路由选择,多种协议以及加密通信支持乃至于load balance.
但是同样的,功能的复杂以及自由度的提升,一样也造成了配置文件的复杂化,所以就没有那么即开即用化,友好程度明显降低。不过主要的难度还是集中在服务器端或者中转代理的配置上,用户端相对来说,在一些图形化client的帮助下,一般用户还是不难去掌握使用的。
我这次主要是为了让这v2ray能在我的ERL3上能顺利运转起来做透明路由(原先的SS花式断,基本废了。原因大家都理解),所以跟一般的客户端配置略有差异。不过能理解就行,毕竟逻辑跟原理是一样的。
首先值得高兴的是,ERL3在升级到2.0.x版本的固件后,后台的Debian内核也升级到了9.x…所以,习惯于用shadowscoks-libev 版本的同学,可以直接用APT安装了。并且,v2ray的官方go.sh安装脚本可以无障碍的直接在CLI下运行,完全不需要担心兼容性问题。
VPS端就不阐述一起必然需要的准备了,相信大部分DIY的留学生应该还是很熟悉这套操作的。
简单的来说,vps服务器端跟本地透明代理端,运行的东西完全一样。v2ray的官方文档也写的很清楚,v2ray本身并没有服务器端跟客户端的区别。所以除了配置文件的不同,2者其实是完全一样的东西哦。
所以我们要做的就是:
- 安装v2ray
- 写v2ray的配置文件
- 运行
听上去跟把大象放进冰箱一样的简单呢。
一切的关键都在配置文件里,很清楚了吧。
v2ray使用的是非常常见的JSON格式的配置文件。粗略的项目如下:
{
"log": {},
"api": {},
"dns": {},
"stats": {},
"routing": {},
"policy": {},
"reverse": {},
"inbounds": [],
"outbounds": [],
"transport": {}
}
简单的说就是这些模块的组合就能让v2ray工作起来。
其中我们一定需要理解的是,inbound, outbound以及routing。log最好能明白因为排错会很方便。 dns看需要,我个人更喜欢用gfw+ipset的分流,并且用ubound做DNS over Tls的解析。。所以dns我完成没涉及。但是据说很不错。至少看着能解决投毒的问题,所以也是值得研究的。
至于具体的inbound, outbound有哪些参数啥的,我个人推荐直接查下官方文档然后找几个配置example理解一下。应该还是不难理解的。
然后我们从逻辑上大概理解下v2ray是怎么工作的。
从本质上来说,v2ray,跟ss和ssr他们没有根本的区别。都是一样的代理转发工具。虽然v2ray更大更强更威猛,但是说到底他还是个二道贩子。主要的功能就是为了把从inbound进来的东西从outbound转发出去。就这么简单。
到了这里,有一点就很清晰了,就是client端的outbound的配置,需要跟server端inbound的配置相对应,这样双方才能平等交流互信互惠,一切都遵循和平共处五项原则。
我们来看个配置文件的实例,抄自白话版v2ray教程:
{
"inbounds": [
{
"port": 16823, // 服务器监听端口
"protocol": "vmess", // 主传入协议
"settings": {
"clients": [
{
"id": "b831381d-6324-4d53-ad4f-8cda48b30811", // 用户 ID,客户端与服务器必须相同
"alterId": 64
}
]
}
}
],
"outbounds": [
{
"protocol": "freedom", // 主传出协议
"settings": {}
}
]
}
这里其实就2个模块,一个inbound用来解决输入,一个outbound用来解决输出。至于中间的vmess, 这个是v2ray私有的通信协议,但是应该已经可识别特征,因为我在tcp模式下不管加不加伪装都被灭过不止一次端口。剩下的端口啊, id啥的。。都是一个作用。就是匹配握手。
所以把大的部分拆开了,还是不难去理解的。
那么v2ray就那么简单?显然不是啊。
为啥它牛呢,因为你现在看到的只是前面的部分,后面经过简单计算推导的结果还没出来啊。
因为v2ray的特征是模块化,并且本身就已经携带了如vmess, mKCP, shadowsocks, Mux,并且支持websocket, HTTPS, HTTP/2等多种协议,所以其本身的自由度非常巨大。即使不考虑商用多用户多服务器等大规模管理,我们依然面对了非常巨大的选择空间,从协议上,是选择shadowsocks还是vess. 通信的标准上使用tcp还是mKCP, KCP用静态还是动态端口。websocket是否需要加tls等等一系列的可供选择的配置。
一般而言,我们常见的是直接从客户端转发到海外VPS端的方式,这样是最直接最容易实现的,只要vps配置完,自己设备上有个v2ray能用的client端,GUI填一些简单参数就很容易搞定。
然而其次,就是我折腾了2天的网关/路由器透明代理。这种方式,对大多数用户其实跟第一种差不多,因为现在梅林啊,老毛子,LEDE等各种固件都集成了各种插件,这些插件用起来也不用自己写配置文件,GUI填下就好了。
我只是因为穷,买不起那些好用的,才只能手工自己写,踩了无数坑之后才搞定了。所以说,有钱就是可以为所欲为啊,哈哈哈。
v2ray还有一种链式代理的工作方式,是类似多重代理的方式。很玄妙。暂时我还没用到所以没有深入研究。
这样可能产生的配置组合就很多。现在比较常见的配置组合是,mKCP动态端口直连;websocket+tls+webproxy;以及号称最牛的组合:websocket+tls+webproxy+CDN的组合。
鉴于太长不适合阅读,我会在下一篇介绍下websocket+tls+webproxy+CDN的配置的一些细节以及我踩的坑。希望能我自己下次别再踩一遍。