加密SOCKS5信道中防DNS泄露

admin 2023年2月28日04:48:34评论63 views字数 3899阅读12分59秒阅读模式
创建: 2023-02-26 19:08
https://scz.617.cn/network/202302261908.txt

本文从纯粹的技术原理角度简介加密SOCKS5信道中防DNS泄露的问题,不涉及其它。

初代SOCKS5协议本身不包含加密机制,但现实世界中有许多加密SOCKS5实现。现代浏览器及相应Proxy插件普遍支持远程DNS解析,DNS泄露得到相当程度的阻止。但是,这样不足以彻底阻止DNS泄露。比较理想的状态是本机所有DNS解析请求都走加密SOCKS5信道,对此至少有两种现成的开源实现,Tor-DNS与DNS2SOCKS,自行放狗。

缺省情况下,Tor-DNS侦听53/UDP,收到DNS请求后做某种处理再发送到Tor SOCKS5Proxy侦听的9050/TCP,由后者设法进行加密后的远程DNS解析,以此对付DNS泄露。

Tor-DNS用Go语言编写,第一次看Go代码,语法都不了解,全凭其他语言经验瞎猜。起初不想猜,让ChatGPT给我翻译成Python,未能如愿,后来硬着头皮看Go代码,大致看明白了。注意answer函数实现,里面有这么一段

buf[0]  = 5             // VER: 5
if q.opcode == 0        // QUERY
{
    var dn  []byte
    if q.typ == 12      // PTR
    {
        buf[1]  = 0xF1  // CMD: RESOLVE_PTR
        dn      = []byte( ptr2ip( q.name ) )
    }
    else                // Any other record type
    {
        buf[1]  = 0xF0  // CMD: RESOLVE
        dn      = []byte( q.name )
    }
    num        := len(dn)
    buf[2]      = 0     // RSV
    buf[3]      = 3     // ATYP: DOMAINNAME
    buf[4]      = byte( num )
    for i, v := range dn
    {
        buf[5+i]    = v
    }
    buf[5+num]  = 0     // DST.PORT
    buf[6+num]  = 0     // DST.PORT

没看过Tor的源码及文档,仅凭上述代码判断这是一种私有"Tor SOCKS5 DNS"协议,域名解析请求报文格式如下

                           +------------+
                           | DST.ADDR   |
+----+------+-------+------+-----+------+----------+
|VER | CMD  |  RSV  | ATYP | LEN | FQDN | DST.PORT |
+----+------+-------+------+-----+------+----------+
| 5  | 0xF0 |   0   |  3   |  X  | ANY  |    0     |
+----+------+-------+------+-----+------+----------+

参看

《RFC 1928意译版(非直译版)》
https://scz.617.cn/network/200503311423.txt

CMD为非标0xF0,Tor SOCKS5 Proxy对此类请求报文做了扩展处理,此时DST.ADDR格式是"len+str",其余字段如上图所示。下面是对www.youtube.com进行A记录查询时的请求报文

05                      // +0x0 VER
f0                      // +0x1 CMD
00                      // +0x2 RSV
03                      // +0x3 ATYP 3表示DST.ADDR字段对应FQDN(全称域名)
0f                      // +0x4 LEN
77 77 77 279 6f 75 74 // +0x5 FQDN www.youtube.com
75 62 65 263 6f 6d
00 00                   // +0x14 DST.PORT

相应的响应报文

+----+-----+-------+------+----------+----------+
|VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
5  |  0  |   0   |  1   | Variable |    0     |
+----+-----+-------+------+----------+----------+

05          // +0x0 VER
00          // +0x1 REP 0表示成功,其余非0值对应不同的失败情形
00          // +0x2 RSV
01          // +0x3 ATYP 1表示BND.ADDR字段对应IPv4地址
ac d9 06// +0x4 BND.ADDR 网络字节序 172.217.14.110
00 00       // +0x8 BND.PORT

Tor-DNS收到上述响应报文后再组织一个符合DNS协议的A记录查询响应报文,发送给DNS Client。

目前stunnel不支持UDP转发,但Tor-DNS可与stunnel配合,只有一种合理解释,stunnel也支持私有"Tor SOCKS5 DNS"协议,我找到了相应代码。

/*
 * stunnel-5.68srcprotocol.c
 */

NOEXPORT void socks5_server ( CLI *c )
{
    if ( socks.req.ver != 0x05 )
    {
        ...
    }
    // CONNECT
    else if ( socks.req.cmd == 0x01 )
    {
        ...
    }
    /*
     * Line 488
     * RESOLVE (a TOR extension)
     */

    else if ( socks.req.cmd == 0xf0 )
    {
        s_ssl_read( c, &host_len, sizeof host_len );
        host_name   = str_alloc( (size_t)host_len+1 );
        s_ssl_read( c, host_name, host_len );
        host_name[host_len]
                    ='';
        s_ssl_read( c, &port_number, 2 );
        port_name   = str_printf( "%u", ntohs( port_number ) );
        if ( hostport2addr( &addr, host_name, port_name, 0 ) )
        {

stunnel只检查了socks.req.cmd是否为0xf0,未检查socks.req.atyp是否为3,并且不支持socks.req.cmd为0xf1;换句话说,stunnel部分支持私有"Tor SOCKS5 DNS"协议,但对于防DNS泄露,stunnel足矣。

Go可以跨平台交叉编译,Tor-DNS可以编译成PE。

DNS2SOCKS不同于Tor-DNS,前者是一种更通用的防DNS泄露方案,不必与Tor SOCKS5 Proxy或stunnel相配合,可与任意加密SOCKS5 Proxy相配合,DNS2SOCKS要求指定一个支持TCP DNS的DNS Server。其技术原理是,侦听53/UDP,收到UDP DNS请求报文后将之转换成TCP DNS请求报文,通过SOCKS5发送TCP DNS请求;通过SOCKS5收TCP DNS响应,将之转换成UDP DNS响应返回给DNS Client。所有的SOCKS5 Proxy都支持TCP转发,但不见得支持UDP转发,后者实现起来比较复杂。DNS2SOCKS可与Tor、stunnel配合,但未使用私有"Tor SOCKS5 DNS"协议。DNS2SOCKS不利之处在于TCP DNS效率不如UDP DNS,容易超时。若与Tor、stunnel配合,建议用Tor-DNS,后者效率高得多。

Windows版可用Visual C++ 2015 Express Edition编译,作者提供了预编译的PE;同一份源码可用GCC编译Linux版。

原文始发于微信公众号(青衣十三楼飞花堂):加密SOCKS5信道中防DNS泄露

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月28日04:48:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   加密SOCKS5信道中防DNS泄露https://cn-sec.com/archives/1578967.html

发表评论

匿名网友 填写信息