大型企业网络拓扑图绵阳做最好优化网站的

当前位置: 首页 > news >正文

大型企业网络拓扑图,绵阳做最好优化网站的,棋牌 彩票网站建设,企业信息平台wmproxy wmproxy是由Rust编写#xff0c;已实现http/https代理#xff0c;socks5代理#xff0c; 反向代理#xff0c;静态文件服务器#xff0c;内网穿透#xff0c;配置热更新等#xff0c; 后续将实现websocket代理等#xff0c;同时会将实现过程分享出来#xff…wmproxy wmproxy是由Rust编写已实现http/https代理socks5代理 反向代理静态文件服务器内网穿透配置热更新等 后续将实现websocket代理等同时会将实现过程分享出来 感兴趣的可以一起造个轮子法 项目 wmproxy gite: https://gitee.com/tickbh/wmproxy github: https://github.com/tickbh/wmproxy 内网、公网 内网也叫做局域网通常指单一的网络环境。例如你家里的路由器网络、网吧、公司网络、学校网络。网络大小不定内网中的主机可以互联互通但是越出这个局域网访问就无法访问该网络中的主机。 公网就是互联网其实也可以看做一个扩大版的内网比如叫城际网省域网国网。有单独的公网IP任何其它地址可以访问网络的可以直接访问该IP从而实现服务。 为什么要内网穿透 内网限制 IP不固定通过家庭网手机4G/5G访问的出口地址都是动态的每次连接都会变化运营商通常会做NAT转化从而实际上你访问的出口地址其实也是一个内网地址如通常https://www.baidu.com/s?wdip查询地址常用端口无法使用如80/443这类标准端口被直接限制不能使用。 公网优缺点 服务器贵带宽贵IP固定所有端口均可开放带宽稳定基本上所有高防机房或者云厂商都能提供稳定的带宽 内网穿透的场景 场景1:开发人员本地调试接口 描述线上项目有问题或者有某些新功能必须进行Debug进行调试和测试。 特点本地调试、网速要求低、需要HTTP或者HTTPS协议。 需求必须本地必须HTTP[S]网址。 场景2公司或者家里的本地存储或者公司内部系统 描述如外出进行工作或者本地有大量的私有数据敏感不适合上云但是自己必须得进行访问如git服务或者照片服务等 特点需要远程能随时随地的访问访问内容不确定但是需要能提供 需求要相对比较稳定的线路但是带宽相对要求较低 场景3私有服务器和小伙伴开黑 描述把自己的电脑做服务器有时候云上的主机配置相对较高点的一个月费用极高所以需要本地做私有服务器或者把自己当做一台训练机 特点对稳定性要求不用太高的可以提供相应的服务 TCP内网穿透的原理 内网IP无法直接被访问所以此时需求 内网服务器公网服务器有公网IP 此时网络如下如此外部用户就能访问到内网服务器的数据此时内网穿透客户端及服务端是保持长连接以方便进行推送本质上是长链接在转发数据而实现穿透功能 #mermaid-svg-5RZHS3Ej6s0qVw7V {font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .error-icon{fill:#552222;}#mermaid-svg-5RZHS3Ej6s0qVw7V .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5RZHS3Ej6s0qVw7V .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .marker.cross{stroke:#333333;}#mermaid-svg-5RZHS3Ej6s0qVw7V svg{font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5RZHS3Ej6s0qVw7V .label{font-family:“trebuchet ms”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .cluster-label text{fill:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .cluster-label span{color:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .label text,#mermaid-svg-5RZHS3Ej6s0qVw7V span{fill:#333;color:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .node rect,#mermaid-svg-5RZHS3Ej6s0qVw7V .node circle,#mermaid-svg-5RZHS3Ej6s0qVw7V .node ellipse,#mermaid-svg-5RZHS3Ej6s0qVw7V .node polygon,#mermaid-svg-5RZHS3Ej6s0qVw7V .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5RZHS3Ej6s0qVw7V .node .label{text-align:center;}#mermaid-svg-5RZHS3Ej6s0qVw7V .node.clickable{cursor:pointer;}#mermaid-svg-5RZHS3Ej6s0qVw7V .arrowheadPath{fill:#333333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5RZHS3Ej6s0qVw7V .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-5RZHS3Ej6s0qVw7V .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-5RZHS3Ej6s0qVw7V .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5RZHS3Ej6s0qVw7V .cluster text{fill:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V .cluster span{color:#333;}#mermaid-svg-5RZHS3Ej6s0qVw7V div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:“trebuchet ms”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5RZHS3Ej6s0qVw7V :root{–mermaid-font-family:“trebuchet ms”,verdana,arial,sans-serif;} 由穿透客户端连接到内网服务器 建立连接/保持连接 访问建立连接 内网服务器 内网穿透客户端wmproxy 内网穿透服务端wmproxy 外网用户 Rust实现内网穿透 wmproxy一款简单易用的内网穿透工具简单示例如下 客户端相关 客户端配置client.yaml

连接服务端地址

server: 127.0.0.1:8091

连接服务端是否加密

