文档章节

基于netty实现的socks5代理协议

xtuhcy
 xtuhcy
发布于 2016/12/28 17:28
字数 1734
阅读 2.9K
收藏 2

基于netty实现的socks5代理协议

socks5协议

简介

socks5协议是一个标准的代理协议,工作在网络的四层,理论上可以代理任意应用层协议。协议标准RFC1928,用户/密码鉴权标准RFC1929。协议的中文版本可以参考这里

现有开源实现

用的比较多的是linux下的ss5开源实现,ss5的安装和配置如下:

./configure --with-debug --with-epollio --with-gssapi
make
make install
chomd +x /etc/init.d/ss5

修改/etc/init.d/ss5,增加端口,日志等配置:

export SS5_SOCKS_PORT=1081
export SS5_CONFIG_FILE=/tmp/ss5.conf
export SS5_PASSWORD_FILE=/tmp/ss5.passwd
export SS5_LOG_FILE=/tmp/ss5.log
export SS5_PROFILE_PATH=/tmp

修改/etc/sysconfig/ss5,配置服务器启动用户:

SS5_OPTS=" -u root"

修改/etc/opt/ss5/ss5.conf,配置鉴权方式:

permit -        0.0.0.0/0       -       0.0.0.0/0       -       -       -       -       -	
#不使用用户认证,
auth 0.0.0.0/0 – –
#使用用户名/密码认证,
auth 0.0.0.0/0 – u

修改/etc/opt/ss5/ss5.passwd,配置用户密码:

user passord

启动ss5服务:

service ss5 start

为什么要自己实现

需要更精确的记录代理访问日志,需要自己特殊的鉴权方式。ss5是基于c开发的,本人c语言一般,改起来还是稍显费劲,而基于java开发的socks5协议并没有特别成熟的,最终决定自己用netty4.1开发。

netty基本概念

NIO和BIO

BIO阻塞IO,NIO非阻塞IO。NIO基于事件通知机制,可以达到在单线程情况下同时处理多个IO。传统的BIO对每个IO请求都需要分配单独线程处理,而线程的分配是需要占用内存,分配的代价很高。因此传统的BIO每秒并发最多到千级别(和服务器配置相关),而NIO能支持每秒万级的并发。

NIO并不是没有缺点,NIO的异步特性对编程要求较高,和BIO的传统开发相比较,要更难控制,开发和调试难度也较大。

netty简介

在java开发中,提到NIO必会想到netty,netty是一个NIO开发框架,能降低NIO应用开发难度,开发者不需要关注通讯连接,可以将主要的精力放在对收到的信息进行编码,转换为对象,进行业务逻辑处理。netty框架是一个典型的管道过滤器模式的应用。netty3.x和4.x版本有较大的改动,本文主要使用netty4.1。

EventLoopGroup和EventLoop

前面提到NIO能在单线程模型相支持多IO,实际上线程并不是一个,而是有限的几个,这里的EventLoopGroup就是线程池,EventLoop就是线程。EventLoopGroup的线程数量和CPU核心数量相关,也可以初始化的时候自定义。

NIO应用的服务器端通常不止一个线程池,一般会建立一个boss线程池,一个worker线程池。boss线程池用来接收客户端连接,接收的连接交给worker线程池监听,一个worker线程可以监听多个io。

//boss线程池,这里定义线程数量为2
EventLoopGroup boss = new NioEventLoopGroup(2);
//worker线程池,线程数量结合cpu核心计算出来Runtime.getRuntime().availableProcessors() * 2
EventLoopGroup worker = new NioEventLoopGroup();

ServerBootstrap和Bootstrap

Bootstrap是一个builder模式的类型构造器,ServerBootstrap用于服务器端的构造,Bootstrap用于客户端的构造。主要配置线程池、ChannelFactory、基本参数、ChannelHandler链表初始化等。ServerBootstrap调用bind监听端口,Bootstrap调用connect连接服务器端。

在netty中ChannelFuture会经常碰到,由于netty所有的操作都是异步的,bind,connet,close等都不会立即返回接口,都是通过监听方法回调。通过调用ChannelFuture.addListener()添加监听方法。ChannelFutureListener里有几个内置的监听方法CLOSE,CLOSE_ON_FAILURE,FIRE_EXCEPTION_ON_FAILURE。

Channel,ChannelPipeline,ChannelHandler,ChannelHandlerContext

一个Channel分配一个ChannelPipeline,每个ChannelPipeline里是多个ChannelHandler组成的链表,每个ChannelHandler会对应一个ChannelHandlerContext。看看下面的图就能明白: 输入图片说明

  • Channel负责底层通讯,Channel会绑定到一个worker线程中,Channel在收到Event后会传递给ChannelPipeline,Event会在ChannelHandler链表中流转。 输入图片说明

  • ChannelPipeline负责消息的传递,里面是一个ChannelHandler的组成的双向链表,按消息类型分为上行消息ChannelHandler和下行消息ChannelHandler。因此就有了两个子接口,ChannelInboundHandler只关心上行消息,ChannelOutboundHandler只关心下行消息。如果上下行消息都需要关系可以继承ChannelDuplexHandler。ChannelHandler通过调用fireChannelRead()将上行消息传递给下一个Handler,通过调用write()形成下行消息,调用write()后,上行消息将不再传递给下一个Handler。

  • ChannelHandler是处理消息的单元,是netty开发的核心。开发人员大部分都是在写各种Handler。netty内置了很多协议的handler,但是比较遗憾文档不多。上面已经说过,ChannelHandler按消息类型分可以分为ChannelInboundHandler和ChannelOutboundHandler。按功能分为编解码Handler(编码Encoder/解码Decoder)和消息处理Handler。通常需要将上行消息需要进行解码转换为对象,再将对象传递给之后的业务处理Handler。业务处理完毕,将下行对象编码后转换为ByteBuf交给Channel传递给网络层。

