Go入门与Socks5的简要理解 | 青训营笔记

99 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

本堂课重点内容

  • 介绍了Golang的背景、特性和优势,以及当前Golang市场环境
  • 进行了Golang语法的初步入门
  • 通过循序渐进的三个实战样例进行从零到入门的训练

课堂零碎收获整理

  • Go的时间格式化必须使用2006-01-02 15:04:05,也就是06年1月2日下午3时4分5秒,可以发现每一个数字都对应不同的位置,根据参考文章的底层代码分析,每个数字对应了每个位置,让格式化更加的高效
  • 对于随机数,通常会在程序的开始置随机数种子,通常使用时间作为种子,也就是rand.Seed(time.Now().UnixNano())
  • 对于一个标准函数,应当有两个返回,一个返回代表返回的数据,可以是类型或自定义结构体,而另一个则是err,用于错误处理
  • 标准库的io.copy()可以实现一个单向数据转发,若要实现双向转发,需要启动两个goroutinue

SOCKS5

这部分是我不熟悉的地方,我会做相对多的笔记和一些参考

简介

根据维基介绍,SOCKS是一种互联网协议,为Socket Secure的缩写,主要用于客户端与外网服务器之间通讯的中间传递。

简单而言,他就是一种代理协议,扮演一个中间人,负责在客户端和目标主机之间转发数据。

SOCKS5由IETF在1996年正式发布,经过这么多年的发展,互联网上基本上都以SOCKS5为主,SOCKS4已经退出了历史的舞台。

特点

  • socks协议位于OSI模型中的第五层,也就是会话层(Session Layer)

  • socks5协议是明文传输,诞生于互联网早期

  • socks5相当于在防火墙开了一个口子,让授权的用户可以通过单端口访问内部的所有资源。

  • 网上的代理IP池很多代理的协议就是socks5

  • socks5不关心流量细节,可以是HTTP流量,也可以是其他TCP流量。

  • 相较于SOCKS4a,SOCKS5多了认证、IPv6、UDP支持。

  • SOCKS5不兼容SOCKS4协议,实际上,SOCKS5可以完全取代SOCKS4

原理

image-20230115112238136

正常访问网站流程

先与对方网站建立HTTP连接,然后三次握手,握手完成后发起HTTP请求,后服务返回HTTP响应。

含代理的访问流程

可以分为四个阶段:握手、认证、请求、relay

  • 握手:浏览器向socks5代理发送请求,包的内容包括一个协议的版本号以及支持的种类,socks5服务器会选中一个认证方式,返回给浏览器。
  • 认证:这部分会与服务器进行认证,只有认证通过后才会进行下一步,否则连接失败
  • 请求:浏览器会向socks5服务器发起请求,主要信息包括版本号、请求类型,一般主要是connection请求,就代表代理服务器要和某个域名或者某个IP地址的某个端口建立TCP连接。代理服务器收到响应后,会真正和后端服务器建立连接,然后返回一个响应。
  • relay:socks5服务器收到请求后,解析内容。如果是UDP请求,服务器直接转发; 如果是TCP请求,服务器向目标服务器建立TCP连接,后续负责把客户端的所有数据转发到目标服务

SOCKS5认证格式

SOCKS5协议是支持认证的,也就是说在TCP三次握手后,要和服务器进行认证,格式如下(以字节为单位):

+----+----------+----------+
|VER | NMETHODS | METHODS  |
+----+----------+----------+
| 1  |    1     | 1 to 255 |
+----+----------+----------+
  • VER: 当前版本号
  • NMETHODS: 客户端支持的认证方式的个数
  • METHODS: 客户端支持的认证方式

服务器在客户端发送的认证方式中选择一种进行匹配,会返回如下内容:

+----+----------+
|VER |  METHODS |
+----+----------+
| 1  |    1     |
+----+----------+
  • VER: 同上
  • METHOD: 服务器端匹配的结果

认证方式有如下几种

  • 0x00: 无验证需求
  • 0x01: GSSAPI,通用安全服务应用程序接口
  • 0x02: USERNAME&PASSWORD,用户名密码验证
  • 0x03 - 0x07: IANA ASSIGNED,IANA分配
  • 0x80 - 0xfe: RESERVED FOR PRIVATE METHODS,私人方法保留
  • 0xff: NO ACCEPTABLE METHODS,无可接受方法

如果服务器返回是0xff,则表明服务端不支持客户端所有的认证方式,也就是认证失败。

而如果你不需要认证,则直接发送0x00即可

SOCKS5请求格式

客户端发送的请求格式

+----+-----+-------+------+----------+----------+
|VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | X'00' |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • VER: 当前版本号
  • CMD: SOCKS命令码
  • RSV: 0x00,保留
  • ATYP: DST.ADDR类型
  • DST.ADDR: 目的地址
  • DST.PORT: 目标端口,固定2个字节

对于CMD,命令码有如下:

  • 0x01: CONNECT请求
  • 0x02: BIND请求
  • 0x03: UDP转发

对于ATYP,有如下类型:

  • 0x01: IPv4地址,DST.ADDR部分4字节长度
  • 0x03: 域名,DST.ADDR部分第一个字节为域名长度,DST.ADDR剩余的内容为域名,没有\0结尾。
  • 0x04: IPv6地址,16个字节长度。

服务端发送的返回格式

+----+-----+-------+------+----------+----------+
|VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | X'00' |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • VER: 同上,SOCKS5都应该是0x05
  • REP: 应答字段
  • RSV: 保留字段
  • ATYP: BND.ADDR类型
  • BND.ADDR: 服务器绑定的地址
  • BND.PORT: 服务绑定的端口DST.PORT

对于REP应答字段,有如下内容:

  • 0x00: 成功
  • 0x01: 普通SOCKS服务器连接失败
  • 0x02: 现有规则不允许连接
  • 0x03: 网络不可达
  • 0x04: 主机不可达
  • 0x05: 连接被拒
  • 0x06: TTL超时
  • 0x07: 不支持的命令
  • 0x08: 不支持的地址类型
  • 0x09 - 0xff: 未定义

也就是说,除了0x00其他都是出现错误

对于ATYP,有如下类型:

  • 0x01: IPv4地址,DST.ADDR部分4字节长度
  • 0x03: 域名,DST.ADDR部分第一个字节为域名长度,DST.ADDR剩余的内容为域名,没有\0结尾
  • 0x04: IPv6地址,16个字节长度

SOCKS与HTTP代理的区别

SOCKS工作在比HTTP代理更低的层次,SOCKS使用握手协议来通知代理软件其客户端试图进行SOCKS连接,然后尽可能透明的进行操作。也就是说,SOCKS希望的是充当一个透明的代理中介,尽可能的不对请求数据进行过多的更改。而常规的代理(如HTTP)可能会解释和重写报头.

SOCKS可以转发UDP流量,而HTTP代理并不行(仅限SOCKS5)

简要概括,就是SOCKS相当于在防火墙上打了个洞。

参考

Golang神奇的2006-01-02 15:04:05:www.jianshu.com/p/c7f7fbb16…

OSI模型:zh.m.wikipedia.org/zh-sg/OSI%E…

SOCKS5抓包分析:www.quarkay.com/code/394/SO…

理解SOCKS5协议的工作过程和协议细节:wiyi.org/socks5-prot…

SOCKS5代理分析:guiyongdong.github.io/2017/12/09/…

Golang的SOCKS5实战:github.com/wangkechun/…

Golang学习路线

码一下golang的学习路线,便于以后按照路线进行学习!

image