首页 > 其他分享 >43 干货系列从零用Rust编写负载均衡及代理,内网穿透方案完整部署

43 干货系列从零用Rust编写负载均衡及代理,内网穿透方案完整部署

时间:2024-01-22 13:44:08浏览次数:29  
标签:http 零用 0.0 43 server 服务端 docker Rust wmproxy

wmproxy

wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代理等,会将实现过程分享出来,感兴趣的可以一起造个轮子

项目地址

国内: https://gitee.com/tickbh/wmproxy

github: https://github.com/tickbh/wmproxy

设计目标

部署软件,实现内网穿透功能。

配置文件准备

服务端的配置文件mapping_server.toml

default_level = "trace"
[proxy]
#绑定的ip地址
bind_addr = "0.0.0.0:8091"

username = "wmproxy"
password = "wmproxy"

#内网映射http绑定地址
map_http_bind = "0.0.0.0:8001"
#内网映射tcp绑定地址
map_tcp_bind = "0.0.0.0:8002"
#内网映射https绑定地址
map_https_bind = "0.0.0.0:8003"
#内网映射的公钥证书,为空则是默认证书
# map_cert = 
#内网映射的私钥证书,为空则是默认证书
# map_key =
# 双向认证
# two_way_tls = true
# #接收客户端是为是加密客户端
# tc = true
#当前服务模式,server为服务端,client为客户端
mode = "server"

客户端的配置文件mapping_client.toml,需注意填上正确的服务端地址。此处服务端地址填的是docker的名字,非docker启动换成相应的ip

control = "0.0.0.0:8838"

[proxy]
# 连接服务端地址
server = "wmproxy_server_docker:8091"
bind_addr = "0.0.0.0:8090"
flag = "http https socks5"
# 连接服务端是否加密
# ts = true
# two_way_tls = true
username = "wmproxy"
password = "wmproxy"

# 内网映射配置的数组

  #将localhost的域名转发到本地的0.0.0.0:8080
[[proxy.mappings]]
name = "web"
mode = "http"
local_addr = "192.168.17.22:8080"
domain = "localhost"

headers = [
  "proxy x-forward-for {client_ip}",
  "proxy + from $url",
  "+ last-modified 'from proxy'",
  "- etag",
]

#将tcp的流量无条件转到0.0.0.0:8080
[[proxy.mappings]]
name = "tcp"
mode = "tcp"
local_addr = "192.168.17.22:8080"
domain = ""

安装

docker

安装方法docker,注意在docker里配置文件的监听地址需改成0.0.0.0,否则无法映射到宿主机。当前将两个docker配置到相同的network环境中,是为了互通,如果分别部署到不同的网络环境可以删除掉。

docker pull dreamwhat/wmproxy

配置服务端docker-compose.yaml

version: '3.5'
services:

  wmproxy_server:
    container_name: wmproxy_server_docker        # 指定容器的名称
    image: dreamwhat/wmproxy:0.2.4
    command:
      - sh
      - -c
      - |
        wmproxy run -c /etc/config/mapping_server.toml
    ports:
      - "127.0.0.1:8837:8837"
      - "8091:8091"
      - "8001:8001"  #http映射
      - "8002:8002"  #tcp映射
      - "8003:8003"  #https映射
    volumes:
      - ./mapping_server.toml/:/etc/config/mapping_server.toml:r

networks:
  default:
    name: wmproxy-network

通过docker-compose进行启动。

docker-compose up

有显示如下信息表明已开始监听请求:如果需要后台加上docker-compose up -d即可。

wmproxy_server_docker  | 2024-01-15T06:13:22.790886788+00:00 INFO wmproxy::option - 绑定代理:0.0.0.0:8091,提供代理功能。
wmproxy_server_docker  | 2024-01-15T06:13:22.790919459+00:00 INFO wmproxy::option - 内网穿透,http绑定:0.0.0.0:8001,提供http内网功能。
wmproxy_server_docker  | 2024-01-15T06:13:22.790960305+00:00 INFO wmproxy::option - 内网穿透,https绑定:0.0.0.0:8003,提供https内网功能。
wmproxy_server_docker  | 2024-01-15T06:13:22.791089397+00:00 INFO wmproxy::option - 内网穿透,tcp 绑定:0.0.0.0:8002,提供tcp内网功能。

配置客户端docker-compose.yaml,因为本机IP为192.168.17.22,此处做个8080的服务器做响应

