用v2ray搭个反向代理,留个痕迹方便以后抄作业,就不折腾frp了。
(v2ray的反代还是太烂了,frp真香)
入门:微软远程桌面反代
teamviewer太辣鸡了。
teamviewer太辣鸡了。
teamviewer太辣鸡了。
重要的事情说三遍,现在还不如win10系统自带的远程桌面,至少没辣么恶心。
需要反代的机子
这机子就是指你要控制的那台电脑,与一般的远程连接相似,只不过流量是走的反代而已。
这例子的情景需要在控制的那台电脑上运行v2ray,对应的config.json
:
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
| { "reverse": { "bridges": [ { "tag": "remote_desktop_bridge_01", "domain": "rd-bridge-01.zhouxuebin.club" } ] }, "outbounds": [ { "tag": "tunnel", "protocol": "vmess", "settings": { "domainStrategy": "UseIPv4", "vnext": [ { "address": "xxx.xxx.xxx.xxx", "port": 2021, "users": [ { "id": "00112233-4455-6677-8899-aabbccddeeff", "alterId": 1, "security": "auto" } ] } ] }, "streamSettings": { "network": "tcp", "tcpSettings": {} } }, { "tag": "bridge_out", "protocol": "freedom", "settings": {} } ], "routing": { "rules": [ { "type": "field", "inboundTag": ["remote_desktop_bridge_01"], "domain": ["full:rd-bridge-01.zhouxuebin.club"], "outboundTag": "tunnel" }, { "type": "field", "inboundTag": ["remote_desktop_bridge_01"], "outboundTag": "bridge_out" } ] } }
|
bridges
的domain是随便取的,只要运行反代的服务器能够区分开就好,不需要真实存在。而outbounds
有两个,一个走的是本地协议的,也就是bridge_out
这台机子承载了两个方向的流量,一个是正向流量,另一个是反向流量,v2ray靠的是domain字段队两个方向的流量进行区分的。
正向流量是指:VPS主机(xxx.xxx.xxx.xxx:2021
) -> 反代机子(inbound tag:remote_desktop_bridge_01
)-> v2ray路由(outbound tag:bridge_out
) -> 本地协议(127.127.1.1:3389
)
反向流量是指:本地协议的响应数据 -> 反代机子(inbound tag:remote_desktop_bridge_01
,domain:rd-bridge-01.zhouxuebin.club
) -> v2ray路由(outbound tag:tunnel
) -> VPS主机
如果嘴瓢说反了,那也没关系,问题不大的。
VPS
VPS负责接受两个方向的连接,以及中转两个方向的流量,对应的config.json
:
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
| { "reverse": { "portals": [ { "tag": "remote_desktop_portal_01", "domain": "rd-bridge-01.zhouxuebin.club" } ] }, "log": { "loglevel": "warning" }, "inbounds": [ { "port": 2021, "listen": "0.0.0.0", "tag": "bridge_in", "protocol": "vmess", "settings": { "clients": [ { "id": "00112233-4455-6677-8899-aabbccddeeff", "level": 0, "alterId": 1, } ] }, "streamSettings": { "network": "tcp" } } ], "outbounds": [ { "protocol": "freedom", "settings": {}, "tag": "direct" }, { "protocol": "blackhole", "settings": {}, "tag": "blocked" } ], "routing": { "domainStrategy": "IPOnDemand", "rules": [ { "type": "field", "inboundTag": ["bridge_in"], "outboundTag": "remote_desktop_portal_01" } ] } }
|
VPS的工作其实也挺简单的,就一个inbound
负责监听和建立反代机子和访问反代的机子两者的连接,实现流量交换,甚至不需要outbound
。routing
就只要把inbound
流量转发到portal
就好了。这里重点放在reverse
设置上,portals
里面的domain
必须与反代主机上填的domain一致,无论这个domain是否实际存在。如果需要区分反代机子和访问反代机子的访问,可以在inbound
和routing
里面调整。
直接通过VPS的IP访问反代机子的远程桌面,在inbound
增加个任意门协议负责监听3389端口,把流量转发到portal就行了。这样访问反代(远程桌面)的机子可以直接通过VPS的IP或者域名进行连接,就不需要本地再跑v2ray了。例子见入门2,这个例子就直接在VPS监听。
访问反代的机子
本例子这里还需要在访问的机子上再运行一个v2ray,才能把数据发往VPS,config.json
如下:
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
| { "inbounds": [ { "protocol": "dokodemo-door", "listen": "127.127.1.1", "port": 3389, "settings": { "address": "127.127.1.1", "port": 3389, "protocol": "tcp" } } ], "outbounds": [ { "protocol": "vmess", "settings": { "domainStrategy": "UseIPv4", "vnext": [ { "address": "xxx.xxx.xxx.xxx", "port": 2021, "users": [ { "id": "00112233-4455-6677-8899-aabbccddeeff", "alterId": 1, "security": "auto" } ] } ] }, "streamSettings": { "network": "tcp" } } ] }
|
具体来说,就是负责把访问本地127.127.1.1:3389
(这里是listen
的IP)的流量封装到反代的机子上,按照反代机子的本地协议转发到127.127.1.1:3389
(这里是settings
里面的address
)。这样说可能比较抽象,用另外一个简单的例子说明:
1 2 3 4 5 6 7 8 9 10
| { "protocol": "dokodemo-door", "listen": "127.0.0.1", "port": 8088, "settings": { "address": "192.168.1.101", "port": 80, "protocol": "tcp" } }
|
这样你每次在本地访问127.0.0.1:8088
,实际上流量转发到反代机子后,反代机子通过本地的网络连接到192.168.1.101:80
,然后把结果再通过反代传回本地。
示意图
懒,有空再画
入门2:ssh反代
这个例子讲述了用任意门协议直接在VPS上监听反代连接,这样就不需要在访问反代的电脑上运行v2ray了。
注意:实际上这么做是非常危险的,直接把ssh访问暴露在公网非常容易收到攻击。假如该机子的root密码是简单的123456,那么其他人就可以轻易地登上服务器并运行rm -rf /。如果确定要这么做,建议把密码登录关了,只留密钥登录。
需要反代的服务器
需要通过反代建立ssh连接的服务器的配置:
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
| { "reverse": { "bridges": [ { "tag": "ssh_rev_br_01", "domain": "ssh-rev-01.zhouxuebin.club" } ] }, "log": { "access": "", "error": "", "loglevel": "warning" }, "inbounds": [ ], "outbounds": [ { "tag": "tunnel", "protocol": "vmess", "settings": { "domainStrategy": "UseIPv4", "vnext": [ { "address": "xxx.xxx.xxx.xxx", "port": 2021, "users": [ { "id": "00112233-4455-6677-8899-aabbccddeeff", "alterId": 1, "security": "auto" } ] } ] }, "streamSettings": { "network": "tcp" } }, { "tag": "direct", "protocol": "freedom", "settings": {} }, { "tag": "block", "protocol": "blackhole", "settings": {} } ], "routing": { "rules": [ { "type": "field", "inboundTag": ["ssh_rev_br_01"], "domain": ["ssh-rev-01.zhouxuebin.club"], "outboundTag": "tunnel" }, { "type": "field", "inboundTag": ["ssh_rev_br_01"], "outboundTag": "direct" } ] } }
|
跟入门1相同,一个bridge,两个outbound(direct和tunnel),两条routing规则。bridges的domain依然是不必存在的,outbound的address填的是自己VPS的IP或域名。
VPS
VPS上的配置文件:
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
| { "reverse": { "portals": [ { "tag": "ssh_rev_portal01", "domain": "ssh-rev-01.zhouxuebin.club" } ] }, "log": { "access": "", "error": "", "loglevel": "warning" }, "inbounds": [ { "port": 2021, "listen": "0.0.0.0", "tag": "bridge_in", "protocol": "vmess", "settings": { "clients": [ { "id": "00112233-4455-6677-8899-aabbccddeeff", "alterId": 1, "level": 0, "email": "ssh01@user.com" } ] }, "streamSettings": { "network": "tcp" } }, { "protocol": "dokodemo-door", "tag": "ssh_in", "listen": "0.0.0.0", "port": 4001, "settings": { "address": "127.0.0.1", "port": 22, "protocol": "tcp" } } ], "outbounds": [], "routing": { "rules": [ { "type": "field", "inboundTag": ["bridge_in"], "outboundTag": "ssh_rev_portal01" }, { "type": "field", "inboundTag": ["ssh_in"], "outboundTag": "ssh_rev_portal01" } ] } }
|
使用方式:ssh username@vps.domain -p 4001
,这样就相当于在反代的机子上运行ssh username@127.0.0.1 -p 22
。
进阶:代理与反代流量的混合
这里就放出inbounds
和routing
就算了,其他大同小异。代理和反代的流量跑的是本地的websocket,通过apache加TLS层封装为wss再对外开放。为了不占用根路径,这里的path改成了/ray
,也就是伪装成wss://xxxx/ray
协议,这么麻烦还是因为apache同时承担着网页服务器部分的流量……
inbounds
:这里的client_traffic_mix
同时承载了反向代理和普通代理的流量。
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
| { "inbounds": [ { "tag": "client_traffic_mix", "listen": "127.0.0.1", "port": 2019, "protocol": "vmess", "settings": { "clients": [ { "id": "00112233-4455-6677-8899-aabbccddeeff", "alterId": 1, "level": 0, "email": "whatever@it.is" } ] }, "streamSettings": { "network": "ws", "wsSettings": { "path": "/ray" } }, "sniffing": { "enabled": "true", "destOverride": [ "http", "tls" ] } } ] }
|
自己的id和alterId就填clients
里面。
routing
:负责区分两个代理的流量,说实话好像也没什么比较好的解决方案。现在采用的是分IP的方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| { "routing": { "domainStrategy": "IPOnDemand", "rules": [ { "type": "field", "inboundTag": ["client_traffic_mix"], "ip": [ "127.127.1.1" ], "outboundTag": "remote_desktop_portal_01" }, { "type": "field", "inboundTag": ["client_traffic_mix"], "outboundTag": "direct" } ] } }
|
这里根据访问的IP进行流量区分,也就是说访问127.127.1.1
的流量转发到反代的tag,从反代的机子出,其他流量都直接从VPS出。
还有一种是分用户的方案,其实也大同小异,routing
部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| { "routing": { "domainStrategy": "IPOnDemand", "rules": [ { "type": "field", "user": ["whatever@it.is"], "outboundTag": "remote_desktop_portal_01" }, { "type": "field", "inboundTag": ["client_traffic_mix"], "outboundTag": "direct" } ] } }
|
这样就直接把email
为whatever@it.is
用户的所有流量转发到反代的portal了,其他的就直接走outbound tag为direct的代理流量。
附一个apache2转发外部wss/https到本地ws/http流量:
1 2 3 4 5 6 7 8 9 10 11
| <IfModule mod_ssl.c> <VirtualHost _default_:443> # ...... RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /ray(.*) ws://localhost:2019/ray$1 [P,L] SSLProxyEngine On ProxyPass /ray http://localhost:2019 ProxyPassReverse /ray http://localhost:2019 </VirtualHost> </IfModule>
|