前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >netty系列之:netty对SOCKS协议的支持

netty系列之:netty对SOCKS协议的支持

作者头像
程序那些事
发布2021-12-21 20:39:21
7060
发布2021-12-21 20:39:21
举报
文章被收录于专栏:程序那些事

简介

SOCKS是一个优秀的网络协议,主要被用来做代理,它的两个主要版本是SOCKS4和SOCKS5,其中SOCKS5提供了对认证的支持。通常来说我们使用SSH工具可以构建简单的SOCKS协议通道,那么对于netty来说,是怎么提供对SOCKS的支持呢?一起来看看吧。

SocksMessage

首先是代表SOCKS消息对象的SocksMessage。SocksMessage是一个接口,它里面只有一个返回SocksVersion的version方法。

SocksVersion表示的是Socks的版本号。在netty中,支持三个版本,分别是:

代码语言:javascript
复制
    SOCKS4a((byte) 0x04),

    SOCKS5((byte) 0x05),

    UNKNOWN((byte) 0xff);

其对应的数值是SOCKS协议中的VER字段,我们以SOCKS4协议为例,再复习一下SOCKS的协议结构:

含义

VER

CMD

DSTPORT

DSTIP

ID

字节个数

1

1

2

4

可变

既然netty中SOCKS有两个版本,相对于的SocksMessage接口就有两个实现,分别是Socks4Message和Socks5Message。

Socks4Message

Socks4Messag继承自SocksMessage,表示的是SOCKS4的消息。

事实上,Socks4Messag是一个tag interface,它里面什么内容都没有。

代码语言:javascript
复制
public interface Socks4Message extends SocksMessage {
    // Tag interface
}

对于SOCKS4来说,有两种数据请求类型,分别是CONNECT和BIND,这两种请求类型被定义在Socks4CommandType中:

代码语言:javascript
复制
    public static final Socks4CommandType CONNECT = new Socks4CommandType(0x01, "CONNECT");
    public static final Socks4CommandType BIND = new Socks4CommandType(0x02, "BIND");

有请求就有响应,对应的有两个类,分别是Socks4CommandRequest和Socks4CommandResponse。

对于Request来说,我们需要请求类型,USERID,DSTIP和DSTPORT这几个数据:

代码语言:javascript
复制
    Socks4CommandType type();

    String userId();

    String dstAddr();

    int dstPort();

对于响应来说,有四个不同的状态,分别是SUCCESS、REJECTED_OR_FAILED、IDENTD_UNREACHABLE、IDENTD_AUTH_FAILURE。

代码语言:javascript
复制
    public static final Socks4CommandStatus SUCCESS = new Socks4CommandStatus(0x5a, "SUCCESS");
    public static final Socks4CommandStatus REJECTED_OR_FAILED = new Socks4CommandStatus(0x5b, "REJECTED_OR_FAILED");
    public static final Socks4CommandStatus IDENTD_UNREACHABLE = new Socks4CommandStatus(0x5c, "IDENTD_UNREACHABLE");
    public static final Socks4CommandStatus IDENTD_AUTH_FAILURE = new Socks4CommandStatus(0x5d, "IDENTD_AUTH_FAILURE");

除了Socks4CommandStatus之外,响应请求还有DSTIP和DSTPORT两个属性。

代码语言:javascript
复制
    Socks4CommandStatus status();

    String dstAddr();

    int dstPort();

Socks5Message

同样的,对于SOCKS5来说,也有一个对应的接口Socks5Message,这个接口也是一个Tag interface,它里面什么都没有:

代码语言:javascript
复制
public interface Socks5Message extends SocksMessage {
    // Tag interface
}

对于SOCKS5来说,它的请求要比SOKCS4要复杂,首先的请求是一个初始化请求Socks5InitialRequest,该请求包含了可以接受的认证列表。

这个列表用Socks5AuthMethod来表示,它包含4个方法:

代码语言:javascript
复制
    public static final Socks5AuthMethod NO_AUTH = new Socks5AuthMethod(0x00, "NO_AUTH");
    public static final Socks5AuthMethod GSSAPI = new Socks5AuthMethod(0x01, "GSSAPI");
    public static final Socks5AuthMethod PASSWORD = new Socks5AuthMethod(0x02, "PASSWORD");
    public static final Socks5AuthMethod UNACCEPTED = new Socks5AuthMethod(0xff, "UNACCEPTED");

对于Socks5InitialRequest来说,它包含了一个authMethods的列表:

代码语言:javascript
复制
public interface Socks5InitialRequest extends Socks5Message {
    List<Socks5AuthMethod> authMethods();
}

对于InitialRequest来说,对应的也有Socks5InitialResponse,它包含了服务端选择的Socks5AuthMethod,所以对Socks5InitialResponse来说,它里面只包含了一个Socks5AuthMethod:

代码语言:javascript
复制
public interface Socks5InitialResponse extends Socks5Message {

    Socks5AuthMethod authMethod();
}

客户端和服务器端协商好选择的认证协议之后,接下来就是认证的过程,如果使用的是用户名密码的模式,则对应的是Socks5PasswordAuthRequest:

代码语言:javascript
复制
public interface Socks5PasswordAuthRequest extends Socks5Message {

    String username();

    String password();
}

password认证的结果只有两种结果,分别是SUCCESS和FAILURE:

代码语言:javascript
复制
    public static final Socks5PasswordAuthStatus SUCCESS = new Socks5PasswordAuthStatus(0x00, "SUCCESS");
    public static final Socks5PasswordAuthStatus FAILURE = new Socks5PasswordAuthStatus(0xFF, "FAILURE");

对于Socks5PasswordAuthResponse来说,它包含了一个认证的status:Socks5PasswordAuthStatus。

认证完毕之后,接下来就可以发送CommandRequest了。对应的Socks5CommandRequest包含下面几个属性:

代码语言:javascript
复制
    Socks5CommandType type();

    Socks5AddressType dstAddrType();

    String dstAddr();

    int dstPort();

对应的Socks5CommandResponse包含下面的属性:

代码语言:javascript
复制
    Socks5CommandStatus status();
    Socks5AddressType bndAddrType();
    String bndAddr();
    int bndPort();

总结

以上就是netty对SOCKS4和SOCKS5协议的消息封装。基本上netty中的对象是和SOCKS协议一致的。

本文已收录于 http://www.flydean.com/36-netty-socks-support/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • SocksMessage
    • Socks4Message
      • Socks5Message
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档