version: '3.5'
services:

  wmproxy_client:
    container_name: wmproxy_client_docker        # 指定容器的名称
    image: dreamwhat/wmproxy:0.2.4
    # image: wmproxy
    command:
      - sh
      - -c
      - |
        wmproxy run -c /etc/config/mapping_client.toml
    ports:
      - "127.0.0.1:8838:8838"
      - "8090:8090"
    volumes:
      - ./mapping_client.toml/:/etc/config/mapping_client.toml:r

networks:
  default:
    name: wmproxy-network

启动方式同上,服务端看到如下输出则表示正常:

wmproxy_server_docker  | 2024-01-15T06:15:47.988802113+00:00 TRACE wmproxy::wmcore - 代理收到客户 端连接: 172.25.0.3:57214->0.0.0.0:8091

客户端同样会输出启动成功信息。

  • 客户端的代理信息会通过服务端进行代理处理。
  • 服务端的HTTP请求会转发到客户端进行处理。

客户端代理验证

客户端为8090处理代理端口,如果不需要可以不映射端口。
此时客户端的代理请求将会通过服务端进行转发,可以用这种方式访问到服务端内网的数据。以下通过代理访问www.baidu.com,因为用户密码均配置wmproxy,所以需要进行设置

curl.exe -x http://wmproxy:[email protected]:8090 http://www.baidu.com
curl.exe -x socks5://wmproxy:[email protected]:8090 http://www.baidu.com

此时服务端的docker上可以看到如下输出:

wmproxy_server_docker  | 2024-01-15T06:23:36.796799098+00:00 TRACE wmproxy::check::health - connect addr = 183.2.172.185:80
wmproxy_server_docker  | 2024-01-15T06:23:36.798174881+00:00 TRACE wmproxy::check::health - success connect addr = 183.2.172.185:80

通过ping www.baidu.com可以知道,此时服务端发起了www.baidu.com的连接。

PS C:\Users\PC> ping www.baidu.com

Pinging www.a.shifen.com [183.2.172.42] with 32 bytes of data:
Reply from 183.2.172.42: bytes=32 time=24ms TTL=51

且通过curl的输出内容为正确返回

PS C:\Users\PC> curl.exe -x http://wmproxy:[email protected]:8090 http://www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> 
...

此时客户端通过服务端访问网络为通的。

内网穿透验证

此时我们启动本地监听的8080服务器。请求返回如下

PS C:\Users\PC> curl http://127.0.0.1:8080


StatusCode        : 200
StatusDescription : OK
Content           : {72, 101, 108, 108...}
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 13
                    Server: wenmeng

                    Hello World

Headers           : {[Content-Length, 13], [Server, wenmeng]}
RawContentLength  : 13

测试8001的内网穿透,当前我们绑定地址为localhost,因为我们在客户端的配置里进行了如下配置:

[[proxy.mappings]]
name = "web"
mode = "http"
local_addr = "192.168.17.22:8080"
domain = "localhost"
  • 我们尝试用ip进行访问,告诉我们无法访问,正确预期。
PS C:\Users\PC> curl.exe http://127.0.0.1:8001/
not found
  • 我们用localhost的网址进行访问,返回预期的结果,且加上了带回来的Last-Modified,此时该途径测试通过。
PS C:\Users\PC> curl http://localhost:8001


StatusCode        : 200
StatusDescription : OK
Content           : {72, 101, 108, 108...}
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 13
                    Last-Modified: from proxy
                    Server: wmproxy

                    Hello World

Headers           : {[Content-Length, 13], [Last-Modified, from proxy], [Server, wmproxy]}
RawContentLength  : 13

但是通过8002因为是tcp转发的,此时无论是127.0.0.1或者为localhost将同样的进行处理。此时得到的结果均和正常访问8080一模一样的进行返回。

PS C:\Users\PC> curl http://127.0.0.1:8002


StatusCode        : 200
StatusDescription : OK
Content           : {72, 101, 108, 108...}
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 13
                    Server: wenmeng

                    Hello World

Headers           : {[Content-Length, 13], [Server, wenmeng]}
RawContentLength  : 13

二进制文件部署

通过从https://github.com/tickbh/wmproxy/tags下载相应平台的二进制文件启动,此处用windows的表示即重命名成wmproxy.exe
服务端启动

wmproxy -c mapping_server.toml

客户端启动,其中连接的目标ip需进行修改

wmproxy -c mapping_client.toml

我们将会得到相同的体验。

小结

