via: https://github.com/net4people/bbs/issues/30
dnstt是一种新的DNS隧道,可以与DNS over HTTPS和DNS over TLS解析器一起使用,根据Turbo Tunnel的理念设计。
https://www.bamsoftware.com/software/dnstt/
git clone https://www.bamsoftware.com/git/dnstt.git
它与其他DNS隧道有何不同?
它可以与DNS over HTTPS(DoH)和DNS over TLS(DoT)解析器一起使用,这使得网络观察者更难以判断是否使用了隧道。
它嵌入了一个适当的可靠性和会话协议(KCP+smux)。客户端和服务器可以同时发送和接收数据,客户端无需等待一个查询接收到响应后再发送下一个查询。同时进行多个查询有助于提高性能。(这就是Turbo Tunnel的概念。)
它使用Noise协议对隧道进行端到端的加密和认证,与DoH/DoT加密分开。
.------. | .--------. .------.
|tunnel| | | public | |tunnel|
|client|<---DoH/DoT--->|resolver|<---UDP DNS--->|server|
'------' |c '--------' '------'
| |e |
.------. |n .------.
|local | |s |remote|
| app | |o | app |
'------' |r '------'
这样的DNS隧道对于绕过审查是有用的。想象一下,一个审查者可以观察到客户端⇔解析器的连接,但无法观察到解析器⇔服务器的连接(图中的垂直线)。传统基于UDP的DNS隧道通常被认为很容易被检测到,因为它们生成的DNS消息的格式不同寻常,而且每个DNS消息必须带有隧道服务器的域名标记,因为中间的递归解析器需要知道将它们转发到哪里。但是使用DoH或DoT,客户端⇔解析器的DNS消息是加密的,因此审查者不能轻易地看到正在使用隧道。(当然,根据加密流量的数量和时序可能仍然可能启发式地检测到隧道,仅仅加密本身并不能解决这个问题。)
我希望这个软件发布可以展示这种类型的隧道设计的潜力。目前,该软件不提供TUN/TAP网络接口,甚至不提供SOCKS或HTTP代理接口。它只是将本地TCP套接字连接到远程TCP套接字。不过,您可以相对容易地设置它以像普通的SOCKS或HTTP代理一样工作,见下文。
DNS区设置
DNS隧道通过使隧道服务器充当特定DNS区的权威解析器来工作。中间的解析器通过将该区域的子域的查询转发到隧道服务器来充当代理。要设置DNS隧道,您需要一个域名和一个可以运行服务器的主机。
假设您的域名是example.com,您的主机的IP地址是203.0.113.2和2001:db8::2。转到您的域名注册商的配置面板,并添加三个新记录:
A tns.example.com 指向203.0.113.2
AAAA tns.example.com 指向2001:db8::2
NS t.example.com 由tns.example.com管理
tns和t标签可以是任何您想要的内容,但tns标签不应是t标签的子域(该子域下的所有内容都保留给隧道负载)。t标签应该很短,因为DNS消息中的空间有限,而且域名占用其中的一部分。
隧道服务器设置
在服务器主机上运行以下命令;即在上面的示例中的tns.example.com / 203.0.113.2 / 2001:db8::2上运行。
cd dnstt-server
go build
首先,您需要为端到端隧道加密生成加密密钥。
./dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub
privkey写入server.key
pubkey写入server.pub
现在运行服务器。127.0.0.1:8000是将转发隧道流的TCP地址(图中的“远程应用程序”)。
./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:8000
隧道服务器需要在端口53上可访问。您可以直接绑定到端口53(-udp :53),但这需要您以root身份运行服务器。最好像上面显示的那样在非特权端口上运行服务器,并使用端口转发将端口53转发到它。在Linux上,以下命令将端口53转发到端口5300:
sudo iptables -I INPUT -p udp --dport 5300 -j ACCEPT
sudo iptables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300
sudo ip6tables -I INPUT -p udp --dport 5300 -j ACCEPT
sudo ip6tables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300
您还需要为隧道服务器连接到的内容提供一些内容。它可以是代理服务器或其他任何内容。为了测试,您可以使用Ncat监听器:
sudo apt install ncat
ncat -lkv 127.0.0.1 8000
隧道客户端设置
cd dnstt-client
go build
将服务器上的server.pub(公钥文件)复制到客户端。您不需要在客户端上使用server.key(私钥文件)。
选择一个DoH或DoT解析器。这里有一个DoH解析器的列表:
https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers
以及这里有一个DoT解析器的列表:
https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Public+Resolvers#DNSPrivacyPublicResolvers-DNS-over-TLS%28DoT%29
https://dnsencryption.info/imc19-doe.html
要使用DoH解析器,请使用-doh选项:
./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:7000
对于DoT,请使用-dot:
./dnstt-client -dot dot.example:853 -pubkey-file server.pub t.example.com 127.0.0.1:7000
127.0.0.1:7000指定了隧道的客户端端口。连接到该端口的任何内容(图中的“本地应用程序”)将通过解析器进行隧道传输,并连接到隧道服务器上的127.0.0.1:8000。您可以使用Ncat客户端测试它;运行此命令,您在客户端终端中键入的任何内容都将显示在服务器上,反之亦然。
ncat -v 127.0.0.1 7000
如何创建标准代理
您可以通过使隧道服务器转发到标准代理服务器来使隧道工作像普通的代理服务器。我发现使用Ncat的HTTP代理服务器模式很方便。
ncat -lkv --proxy-type http 127.0.0.1 3128
./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:3128
在客户端上,将您的应用程序配置为使用隧道的本地端口(127.0.0.1:7000)作为HTTP/HTTPS代理:
./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:7000
curl -x http://127.0.0.1:7000/ https://example.com/
我尝试使用Firefox通过DNS隧道连接到Ncat HTTP代理,它可以正常工作。
本地测试
如果您只想看看它是如何工作的,而不想费心设置DNS区域或网络服务器,您可以在本地主机上运行隧道的两端。这种方式使用明文UDP DNS,所以不用说,跨互联网使用这样的配置是不隐蔽的。因为在这种情况下没有中间解析器,您可以使用任何您想要的域名;只需在客户端和服务器上保持一致即可。
./dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub
./dnstt-server -udp 127.0.0.1:5300 -privkey-file server.key t.example.com 127.0.0.1:8000
ncat -lkv 127.0.0.1 8000
./dnstt-client -udp 127.0.0.1:5300 -pubkey-file server.pub t.example.com 127.0.0.1:7000
ncat -v 127.0.0.1 7000
当它工作时,您将在服务器上看到如下的日志消息:
2020/04/20 01:48:58 pubkey 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff
2020/04/20 01:49:00 begin session 468d274a
2020/04/20 01:49:03 begin stream 468d274a:3
以及在客户端上看到如下的日志消息:
2020/04/20 01:49:00 MTU 134
2020/04/20 01:49:00 begin session 468d274a
2020/04/20 01:49:03 begin stream 468d274a:3
注意事项
对于外部观察者来说,DoH或DoT隧道是隐蔽的,但对于中间的解析器来说并非如此。如果解析器想要阻止您使用隧道,他们可以很容易地做到,只需不递归解析隧道服务器的DNS区域的请求。然而,隧道仍然对恶意解析器的窃听或篡改是安全的;解析器可以拒绝服务,但无法更改或读取隧道的内容。
出于技术原因,该隧道要求解析器支持至少1232字节的UDP负载大小,这比DNS保证的最小值512要大。我怀疑大多数公共的DoH或DoT服务器都满足这个要求,但我没有进行过调查或其他任何操作。
我没有进行任何系统性能测试,但我对Google、Cloudflare和Quad9解析器进行了一些初步测试。使用Google和Cloudflare时,通过Ncat传输文件时,我可以获得超过100 KB/s的下载速度。Cloudflare的DoH解析器偶尔会发送“400 Bad Request”响应(当隧道客户端看到这样的意外状态码时,它会自动限制自身的速度)。Quad9解析器的性能似乎明显不如其他解析器,但我不知道原因。
没有评论:
发表评论