zoukankan      html  css  js  c++  java
  • netty系列之:netty对SOCKS协议的支持

    简介

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

    SocksMessage

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

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

        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,它里面什么内容都没有。

    public interface Socks4Message extends SocksMessage {
        // Tag interface
    }
    

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

        public static final Socks4CommandType CONNECT = new Socks4CommandType(0x01, "CONNECT");
        public static final Socks4CommandType BIND = new Socks4CommandType(0x02, "BIND");
    
    

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

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

        Socks4CommandType type();
    
        String userId();
    
        String dstAddr();
    
        int dstPort();
    

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

        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两个属性。

        Socks4CommandStatus status();
    
        String dstAddr();
    
        int dstPort();
    

    Socks5Message

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

    public interface Socks5Message extends SocksMessage {
        // Tag interface
    }
    

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

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

        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的列表:

    public interface Socks5InitialRequest extends Socks5Message {
        List<Socks5AuthMethod> authMethods();
    }
    

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

    public interface Socks5InitialResponse extends Socks5Message {
    
        Socks5AuthMethod authMethod();
    }
    

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

    public interface Socks5PasswordAuthRequest extends Socks5Message {
    
        String username();
    
        String password();
    }
    

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

        public static final Socks5PasswordAuthStatus SUCCESS = new Socks5PasswordAuthStatus(0x00, "SUCCESS");
        public static final Socks5PasswordAuthStatus FAILURE = new Socks5PasswordAuthStatus(0xFF, "FAILURE");
    
    

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

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

        Socks5CommandType type();
    
        Socks5AddressType dstAddrType();
    
        String dstAddr();
    
        int dstPort();
    

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

        Socks5CommandStatus status();
        Socks5AddressType bndAddrType();
        String bndAddr();
        int bndPort();
    

    总结

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

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

    最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

  • 相关阅读:
    python 格式化打印
    微软开发工具包下载
    win7 Adobe flash player 无法在线更新
    MySQL5.7本地首次登录win10报错修改
    MySQL本地登录及数据库导入导出
    03蓝桥杯特训课笔记总结:
    03第八届蓝桥杯省赛真题- 2.等差素数列
    02填空题
    01蓝桥杯第七届 方格填数(dfs)
    63中国剩余定理
  • 原文地址:https://www.cnblogs.com/flydean/p/15769696.html
Copyright © 2011-2022 走看看