SOCKS5 协议解析
代理
根据 HTTP 1.1 的定义,proxy 是:
An intermediary program which acts as both a server and a client for the purpose of making requests on behalf of other clients. Requests are serviced internally or by passing them on, with possible translation, to other servers.
代理就是中间人,一人分饰两角:客户端眼中的目标服务器,目标服务器眼中的客户端——这意味着他必须同时满足C/S 双方的规范。
再细分,如果只是简单的 pipe C/S 两端数据,那他就是个“透明代理”;一旦他对请求或响应进行了修改,那就是“非透明代理”。
但其实,SOCKS5 协议并不负责代理服务器的数据传输环节,此协议只是在C/S两端真实交互之间,建立起一条从客户端到代理服务器的授信连接。
协议流程
从流程上来说,SOCKS5 是一个C/S 交互的协议,交互大概分为这么几步:
1.客户端发送认证协商
2.代理服务器就认证协商进行回复
3.客户端发送希望连接的目标信息
4.代理服务器就连接信息进行确认或拒绝
5.代理服务器连接目标并 pipe 到客户端
协议细节
1. 认证
1.1 请求认证:
| 版本号(1字节) | 可供选认证方法(1字节) | 选择的方法(1~255字节) |
| 固定为5 | 选了多少种 | · X’00’ 不需要认证 · X’01’ GSSAPI · X’02’ 用户名/密码 · X’03’ -- X’7F’ 由IANA分配 · X’80’ -- X’FE’ 为私人方法所保留的 · X’FF’ 没有可以接受的方法 |
1.2 响应认证:
| 版本号(1字节) | 确认认证的方法 |
| 固定为5 | 认证方法列表的某项: · X’00’ 不需要认证 · X’01’ GSSAPI · X’02’ 用户名/密码 · X’03’ -- X’7F’ 由IANA分配 · X’80’ -- X’FE’ 为私人方法所保留的 · X’FF’ 没有可以接受的方法 |
如果客户端不支持认证,那么握手会是这样子:
1 |
请求: 0x05 0x01 0x00 |
如果客户端还支持用户名/密码的认证方式
1 |
请求: 0x05 0x02 0x00 0x02 |
如果客户端只支持用户名/密码的认证方式,那么握手会是这样子:
1 |
请求: 0x05 0x01 0x02 |
2. 请求信息
2.1 发送目标信息:
| 版本号(1字节) | 命令(1字节) | 保留(1字节) | 请求类型(1字节) | 地址(不定长) | 端口(2字节) |
| 固定为5 | 0x01: CONNECT 0x02: BIND 0x03: UDP ASSOCIATE |
固定为 0x00 | 0x01: IP V4 地址 0x03: 域名 0x04: IP V6 地址 |
如果请求 类型是域名, 第个1字节为 域名的长度 |
命令字段说明:
- CONNECT: 用于客户端请求服务器进行代理
- BIND: 用于客户端向服务器上报自己的反向连接监听地址(应用场景如 FTP 下载,客户端需要接受来自服务器的连接)
- UDP ASSOCIATE:用于请求建立到 UDP 数据报中继的连接
2.2 确认连接:
| 版本号(1字节) | 确认回应(1字节) | 保留(1字节) | 响应类型(1字节) | 地址(不定长) | 端口(2字节) |
| 固定为5 | 0x00: succeeded 0x01: general SOCKS server failure 0x02: connection not allowed by ruleset 0x03: Network unreachable 0x04: Host unreachable 0x05: Connection refused 0x06: TTL expired 0x07: Command not supported 0x08: Address type not supported 0x09: to X’FF’ unassigned |
固定为 0x00 | 仅用于响应客 户端BIND命令: 0x01: IP V4 地址 0x03: 域名 0x04: IP V6 地址 |
仅用于响应客 户端BIND命令: 如果请求 类型是域名, 第个1字节为 域名的长度 |
仅用于响应客 户端BIND命令 |
可以看出,在代理服务器确认回应为 0x00 时,此次 SOCKS5 协议协商部分顺利完成,宣告进入到数据传输阶段(也可以说,这之后发生的事已经与SOCKS5协议无关)。
如果客户端要求请求 shadowsocks 代理 127.0.0.1:8000 的请求,那么客户端和 shadowsocks 之间的请求和响应是这样的:
1 |
# request: VER CMD RSV ATYP DST.ADDR DST.PORT |
这里 0x7f 0x00 0x00 0x01 0x1f 0x40 对应的是 127.0.0.1:8000。
需要注意的是,当请求中的 CMD == 0x01 时,绝大部分 SOCKS5 客户端的实现都会忽略 SOCKS5 服务器返回的 BND.ADDR 和 BND.PORT 字段,
所以这里的 0x00 0x00 0x00 0x00 0x10 0x10 只是 shadowsocks 返回的一个无意义的地址和端口。
出处:
loggerhead: shadowsocks 源码解析
SOCKS5 协议解析的更多相关文章
- HTTP协议和SOCKS5协议
HTTP协议和SOCKS5协议 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们平时上网的时候基本上是离不开浏览器的,尤其是搜索资料的时候,那么这个浏览器是如何工作的呢?用的又是 ...
- ts 协议解析
pes : http://wenku.baidu.com/link?url=KjcA0qXqZ1bWVQTa8i1YOmygofldSQL7Pjj-zGRw1e_6_LFmVLo5DIWF0SNwVn ...
- [转]netty对http协议解析原理
本文主要介绍netty对http协议解析原理,着重讲解keep-alive,gzip,truncked等机制,详细描述了netty如何实现对http解析的高性能. 1 http协议 1.1 描述 标示 ...
- twemproxyRedis协议解析探索——剖析twemproxy代码正编
这篇文章会对twemproxyRedis协议解析代码部分进行一番简单的分析,同时给出twemproxy目前支持的所有Redis命令.在这篇文章开始前,我想大家去简单地理解一下有限状态机,当然不理解也是 ...
- B/S 架构中,网络模型的分解与协议解析
前言 如果是C/S专业毕业的或者是学过计算机网络课程的童鞋们,相信大家都知道网络模型的划分,本文首先来聊一聊目前对于B/S结构中,网络模型分解的两种方式. 没错,相信大家看到这个图片的时候就已经明白了 ...
- 详解BLE 空中包格式—兼BLE Link layer协议解析
BLE有几种空中包格式?常见的PDU命令有哪些?PDU和MTU的区别是什么?DLE又是什么?BLE怎么实现重传的?BLE ACK机制原理是什么?希望这篇文章能帮你回答以上问题. 虽然BLE空中包(pa ...
- netty对http协议解析原理解析
本文主要介绍netty对http协议解析原理,着重讲解keep-alive,gzip,truncked等机制,详细描述了netty如何实现对http解析的高性能. 1 http协议 1.1 描述 标示 ...
- MODBUS协议解析中常用的转换帮助类(C#)
p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...
- AOSP中的HLS协议解析
[时间:2018-04] [状态:Open] [关键词:流媒体,stream,HLS, AOSP, 源码分析,HttpLiveSource, LiveSession,PlaylistFetcher] ...
随机推荐
- Java如何计数字串中的一组词组?
在Java编程中,如何计数字串中的一组词组? 以下示例演示如何使用regex.Matcher类的matcher.groupCount()方法来计算字符串中的一组词组. package com.yiib ...
- mysql delete两种关联删除方式
基本格式: DELETE t1 FROM t1,t2 WHERE t1.id=t2.id 或 DELETE FROM t1 USING t1,t2 WHERE t1.id=t2.id 示例应用: ...
- [PHP] 06 - Security: Error, Exception and Filter
前言 Ref: PHP 发送电子邮件 Ref: PHP Secure E-mails PHP发邮件部分在此系列中略. 这里展开”安全“相关的部分. 有啥区别? Ref: PHP异常与错误处理机制 P ...
- [Node.js] 05 - Modules and Function
一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码.JSON 或者编译过的C/C++ 扩展. 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的. No ...
- 分辨率,PPi,DPI,DPR,物理像素,逻辑像素
屏幕尺寸:指的是屏幕对角线的长度 分辨率:是指宽度上和高度上最多能显示的物理像素点个数 点距:像素与像素之间的距离,点距和屏幕尺寸决定了分辨率大小 PPI:屏幕像素密度,即每英寸(1英寸=2.54厘米 ...
- Proc文件系统接口调试
在tpd_i2c_probe I2C的探测函数中创建proc接口 //----------------------------------------------------------------- ...
- Cannot change version of project facet Dynamic Web Module to 3.0 异常问题处理
如何解决Tomcat服务器在初始化应用的时候的以下异常问题 1,Cannot change version of project facet Dynamic Web Module to 3.0 2,O ...
- 多线程局部变量之threading.local()用法
假如,开了十个线程并且做同样的一件事,他们需要带着自己的数据进来,完成事情后带着自己的数据出去.如果是并发,同时进来,他们的数据就会混乱. 一般情况,我们加锁就可以了,一个人先进来,先加锁,另一个人过 ...
- web -- Navigator.vibrate(); 使设备(有振动硬件)产生有频率的振动
MDN 文档 此方法需要用户手势. 否则,它返回false. const koa2 = require(`koa2`); const Router = require(`koa-router`); c ...
- 关于JS获取某月最后一天
发现网上用js获取某月最后一个的方式大多比较复杂,上个简单的: new Date(2013,4).toJSON().substring(0,10) new Date(2013,4,0).toLocal ...