Total Pageviews

Saturday, 9 May 2020

dnstt , a dns tunnel that can do DoH and DoT

dnstt is a new DNS tunnel that works with DNS over HTTPS and DNS over TLS resolvers, designed according to the Turbo Tunnel idea.
git clone https://www.bamsoftware.com/git/dnstt.git
How is it different from other DNS tunnels?
  • It works with DNS over HTTPS (DoH) and DNS over TLS (DoT) resolvers, which makes it more difficult for a network observer to tell that a tunnel is being used.
  • It embeds a proper reliability and session protocol (KCP+smux). The client and server can send and receive simultaneously, and the client doesn't have to wait for one query to receive a response before sending the next query. Having multiple queries in flight helps with performance. (This is the Turbo Tunnel concept.)
  • It encrypts and authenticates the tunnel end to end, separately from the DoH/DoT encryption, using a Noise protocol.
.------.  |            .--------.               .------.
|tunnel|  |            | public |               |tunnel|
|client|<---doh ot---="">|resolver|<---udp dns---="">|server|
'------'  |c           '--------'               '------'
   |      |e                                       |
.------.  |n                                    .------.
|local |  |s                                    |remote|
| app  |  |o                                    | app  |
'------'  |r                                    '------'
A DNS tunnel like this can be useful for censorship circumvention. Think of a censor that can observe the client⇔resolver link, but not the resolver⇔server link (the vertical line in the diagram). Traditional UDP-based DNS tunnels are generally considered to be easy to detect because of the unusual format of the DNS messages they generate—that, and the fact that every DNS message must be tagged with domain name of the tunnel server, because that's how the recursive resolver in the middle knows where to forward them. But with DoH or DoT, the DNS messages on the client⇔resolver are encrypted, so the censor cannot trivially see that a tunnel is being used. (Of course, it may still be possible to heuristically detect a tunnel based on volume and timing of the encrypted traffic—encryption alone doesn't solve that.)
I intend this software release to be a demonstration of the potential this kind of design for a tunnel. Currently the software doesn't provide a TUN/TAP network interface, or even a SOCKS or HTTP proxy interface. It only connects a local TCP socket to a remote TCP socket. Still, you can fairly easily set it up to work like an ordinary SOCKS or HTTP proxy, see below.

DNS zone setup

A DNS tunnel works by having the tunnel server act as an authoritative resolver for a specific DNS zone. The resolver in the middle acts as a proxy by forwarding queries for subdomains of that zone to the tunnel server. To set up a DNS tunnel, you need a domain name and a host where you can run the server.
Let's say your domain name is example.com and your host's IP addresses are 203.0.113.2 and 2001:db8::2. Go to your name registrar's configuration panel and add three new records:
A tns.example.com points to 203.0.113.2
AAAA tns.example.com points to 2001:db8::2
NS t.example.com is managed by tns.example.com
The tns and t labels can be anything you want, but the tns label should not be a subdomain of the t label (everything under that subdomain is reserved for tunnel payloads). The t label should be short because there is limited space in a DNS message, and the domain name takes up part of it.

Tunnel server setup

Run these commands on the server host; i.e. the one at tns.example.com / 203.0.113.2 / 2001:db8::2 in the example above.
cd dnstt-server
go build
First you need to generate crypto keys for the end-to-end tunnel encryption.
./dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub
privkey written to server.key
pubkey  written to server.pub
Now run the server. 127.0.0.1:8000 is the TCP address ("remote app" in the diagram above) to which incoming tunnelled stream will be forwarded.
./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:8000
The tunnel server needs to be reachable on port 53. You could have it bind to port 53 directly (-udp :53), but that would require you to run the server as root. It's better to run the server on a non-privileged port as shown above, and use port forwarding to forward port 53 to it. On Linux, these command will forward port 53 to port 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
You also need something for the tunnel server to connect to. It could be a proxy server or anything else. For testing, you can use an Ncat listener:
sudo apt install ncat
ncat -lkv 127.0.0.1 8000

