SOCKS5实现代理服务器(C++)

代理服务器的简介

  • 就拿翻墙作为一个例子,当我们搜索谷歌的时候,我们中国的墙(在此称为墙)检测到我们发出的请求中有google的字眼,它会直接给我一个错误请求或者干脆返回给我们一个错误的网站
  • 我们中国的墙实际上并不是把国外所有的网站都封锁了,而是把那些富有交流性的东西封锁,比如facebook

回到重点:

假设需要访问facebook,做一个翻墙服务器,首先我们要有一个能够访问facebook的服务器A,同时我们自己的电脑也可以开始访问服务器A,通过服务器A,帮助我们访问facebook,然后把访问内容返回给我们。

  • 当我们在浏览器输入网址并按下确认键后,浏览器把数据封装成socks5的格式,然后发送给服务器A
  • 服务器A得到数据后,将收到的数据进行解析,判断socks5格式是否合法,并返回一个应答信号,这个过程服务器A实际上在模拟socks5的通信格式
  • 服务器A成功与浏览器端口身份验证完成后,服务器A再解析出浏览器发过来的url信息,通过url信息再与对应的服务器建立连接
  • 建立连接后,浏览器发过来的消息,服务器A就转发给facebook的服务器端,facebook服务器接收到请求,然后返回响应给服务器A,服务器A再把响应的结果转发给浏览器。如此就实现了请求和响应的过程。

我们需要借助的SOCKS协议

SOCKS简单介绍

  • SOCKS是一种网络传输协议,主要用于客户端与外网服务器之间的通讯的中间传递。SOCKS是 "SOCKETS"的缩写
  • 目前最新的版本是socks5
  • 版本4和5的区别在于5增加支持UDP,验证,以及IPv6,根据OSI模型,SOCKS是会话层的协议,位于表示曾和传输层之间
  • 想要模拟socks的与浏览器进行通信,我们必须要了解SOCKS的允许机制

SOCKS运作过程

第一步:身份验证(authentication)

1.客户端连接到服务器,并发送一个版本标识符/方法选择消息

  • 格式如下

image

2.服务器从方法中给定的方法中选择一个方法,METHOD设置0x00
返回给客户端表示不需要身份验证,返回0xff的时候,客户端必须关闭这个连接
这里我们直接返回0x00即可,因为我们是测试,不需要这么复杂

image

第二步:SOCKS请求 (客户端–>代理服务器)

  • 也就是代理服务器拿着客户端发过来的网址去访问网站

SOCKS的请求格式

image

  • VER 版本
  • CMD
    • 0x01 代表连接
    • 0x02 代表绑定
    • 0x03
  • RSV 保留的一个字节
  • ATYP 表示使用后面的(目标服务器的地址)DST.ADDR是什么类型
    • 0x01 IPV4的IP
    • 0x03 表示是一个域名
    • 0x04 IPv6的IP
  • DST,ADDR 目标IP或者域名 (长度根据类型而定)
  • DST.PORT 目标服务器的端口号

第三步:响应 (代理服务器–>客户端)

  • 也就是代理服务器拿着网址访问网址对应的服务器后,得到响应,然后把这个响应再转发给客户端(浏览器)

请求格式

SOCKS请求信息由客户端在发送完之后立即发送
建立到SOCKS服务器的连接,并完成
身份验证的谈判。服务器评估请求,并且
返回如下形式的回复:

image

  • VER 版本号
  • REP 回复字段
    • 0x00 成功了
    • 0x01 不通SOCKS服务器故障
    • 0x02 连接不被规则集允许
    • 0x03 网络无法连接
    • 0x04 主机无法连接
    • 0x05 连接被拒绝
    • 0x06 TTL过期
    • 0x07 命令不支持
    • 0x08 地址类型不支持
    • 0x09和0xff还没有被分配
  • RSV 保留字节
  • ATYP 后面的地址类型
    • 0x01 IPV4的IP
    • 0x03 表示是一个域名
    • 0x04 IPv6的IP
  • BND.ADDR 服务器绑定的地址
  • BND.PORT 服务器绑定的端口号

SOCKS5资料参考网址

https://www.ietf.org/rfc/rfc1928.txt

如何使用SOCKS5进行IP代理

  • 首先我们要明白,如果我们直接访问国外的目标服务器,我们的输入的网址将会被GFW拦截(GFW是中国防火墙),之所以我们不能访问外网,就是因为有GFW,就比如我们上不了谷歌的首页,因为我们的请求中有关于谷歌的字眼,被GFW识别后就会直接丢弃或者返回一个错误的网页给我们
  • 其次,我们也必须知道并不是所有国外的网站我们都访问不了,有些网站还是允许访问了。

现在说说原理

  • 一般情况下,从浏览器输入网址后,浏览器经过域名解析,得到网址对应的IP和端口号,然后向目标服务器发送请求,这个过程中都是明文传输,传输的内容中肯定有关于目标服务器的信息,如果目标服务器是不允许访问的,我们就会被拦截。
  • 所以我们可以把请求先发送给一个国外允许我们访问的服务器==,让国外的服务器帮助我们访问目标服务器==,然后把访问的结果返回给我们,这个过程中的数据一定要加密
  • 一定要加密,一定要加密,那怎么加密呢?

1.我们输入网址后我们让浏览器SOCKS5协议向我们的本地自己搭建的SOCKS5服务器发送SOCKS5数据包

2.SOCKS5的数据包中包含了,浏览器要访问的目标服务器的域名或者IP信息

3.我们本地的SOCKS5服务器对这数据进行加密,因为要发送给到国外的服务器,所以要加密处理,防止被解析出来,然后导致被拦截掉。

4。本地的SOCKS5服务器加密数据后,转发给国外的SOCKS5服务器

5.国外的SOCKS5解密数据包,然后从SOCKS5数据包中提取出目标服务器的域名或者是IP,还有端口号

6.国外的SOCKS5服务器帮助我们访问目标服务器,然后得到目标服务器的响应

7.国外的SOCKS5服务器对响应进行加密处理,然后发送给我们本地的SOCKS5服务器

8.本地的服务器对响应进行解密,把解密后的响应发给浏览器

9.浏览器得到响应,解析页面

原理图

在这里插入图片描述

小结

  • 在讲述原理的过程中,整个执行过程如上图
  • 两个服务器可以分开来写,先写处理SOCKS请求的国外的服务器
  • 本地的SOCKS5服务器只是对数据包进行了转发
  • 解析数据包的时候可以使用抓包工具帮助测试
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章