此章中讲述了内网穿透如何部署及客户端访问到服务端内网的资源,这两种场景中相对常见,通过客户端与服务端的加密通讯,网络传中的被嗅探的可能将进一步减少。

点击 [关注][在看][点赞] 是对作者最大的支持

标签:http,零用,0.0,43,server,服务端,docker,Rust,wmproxy
From: https://www.cnblogs.com/wmproxy/p/17979874/wmproxy43

相关文章

  • socketioxide 基于rust 的socket.io server 实现
    socketioxide是基于rust的socket.ioserver实现包含的特性类似axum的API完全兼容官方socket.ioclient支持v4协议状态管理namespacesrooms消息确认polling以及websocket支持说明目前socketioxide实际上也支持adapter,支持是本地的,缺少集群模式的支持,比如nodej......
  • Go语言核心36讲 43 | bufio包中的数据类型(下)
    你好,我是郝林,我今天继续分享bufio包中的数据类型。在上一篇文章中,我提到了bufio包中的数据类型主要有Reader、Scanner、Writer和ReadWriter。并着重讲到了bufio.Reader类型与bufio.Writer类型,今天,我们继续专注bufio.Reader的内容来进行学习。知识扩展问题:bufio.Reader类型读......
  • ATF(Arm Trusted Firmware)
    ATF(ArmTrustedFirmware)是一个为ARMv8-A架构SoC提供的安全固件,其包含了多个组件和功能来确保系统的安全启动和运行时环境。以下是ATF中的一些主要功能和组件:1.**BL1(BootLoaderStage1)**:-这是ATF的第一阶段引导加载程序。-负责从非易失性存储器(如eMMC、UFS、NAND等)中......
  • 洛谷 P9843 [ICPC2021 Nanjing R] Paimon Sorting 题解
    Descirption给出一个排序算法(用伪代码表示):SORT(A)forifrom1tonforjfrom1tonifa[i]<a[j]Swapa[i]anda[j]算出对于一个序列\(A=a_1,a_2,\cdots,a_n\)的所有前缀\(A_k=a_1,a_2,\cdots,a_k\)(\(1\lek\len\)),\(\operatorname{SORT}(A_......
  • 安装Rust环境_基于Windows
    下载rustuprustup是Rust的安装程序,也是它的版本管理程序,因此安装好环境后慎重卸载。https://www.rust-lang.org/zh-CN/tools/install运行rustup-init.exe第一步选3回车,后续操作默认回车直至即为安装成功,cmd终端执行指令rustc-V成功显示Rust版本号......
  • LG8443
    JROI果然很良心,签到题终于可以用来签到了。这道题一看数据范围$1\lel\ler\le10^{18}$,就能知道肯定是数学题。遇到数学题不用急,我们一步步分析。回忆小学学习的关于互质的一条性质:相邻的两个正整数互质。形式化地说,若\(a\)和\(b\)为两个相邻的正整数,则\(\gcd(a,b)=......
  • Rust 所有权和 Move 语义
    Rust所有权和Move语义所有权和生命周期是Rust和其它编程语言的主要区别,也是Rust其它知识点的基础。动态数组因为大小在编译期无法确定,所以放在堆上,并且在栈上有一个包含了长度和容量的胖指针指向堆上的内存。恰到好处的限制,反而会释放无穷的创意和生产力。Rust所有权......
  • P4345 [SHOI2015] 超能粒子炮·改 题解
    P4345[SHOI2015]超能粒子炮·改题解求\[\sum_{i=0}^k\binom{n}{i}\pmod{2333}\]思路这种模数小的组合数计数问题可以考虑Lucas定理,试试呗。如果按余数分类不好优化,可以按商分类求和,这样一来套个前缀和可以得到一个递推式,注意最后一块商可能是不整的,单独拿出来即可。......
  • Rust 错误处理
    目录用panic!处理不可恢复的错误对应panic时的栈展开或终止使用panic!的backtraceWindows设置RUST_BACKTRACE环境变量的两种方式用Result处理可恢复的错误匹配不同的错误不同于使用match和Result<T,E>失败时panic的简写:unwrap和expect传播错误传播错误的简写:?......
  • Rust 常见集合
    目录使用Vector储存列表新建vectorVec::new函数(无初值)vec!宏(有初值)更新vector读取vector的元素注意可变和不可变引用遍历vector中的元素使用枚举来储存多种类型丢弃vector时也会丢弃其所有元素使用字符串储存UTF-8编码的文本什么是字符串?新建字符串更新字符串使......