Tunnel client setup

cd dnstt-client
go build
Copy server.pub (the public key file) from the server to the client. You don't need server.key (the private key file) on the client.
Choose a DoH or DoT resolver. There is a list of DoH resolvers here:
And a list of DoT resolvers here:
To use a DoH resolver, use the -doh option:
./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:7000
For DoT, use -dot:
./dnstt-client -dot dot.example:853 -pubkey-file server.pub t.example.com 127.0.0.1:7000
127.0.0.1:7000 specifies the client end of the tunnel. Anything that connects to that port ("local app" in the diagram above) will be tunnelled through the resolver and connected to 127.0.0.1:8000 on the tunnel server. You can test it using an Ncat client; run this command, and anything you type into the client terminal will appear on the server, and vice versa.
ncat -v 127.0.0.1 7000

How to make a standard proxy

You can make the tunnel work like an ordinary proxy server by having the tunnel server forward to a standard proxy server. I find it convenient to use Ncat's HTTP proxy server mode.
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
On the client, configure your applications to use the local end of the tunnel (127.0.0.1:7000) as an HTTP/HTTPS proxy:
./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/
I tried with Firefox connecting to an Ncat HTTP proxy through the DNS tunnel, and it works.

Local testing

If you just want to see how it works, without going to the trouble of setting up a DNS zone or a network server, you can run both ends of the tunnel on localhost. This way uses plaintext UDP DNS, so needless to say it's not covert to use a configuration like this across the Internet. Because there's no intermediate resolver in this case, you can use any domain name you want; it just has to be the same on client and server.
./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
When it's working, you will see log messages like this on the server:
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
And this on the client:
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

Caveats

A DoH or DoT tunnel is covert to an outside observer, but not to the resolver in the middle. If the resolver wants to stop you from using a tunnel, they can do it easily, by not recursively resolving requests for the DNS zone of the tunnel server. The tunnel is still secure against eavesdropping or tampering by a malicious resolver, though; the resolver can deny service but cannot alter or read the contents of the tunnel.
For technical reasons, the tunnel requires the resolver to support a UDP payload size of at least 1232 bytes, which is bigger than the minimum of 512 guaranteed by DNS. I suspect that most public DoH or DoT servers meet this requirement, but I haven't done a survey or anything.
I haven't done any systematic performance tests, but I've done some cursory testing with the Google, Cloudflare, and Quad9 resolvers. With Google and Cloudflare I can get more than 100 KB/s download when piping files through Ncat. The Cloudflare DoH resolver occasionally sends a "400 Bad Request" response (the tunnel client automatically throttles itself when it sees an unexpected status code like that). The Quad9 resolvers seem to have notably worse performance than the others, but I don't know why.

As of tag v0.20200426.0 in the source code, dnstt-server lets you control the maximum UDP payload size with the -mtu option. The default is -mtu 1232. You can use -mtu 512 for maximum compatibility with resolvers, at the expense of bandwidth. If you know the resolver you are using supports larger UDP payloads, you can increase the value. The Cloudflare resolver supports -mtu 1452, for example; but I don't recommend going higher than that because you start to risk IP fragmentation. If you use an -mtu value that is larger than what the resolver supports, the tunnel won't work at all and you will get error messages in the server log that tell you what value to use.

