记一次内网搭建过程
3月份的时候大家都居家办公,开发的过程中后端和前端开发联调,每次后端修改接口都要重新发一次服务器上的代码,前后端都在抱怨这么做浪费时间。
- 我们知道我们的个人ip都是都是非公网ip,一般来说外人访问不到我们家中的电脑,那么有没有办法可以让在家办公的前端调用到在家办公的后端的接口呢?
- 答案是内网穿透。简单来说需要一台服务器,服务器上运行一个代理软件,后端小伙伴也要运行同样的代理软件,代理软件建立链接,服务器将某个端口和某个后端小伙伴做映射。这样前端小伙伴访问服务器上某个端口时,实际访问的是后端小伙伴的电脑上的服务。
1. 技术选型(选哪个代理软件)
- 这样的代理软件有很多,大可不必纠结,选择自己熟悉的就可以了。
我选择了v2ray这款代理软件,V2Ray 是一个与Shadowsocks 类似的代理软件,可以用来科学上网(翻墙)学习,V2RayW,V2RayN,Qv2ray 等开箱即用的科学上网软件都是使用v2ray为核心。
v2ray文档全面丰富,可以参照官网的配置来实现我们的需求。
2.实现过程
实际上算是一个反向代理
- 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP,无法在公网上直接访问。另有一台主机 B,它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
- 在主机 A 中配置一个 V2Ray,称为bridge,在 B 中也配置一个 V2Ray,称为portal。
- bridge会向portal主动建立连接,此连接的目标地址可以自行设定。portal会收到两种连接,一是由bridge发来的连接,二是公网用户发来的连接。portal会自动将两类连接合并。于是bridge就可以收到公网流量了。
- bridge在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
bridge会根据流量的大小进行动态的负载均衡。
对应我们的图示,前端就是访问者。服务器就是portal,后端的机器是bridge。
- 对于服务端上的而v2ray配置可以采用如下内容。
reverse: 配置项为配置反向代理所用。
server.json
{
"reverse":{
"portals":[
{
"tag":"portal", //portal的标识。在路由中使用outboundTag将流量转发到这个portal。
"domain":"www.ytty.xyz" //一个域名。当portal接收到流量时,如果流量的目标域名是此域名,则portal认为当前连接上bridge发来的通信连接。而其它流量则会被当成需要转发的流量。portal所做的工作就是把这两类连接进行识别并拼接。
}
]
},
"inbounds": [
{
"tag":"zcc-mobile", //随意 这两个端口17050 17052 对应着后台开发的7050,7052端口,而这两个端口是后台开发的api端口。
"port":17052,
"protocol":"dokodemo-door",
"settings":{
"address":"127.0.0.1", // 后台开发机上的服务地址和端口
"port":7052,
"network":"tcp"
}
},
{
"tag": "tunnel",
"port":16823, //用于接收 bridge 的连接
"protocol":"vmess",
"settings":{
"clients":[
{
"id":"b831381d-6324-4d53-ad4f-8cda48b30811", //id要和开发机上一致
"alterId":64
}
]
}
}
],
"routing":{
"rules":[
{
"type":"field",
"inboundTag":[
"zcc-mobile" //表示从这两个端口进来的流量 会转发到连接的开发机上
],
"outboundTag":"portal"
},
{
"type":"field",
"inboundTag":[
"tunnel" //对于来自 16823即bridge连接的流量 转发到www.ytty.xyz---后端开发机上。
],
"outboundTag":"portal"
}
]
}
}
- 客户端配置如下
client.json{ "reverse":{ "bridges":[ { "tag":"bridge", //一个标识,所有由bridge发出的连接,都会带有这个标识。可以在路由中使用inboundTag进行识别。 "domain":"www.ytty.xyz"//一个域名。bridge向portal建立的连接,都会使用这个域名进行发送。这个域名只作为bridge和portal的通信用途,不必真实存在。 可以随意配置 } ] }, "outbounds": [ { "tag": "bridgeout", "protocol": "freedom" }, { "tag":"zcc-mobile-server", "protocol":"vmess", "settings":{ "vnext":[ // vnext 表示要建立链接的服务器配置 { "address":"123.45.67.89", //服务器地址 "port":16823, //服务器和bridges通信的端口 "users":[ { "id":"b831381d-6324-4d53-ad4f-8cda48b30811", "alterId":64 } ] } ] } } ], "routing":{ "rules":[ { "type":"field", "inboundTag":[ "bridge" // 对于标识主机为www.ytty.xyz 发送到7050端口 ], "domain":[ "full:www.ytty.xyz" ], "outboundTag":"zcc-mobile-server" // }, { "type":"field", "inboundTag":[ "bridge" //对于发来的流量其他流量 不做任何代理 ], "outboundTag":"bridgeout" } ] } }
对于v2ray中有些概念如outbounds,inbounads可能需要看一下v2ray的文档,了解v2ray的工作原理才能理解的清楚。
上面的图画得有些简陋,详细一点流程画法应该如下。
- 启动服务器和后端开发机器上的v2ray,通过服务器上的16823端口建立链接。(开发机上可能不是16823)
- 前端访问123.45.67.89:17050端口,v服务器上2ray检测到。通过已建立的链接(16823)将这测请求发送到开发机上。
- 开发机收到请求,解析可得此次请求要发送到本机上的7050端口,于是发送。
- 7050返回,将信息路由到已链接的(16823)返回给服务器。
- 服务器返回给前端
要运行
客户端执行
./v2ray --config=./client.json
服务端运行
./v2ray --config=./server.json
然后发现访问服务器上的17050端口是访问的自己机器上启动的7050端口。
3. 增加用户和端口
这样的配置只能满足一位后台开发的需求,如果团队内的其他后台开发也有这样的需求呢?如果一个开发需要穿透自己机器上多个端口呢?
- 其实修改配置文件就可以解决了,
对于新增一个后台开发,配置文件修改的必要项如下
- bridges 修改domain
- outbounds 修改vnext中的地址和端口,user id.
- routing中的相关配置项 domain,togs
例如:上面的client.json文件可以修改为如下
client-2.json
{
"reverse":{
"bridges":[
{
"tag":"bridge",
"domain":"www.ytty.xyz1" // 修改1
}
]
},
"outbounds": [
{
"tag": "bridgeout",
"protocol": "freedom"
},
{
"tag":"zcc-mobile-server",
"protocol":"vmess",
"settings":{
"vnext":[ // vnext 表示要建立链接的服务器配置
{
"address":"123.45.67.89", //服务器地址
"port":16824, //修改2
"users":[
{
"id":"b831381d-6324-4d53-ad4f-8cda48b30812", //修改3
"alterId":64
}
]
}
]
}
}
],
"routing":{
"rules":[
{
"type":"field",
"inboundTag":[
"bridge" //
],
"domain":[
"full:www.ytty.xyz1" //修改4
],
"outboundTag":"zcc-mobile-server"
},
{
"type":"field",
"inboundTag":[
"bridge"
],
"outboundTag":"bridgeout"
}
]
}
}
当新增一个后台开发时,服务端文件也要修改。
增加如下项
- 新增portals
- 新增inbounds项目,用于外部流量端口,修改见下。
- 在新增一个inbounds,用于链接新增的开发人员机器 见下,tag==tunnel1
- 新增routing roules 见下
server.json
{
"reverse":{
"portals":[
{
"tag":"portal", //portal的标识。在路由中使用outboundTag将流量转发到这个portal。
"domain":"www.ytty.xyz" //一个域名。当portal接收到流量时,如果流量的目标域名是此域名,则portal认为当前连接上bridge发来的通信连接。而其它流量则会被当成需要转发的流量。portal所做的工作就是把这两类连接进行识别并拼接。
},
{
"tag":"portal1",
"domain":"www.ytty.xyz1"
}
]
},
"inbounds": [
{
"tag":"zcc-mobile", //随意 这两个端口17050 17052 对应着后台开发的7050,7052端口,而这两个端口是后台开发的api端口。
"port":17052,
"protocol":"dokodemo-door",
"settings":{
"address":"127.0.0.1", // 后台开发机上的服务地址和端口
"port":7052,
"network":"tcp"
}
},
//开发增加端口
{
"tag":"zcc-admin",
"port":17050,
"protocol":"dokodemo-door",
"settings":{
"address":"127.0.0.1",
"port":7050,
"network":"tcp"
}
},
{
"tag":"lx-mobile", //修改
"port":27052, //修改
"protocol":"dokodemo-door",
"settings":{
"address":"127.0.0.1", // 后台开发机上的服务地址和端口
"port":7052,
"network":"tcp"
}
}, //新增
{
"tag": "tunnel",
"port":16823, //用于接收 bridge 的连接
"protocol":"vmess",
"settings":{
"clients":[
{
"id":"b831381d-6324-4d53-ad4f-8cda48b30811", //id要和开发机上一致
"alterId":64
}
]
}
},
{
"tag": "tunnel1", //修改
"port":16824, //修改
"protocol":"vmess",
"settings":{
"clients":[
{
"id":"b831381d-6324-4d53-ad4f-8cda48b30812", //id要和开发机上一致 //修改
"alterId":64
}
]
}
} //新增
],
"routing":{
"rules":[
{
"type":"field",
"inboundTag":[
"zcc-mobile", //表示从这两个端口进来的流量 会转发到连接的开发机上
"zcc-admin"
],
"outboundTag":"portal"
},
{
"type":"field",
"inboundTag":[
"lx-mobile" //修改
],
"outboundTag":"portal1" //修改
},//新增
{
"type":"field",
"inboundTag":[
"tunnel"
],
"outboundTag":"portal"
} ,
{
"type":"field",
"inboundTag":[
"tunnel1" //修改
],
"outboundTag":"portal1" //修改
} //新增
]
}
}
对于上面的配置文件,当一个开发人员想要增加一个端口时,服务端增加一个inbounds,并配置路由即可。
当然服务器上要开启外部访问的端口17050,17052等。
小结
使用以上配置文件可以快速搭建内网穿透,而不必理解v2ray
v2ray的功能很强大,想要理解配置文件中的作用,和其他更强大的功能可以访问v2ray的官网查看学习。