ByteBuf

理解ByteBuf对消息的编解码有很多好处,ByteBuf是Channel进行网络通信的核心对象,ByteBuf就像一个缓冲池一样,ByteBuf逻辑上就是一个byte容器。ByteBuf里的数据被两个指针划分为三个部分,如下图所示: 输入图片说明

  • reader index前面的数据是已经读过的数据,这些数据可以扔掉
  • 从reader index开始,到writer index之前的数据是可读数据
  • 从writer index开始,为可写区域

使用netty实现socks5协议

netty中已经内置了socks5协议的编解码,我们只需要实现逻辑处理Handler就行,下面是几个主要的编解码codec:

  • Socks5InitialRequestDecoder负责服务器和客户端协商鉴权方式,返回服务器端支持的鉴权方式,会将消息解码为DefaultSocks5InitialRequest对象
  • Socks5PasswordAuthRequestDecoder是使用用户名和密码的鉴权方式的协议,返回鉴权是否通过,会将消息解码为DefaultSocks5PasswordAuthRequest对象
  • Socks5CommandRequestDecoder负责目标服务器的连接建立,返回建立是否成功,会将消息解码为DefaultSocks5CommandRequest对象
  • Socks5ServerEncoder负责所有下行对象的编码,转换为ByteBuf

编解码工作不需要我们自己开发,剩下的事情就比较简单,只需要处理各个层级的Socks5Request就行了。ChannelHandler链的结构如下:

Socks5ServerEncoder
Socks5InitialRequestDecoder
Socks5InitialRequestHandler(实现自己的处理逻辑)
Socks5PasswordAuthRequestDecoder
Socks5PasswordAuthRequestHandler(实现自己的处理逻辑)
Socks5CommandRequestDecoder
Socks5CommandRequestHandler(实现自己的处理逻辑)

通过实现3个ChannelHandler,我们就能轻松搞定一个socks5协议。全部代码可以在github上查到,项目名为socks5-netty

© 著作权归作者所有

xtuhcy

xtuhcy

粉丝 123
博文 18
码字总数 20733
作品 1
东城
后端工程师
私信 提问
加载中

评论(0)

Netty实现shadowsocks客户端

Shadowsocks是什么 shadowsocks是基于socks5协议实现的代理方式,分为服务器和客户端,双端之间通过使用指定的加密方式(AES,BlowFish,Table等)进行数据传输,有效的突破了GFW。 整个流程可以...

ksfzhaohui
2016/09/08
6.2K
15
Proxy-Go v8.8 发布,新增 iptables 透明转发支持,网关轻松实现全局透明代理!

Proxy 是 golang 实现的高性能 http、https、websocket、tcp、udp、socks5 代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP 端口映射、SSH 中转、TLS 加密传输、协议转换、...

狂奔的蜗牛.
2019/12/23
3K
6
Proxy-Go v8.7 发布,增强 socks5 代理 UDP 功能,DNS 支持 TCP 方式查询!

Proxy 是 golang 实现的高性能 http、https、websocket、tcp、udp、socks5 代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP 端口映射、SSH 中转、TLS 加密传输、协议转换、...

狂奔的蜗牛.
2019/11/25
1.7K
2
Proxy-Go v8.6 发布,增强 TCP 转发

Proxy 是 golang 实现的高性能 http、https、websocket、tcp、udp、socks5 代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP 端口映射、SSH 中转、TLS 加密传输、协议转换、...

狂奔的蜗牛.
2019/11/11
1.9K
9
Proxy-Go v8.5 发布,全能代理服务工具,专业加速!

Proxy 是 golang 实现的高性能 http、https、websocket、tcp、udp、socks5 代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP 端口映射、SSH 中转、TLS 加密传输、协议转换、...

狂奔的蜗牛.
2019/11/04
2.8K
6

没有更多内容

加载失败,请刷新页面

加载更多

Wireshark安装失败或找不到网络接口问题

Wireshark安装失败或找不到网络接口问题 Wireshark捕获数据包,主要依赖Winpcap或Npcap组件。从Wireshark 3.0开始,Npcap代替了Winpcap组件,成为Wireshark默认的网卡核心驱动。当用户安装W...

大学霸
32分钟前
58
0
使用dubbo zookeeper出现的一些问题

1 、在服务提供者方面 @Service要使用dubbo的注解 2、在消费者方面 @Reference 使用dubbo的 3 、消费者开启成功,但一直没有在dubbo中看到服务注册的应用 测试简单的页面也报404错误,这个要...

南桥北木
33分钟前
43
0
sentinel工作流程

1

vqishiyu
34分钟前
48
0
通过手机端远程控制计算机

远程控制可以非常方便的给客户或者同事提供帮助,使用移动端的远程控制,可以更及时的处理问题,Zoho Assist移动端功能非常强大,操作简洁,简单几步即可完成远程协助; 下面给大家演示使用手...

Zoho云服务
37分钟前
39
0
SAF是什么

SAF是 Service Assembly Framework(服务组装框架)的缩写。它提供基于服务注册订阅中心的高效点对点服务调用

writeademo
39分钟前
69
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部