ts: true# 内网映射配置的数组 mappings:#将localhost的域名转发到本地的127.0.0.1:8080- name: webmode: httplocal_addr: 127.0.0.1:8080domain: localhost#将tcp的流量无条件转到127.0.0.1:8080- name: tcpmode: tcplocal_addr: 127.0.0.1:8080domain: 启动客户端 wmproxy -c config/client.yaml服务端相关 服务端配置server.yaml #绑定的ip地址 bind_addr: 127.0.0.1:8091 #代理支持的功能1为http2为https4为socks5 flag: 7 #内网映射http绑定地址 map_http_bind: 127.0.0.1:8001 #内网映射tcp绑定地址 map_tcp_bind: 127.0.0.1:8002 #内网映射https绑定地址 map_https_bind: 127.0.0.1:8003 #内网映射的公钥证书为空则是默认证书 map_cert: #内网映射的私钥证书为空则是默认证书 map_key: #接收客户端是为是加密客户端 tc: true #当前服务模式server为服务端client为客户端 mode: server启动服务端 wmproxy -c config/server.yaml测试实现 在本地的8080端口上启动了一个简单的http文件服务器 http-server .http测试 此时8001的端口是http内网穿透通过服务端映射到客户端并指向到8080端口此时若访问http://127.0.0.1:8001则会显示 http映射是根据域名做映射此时我们的域名是127.0.0.1所以直接返回404无法访问 此时若访问http://localhost:8001结果如下 我们就可以判定我们的内网转发成功了。 tcp测试 tcp就是在该端口上的流量无条件转发到另一个端口上此时我们可以预测tcp映射与域名无关我们在8002上转发到了8080上此时我们访问http://127.0.0.1:8002和http://localhost:8002都可以得到一样的结果 此时tcp转发成功 源码实现 因为TLS连接与协议无关只要把普通的TCP转成TLS剩下的均和普通连接一样处理即可那么此时我们只需要处理TCP和HTTP的请求转发即可。 监听 在程序启动的时候看我们是否配置了相应的http/https/tcp的内网穿透转发如果有我们对相应的端口做监听此时如果我们是https转发要配置相应的证书将会对TcpStream升级为TlsStreamTcpStream let http_listener if let Some(ls) self.option.map_http_bind {Some(TcpListener::bind(ls).await?) } else {None }; let mut https_listener if let Some(ls) self.option.map_https_bind {Some(TcpListener::bind(ls).await?) } else {None };let map_accept if https_listener.is_some() {let map_accept self.option.get_map_tls_accept().await.ok();if map_accept.is_none() {let _ https_listener.take();}map_accept } else {None }; let tcp_listener if let Some(ls) self.option.map_tcp_bind {Some(TcpListener::bind(ls).await?) } else {None };转发相关代码主要在两个类里分别为trans/http.rs和trans/tcp.rs 在http里面需要预处理相关的头文件消息 X-Forwarded-For添加IP信息从而使内网可以知道访问的IP来源Host重写Host信息让内网端如果配置负载均衡可以正确的定位到位置Server重写Server信息让内网可以明确知道这个服务端的类型 http转发源码 以下为部分代码后续将进行比较正规的HTTP服务以适应HTTP2 pub async fn processT(self, mut inbound: T) - Result(), ProxyErrorT whereT: AsyncRead AsyncWrite Unpin, {let mut request;let host_name;let mut buffer BinaryMut::new();loop {// 省略读信息request webparse::Request::new();// 通过该方法解析标头是否合法, 若是partial(部分)则继续读数据// 若解析失败, 则表示非http协议能处理, 则抛出错误// 此处clone为浅拷贝不确定是否一定能解析成功不能影响偏移match request.parsebuffer(mut buffer.clone()) {Ok() match request.get_host() {Some(host) {host_name host;break;}None {if !request.is_partial() {Self::err_server_status(inbound, 503).await?;return Err(ProxyError::UnknownHost);}}},// 数据不完整还未解析完等待传输Err(WebError::Http(HttpError::Partial)) {continue;}Err(e) {Self::err_server_status(inbound, 503).await?;return Err(ProxyError::from(e));}}}// 取得相关的host数据对内网的映射端做匹配如果未匹配到返回错误表示不支持{let mut is_find false;let read self.mappings.read().await;for v in *read {if v.domain host_name {is_find true;}}if !is_find {Self::not_match_err_status(inbound, no found.to_string()).await?;return Ok(());}}// 有新的内网映射消息到达通知客户端建立对内网指向的连接进行双向绑定后续做正规的http服务以支持拓展let create ProtCreate::new(self.sock_map, Some(host_name));let (stream_sender, stream_receiver) channel::ProtFrame(10);let _ self.sender_work.send((create, stream_sender)).await;// 创建传输端进行绑定let mut trans TransStream::new(inbound, self.sock_map, self.sender, stream_receiver);trans.reader_mut().put_slice(buffer.chunk());trans.copy_wait().await?;// let _ copy_bidirectional(mut inbound, mut outbound).await?;Ok(()) }tcp转发源码 tcp处理相对比较简单因为我们无法确定协议里是哪个类型的源码所以对我们来说就是单纯的把接收的数据完全转发到新的端口里。以下是部分源码 pub async fn processT(self, inbound: T) - Result(), ProxyErrorT whereT: AsyncRead AsyncWrite Unpin, {// 寻找是否有匹配的tcp转发协议如果有则进行转发如果没有则丢弃数据{let mut is_find false;let read self.mappings.read().await;for v in *read {if v.mode tcp {is_find true;}}if !is_find {log::warn!(not found tcp client trans);return Ok(());}}// 通知客户端数据进行连接的建立客户端的tcp配置只能存在有且只有一个要不然无法确定转发源let create ProtCreate::new(self.sock_map, None);let (stream_sender, stream_receiver) channel::ProtFrame(10);let _ self.sender_work.send((create, stream_sender)).await;let trans TransStream::new(inbound, self.sock_map, self.sender, stream_receiver);trans.copy_wait().await?;Ok(()) }到此部分细节已基本调通后续将优化http的处理相关以方便支持http的头信息重写和tcp的错误信息将写入正确的日志以方便进行定位。