I repeated the experiment with iodine, an existing DNS tunnel. iodine works over plaintext UDP only. dnstt is faster than iodine in every case, except for the Quad9 DoT resolver. It is possible to run iodine over a DoH proxy; I didn't try that myself but Sebastian Neef reports 4–12 KB/s when tunneling iodine through dnscrypt-proxy.
resolvertransportdownload rate
noneiodine14.6 KB/s
Googleiodine1.8 KB/s
Cloudflareiodine1.4 KB/s
Quad9iodine0.3 KB/s
This graph shows the 5 trials under each experimental condition and gives an idea of the variance. Steeper lines are better.
The source code for these experiments is available in the following repo. I used git-annex to store the data files (there are over 3 GB of pcap files). You will have to git annex get the data files you want after git clone. The .csv files are sufficient to reproduce the graph. See procedure.txt for the commands to run to reproduce the experiment. .keylog files are TLS secrets in NSS Key Log Format; you can use these in Wireshark to decrypt the DoH and DoT streams.
git clone https://www.bamsoftware.com/git/dnstt-tests.git
cd dnstt-tests
git annex get 2020-04-30/*.csv
Rscript graphs.R
Update 2020-05-05: I updated the tables and figure to exclude a preliminary test run that I did not intend to include in the first place. The change did not affect any of the qualitative observations. The Cloudflare/DoH case increased by about 7 KB/s from 126.7 KB/s to 133.5 KB/s; none of the other cases changed by more than 3 KB/s.

I've set up a web page for dnstt:
https://www.bamsoftware.com/software/dnstt/

This utility works during internet shutdown in Turkmenistan. It successfully establishes direct UDP connection to the destination server (without using any public resolver) and transfers up to 2 mbit/s of download.
Iodine is very unstable in these conditions, while dnstt is stable and fast.

 
 (DNS隧道可以实现 DoH和DoT

dnstt是一种新的DNS隧道,可以与DNS over HTTPS和DNS over TLS解析器一起使用,根据Turbo Tunnel的理念设计。

https://www.bamsoftware.com/software/dnstt/

git clone https://www.bamsoftware.com/git/dnstt

它与其他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解析器的性能似乎明显不如其他解析器,但我不知道原因。)
--------------------------------------------

dnstt

dnstt is a DNS tunnel that can use DNS over HTTPS (DoH) and DNS over TLS (DoT) resolvers.
A DNS tunnel is one way of circumventing network censorship. A recursive DNS resolver's purpose is to receive packets and forward them somewhere else—in effect, working as a kind of network proxy. DNS tunnels over plaintext UDP are generally considered easy to detect because of the unusual DNS messages they use. However DoH and DoT are encrypted—an outside observer can see that you are communicating with a public resolver, but cannot decrypt the raw DNS messages to see that they embed a tunnel protocol. (The resolver itself can still easily tell that you are using a tunnel.)
A diagram showing a "local app" and "remote app",
       between which direct communication is blocked by a censor,
       communicating by way of a "tunnel client" and "tunnel server",
       with a "public recursive DNS resolver" in the middle.
       The link between the tunnel client and resolver is marked "HTTPS / TLS" and
       the link between the resolver and the tunnel server is marked "UDP".
dnstt uses end-to-end encryption and authentication between the tunnel client and tunnel server by default. Its protocol design enables higher performance than other DNS tunnels.
Idea: DNS-over-HTTP transport.
Original announcement thread.
Last updated: .

Download

dnstt-20200506.zip (signaturepublic key)
git clone https://www.bamsoftware.com/git/dnstt.git
The code is written in Go. dnstt is in the public domain.

How to set it up

dnstt doesn't offer a TUN/TAP network interface, or even a SOCKS or HTTP proxy interface, only a netcat-like connection between a local TCP socket and a remote TCP socket. However, it's fairly easy to make the tunnel act like a standard proxy server by running a proxy at the tunnel server.
A DNS tunnel works by having the tunnel server act as an authoritative resolver for a specific domain name. The recursive resolver in the middle acts as a proxy by forwarding queries for that domain to the tunnel server. To set up a DNS tunnel, you need a domain name and a host that can receive UDP packets, where you run the tunnel server. In these instructions, we'll assume the following example setup:
Your domain nameexample.com
Your server's IPv4 address203.0.113.2
Your server's IPv6 address2001:db8::2

DNS setup

Go into your name registrar's configuration panel and add three records:
Atns.example.compoints to203.0.113.2
AAAAtns.example.compoints to2001:db8::2
NSt.example.comis managed bytns.example.com
tns.example.com points to the addresses of your tunnel server. It is marked as being the nameserver for everything in the t.example.com DNS zone. When a recursive resolver receives a query for subdomain.t.example.com, it will forward the query to the tunnel server—that is how the client tunnels data to the server.
The "tns" and "t" labels can be anything you want, but the "tns" label should not be a subdomain of the "t" label (everything under that subdomain is reserved for tunnel payloads). The "t" label should be short, because there is limited space available in a DNS message, and the domain name takes up part of it.

Tunnel server setup

tunnel-server$ cd dnstt/dnstt-server
tunnel-server$ go build
First you need to generate private and public keys for the end-to-end tunnel encryption.
tunnel-server$ ./dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub
privkey written to server.key
pubkey  written to server.pub
Now run the server. 127.0.0.1:8000 is the TCP address to which incoming tunnelled streams will be forwarded ("remote app" in the diagram).
tunnel-server$ ./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:8000
The tunnel server needs to be reachable on UDP port 53. You could have it bind to port 53 directly (-udp :53), but that would require you to run the server as root. It's better to run the server on a non-privileged port as shown above, and use port forwarding to forward port 53 to it. On Linux, these commands will forward port 53 to port 5300:
tunnel-server$ sudo iptables -I INPUT -p udp --dport 5300 -j ACCEPT
tunnel-server$ sudo iptables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300
tunnel-server$ sudo ip6tables -I INPUT -p udp --dport 5300 -j ACCEPT
tunnel-server$ sudo ip6tables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-ports 5300
You need something at 127.0.0.1:8000 for the tunnel server to connect to. Down below there are instructions for running a proxy server. For testing purposes, you can use an Ncat listener to print incoming data to the terminal:
tunnel-server$ sudo apt install ncat
tunnel-server$ ncat -l -k -v 127.0.0.1 8000
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on 127.0.0.1:8000
By default, dnstt-server assumes that the recursive resolver supports DNS responses up to a certain size, namely 1232 bytes. If your chosen resolver does not support responses that large (there will be error messages in the server output), you can specify a smaller limit using the -mtu option, for example -mtu 512.

Tunnel client setup

tunnel-client$ cd dnstt/dnstt-client
tunnel-client$ go build
Copy server.pub (the public key file) from the server to the client. You don't need server.key (the private key file) on the client.
Choose a DoH or DoT resolver.
DoH resolvers
DoT resolvers
To use a DoH resolver, use the -doh option:
tunnel-client$ ./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:7000
To use a DoT resolver, use -dot:
tunnel-client$ ./dnstt-client -dot dot.example:853 -pubkey-file server.pub t.example.com 127.0.0.1:7000
127.0.0.1:7000 is the client end of the tunnel ("local app" in the diagram). Anything that connects to that port on the tunnel client will be tunnelled through the public resolver and connected to 127.0.0.1:8000 on the tunnel server. You can test it using an Ncat client. Run this command, and anything you type into the client terminal will appear on the server, and vice versa.
tunnel-client$ ncat -v 127.0.0.1 7000

How to integrate with a proxy server

dnstt is only a tunnel; it's up to you what you want to connect to it. You can make the tunnel work like an ordinary SOCKS or HTTP proxy by having the tunnel server forward to a standard proxy server. There are many ways to set it up; here are some examples.

Ncat HTTP proxy

For testing, I find it convenient to use Ncat's HTTP proxy server mode. But be aware that Ncat's proxy isn't intended for use by untrusted clients; it won't prevent them from connecting to localhost ports on the tunnel server, for example.
tunnel-server$ ncat -l -k -v --proxy-type http 127.0.0.1 3128
tunnel-server$ ./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:3128
tunnel-client$ ./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:7000
On the client, configure applications to use the local end of the tunnel (127.0.0.1:7000) as an HTTP/HTTPS proxy.
tunnel-client$ curl --proxy http://127.0.0.1:7000/ https://wtfismyip.com/text
A screenshot of the Connection Settings dialog in Firefox 68.7.0esr.
      The "Manual proxy configuration" radio button is selected, with
      "HTTP Proxy: 127.0.0.1", "Port: 7000", and
      "Use this proxy server for all protocols" checked.
Configuring an HTTP/HTTPS proxy in Firefox 68. Go to PreferencesGeneral, then Network Settings.

SSH SOCKS proxy

OpenSSH has a built-in SOCKS proxy. If you run an SSH server on the tunnel server, you can use dnstt to tunnel the SSH connection, and the SSH server will proxy connections for you. Let's assume you already have the SSH details configured so that you can run ssh tunnel-server on the tunnel client. Make sure AllowTcpForwarding is set to yes (the default value) in sshd_config.
Run the tunnel server and have it forward directly to the SSH port.
# sshd is already running at port 22
tunnel-server$ ./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:22
Run the tunnel client with the local listening port at 127.0.0.1:2222. Run ssh to connect to the tunnel server as if it were at 127.0.0.1:2222, and open a SOCKS port at 127.0.0.1:7000. Replace tunnel-server with the hostname or IP address of the tunnel and SSH server.
tunnel-client$ ./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:2222
tunnel-client$ ssh -v -N -D 127.0.0.1:7000 -o HostKeyAlias=tunnel-server -p 2222 127.0.0.1
On the client, configure applications to use the SSH SOCKS port (127.0.0.1:7000) as a SOCKS proxy.
tunnel-client$ curl --proxy socks5://127.0.0.1:7000/ https://wtfismyip.com/text
A screenshot of the Connection Settings dialog in Firefox 68.7.0esr.
      The "Manual proxy configuration" radio button is selected, with
      "SOCKS Host: 127.0.0.1", "Port: 7000", and
      "SOCKS v5" selected.
      "Proxy DNS when using SOCKS v5" is checked.
Configuring a SOCKS proxy in Firefox 68. Go to PreferencesGeneral, then Network Settings.

Tor bridge

You can run a Tor bridge on the tunnel server and tunnel the connection to the bridge with dnstt, using dnstt as something like a pluggable transport. The Tor client provides a SOCKS interface that other programs can use.
Have the tunnel server forward to the Tor ORPort:
# tor is already running at port 9001
tunnel-server$ ./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:9001
Have the tunnel client open a local listener at 127.0.0.1:7000. Connections to this port will be forwarded to the bridge's ORPort through the tunnel.
tunnel-client$ ./dnstt-client -doh https://doh.example/dns-query -pubkey-file server.pub t.example.com 127.0.0.1:7000
Add a Bridge line to /etc/tor/torrc (if you use a system Tor), or paste it into Tor Browser. If you use a system Tor, restart the Tor daemon. You can get FINGERPRINT from the file /var/lib/tor/fingerprint on the bridge.
Bridge 127.0.0.1:7000 FINGERPRINT
Configure applications to use the Tor SocksPort as a SOCKS proxy. If you use a system Tor, the SocksPort is 127.0.0.1:9050; if you use Tor Browser, the SocksPort is 127.0.0.1:9150.
tunnel-client$ curl --proxy socks5://127.0.0.1:9050/ https://wtfismyip.com/text
tunnel-client$ curl --proxy socks5://127.0.0.1:9150/ https://wtfismyip.com/text
Original post (): How to run Tor Browser through a DoH/DoT tunnel.

Protocol

See the protocol page.
The "tt" in dnstt stands for Turbo Tunnel, a design paradigm for circumvention protocols. It just means that embeds a sequencing and reliability layer, independent of the DNS transport.
I made a survey of the protocols of some other DNS tunnels.

Performance

See the performance page.

Acknowledgements

Thanks to kcp-gosmuxNoise and its mailing list, the Flynn implementation of NoiseValdikSS, and net4people/bbs and NTC correspondents. This software was developed under a contract with the Counter-Power Lab at UC Berkeley.

from https://www.bamsoftware.com/software/dnstt/
--------------------------------------------


No comments:

Post a Comment