Skip to content

Commit f249813

Browse files
committed
First bits towards providing access over DoH in addition to DNS
Mainly to deal with the Firefox+ESNI situation
1 parent 30b5507 commit f249813

3 files changed

Lines changed: 94 additions & 4 deletions

File tree

dnscrypt-proxy/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type Config struct {
3333
ServerNames []string `toml:"server_names"`
3434
DisabledServerNames []string `toml:"disabled_server_names"`
3535
ListenAddresses []string `toml:"listen_addresses"`
36+
LocalDoHListenAddresses []string `toml:"local_doh_listen_addresses"`
3637
Daemonize bool
3738
UserName string `toml:"user_name"`
3839
ForceTCP bool `toml:"force_tcp"`
@@ -94,6 +95,7 @@ func newConfig() Config {
9495
return Config{
9596
LogLevel: int(dlog.LogLevel()),
9697
ListenAddresses: []string{"127.0.0.1:53"},
98+
LocalDoHListenAddresses: []string{"127.0.0.1:443"},
9799
Timeout: 5000,
98100
KeepAlive: 5,
99101
CertRefreshDelay: 240,
@@ -325,7 +327,7 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
325327
proxy.certRefreshDelayAfterFailure = time.Duration(10 * time.Second)
326328
proxy.certIgnoreTimestamp = config.CertIgnoreTimestamp
327329
proxy.ephemeralKeys = config.EphemeralKeys
328-
if len(config.ListenAddresses) == 0 {
330+
if len(config.ListenAddresses) == 0 && len(config.LocalDoHListenAddresses) == 0 {
329331
dlog.Debug("No local IP/port configured")
330332
}
331333

@@ -349,6 +351,7 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
349351
proxy.serversInfo.lbEstimator = config.LBEstimator
350352

351353
proxy.listenAddresses = config.ListenAddresses
354+
proxy.localDoHListenAddresses = config.LocalDoHListenAddresses
352355
proxy.daemonize = config.Daemonize
353356
proxy.pluginBlockIPv6 = config.BlockIPv6
354357
proxy.cache = config.Cache

dnscrypt-proxy/local-doh.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package main
2+
3+
import (
4+
"net"
5+
"net/http"
6+
7+
"github.com/jedisct1/dlog"
8+
)
9+
10+
type localDoHHandler struct {
11+
}
12+
13+
func (handler localDoHHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
14+
dataType := "application/dns-message"
15+
if request.Header.Get("Content-Type") != dataType {
16+
writer.WriteHeader(400)
17+
return
18+
}
19+
writer.WriteHeader(200)
20+
writer.Header().Add("Server", "dnscrypt-proxy")
21+
writer.Header().Add("Content-Type", "application/dns-message")
22+
writer.Write([]byte("OK\n"))
23+
}
24+
25+
func (proxy *Proxy) localDoHListener(acceptPc *net.TCPListener) {
26+
defer acceptPc.Close()
27+
httpServer := &http.Server{ReadTimeout: proxy.timeout, WriteTimeout: proxy.timeout, Handler: localDoHHandler{}}
28+
if err := httpServer.Serve(acceptPc); err != nil {
29+
dlog.Fatal(err)
30+
}
31+
}

dnscrypt-proxy/proxy.go

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type Proxy struct {
3131
certIgnoreTimestamp bool
3232
mainProto string
3333
listenAddresses []string
34+
localDoHListenAddresses []string
3435
daemonize bool
3536
registeredServers []RegisteredServer
3637
registeredRelays []RegisteredServer
@@ -75,7 +76,7 @@ type Proxy struct {
7576
showCerts bool
7677
}
7778

78-
func (proxy *Proxy) addListener(listenAddrStr string) {
79+
func (proxy *Proxy) addDNSListener(listenAddrStr string) {
7980
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
8081
if err != nil {
8182
dlog.Fatal(err)
@@ -121,7 +122,6 @@ func (proxy *Proxy) addListener(listenAddrStr string) {
121122
FileDescriptors = append(FileDescriptors, fdUDP)
122123
FileDescriptors = append(FileDescriptors, fdTCP)
123124
return
124-
125125
}
126126

127127
// child
@@ -144,6 +144,48 @@ func (proxy *Proxy) addListener(listenAddrStr string) {
144144
go proxy.tcpListener(listenerTCP.(*net.TCPListener))
145145
}
146146

147+
func (proxy *Proxy) addLocalDoHListener(listenAddrStr string) {
148+
listenTCPAddr, err := net.ResolveTCPAddr("tcp", listenAddrStr)
149+
if err != nil {
150+
dlog.Fatal(err)
151+
}
152+
153+
// if 'userName' is not set, continue as before
154+
if len(proxy.userName) <= 0 {
155+
if err := proxy.localDoHListenerFromAddr(listenTCPAddr); err != nil {
156+
dlog.Fatal(err)
157+
}
158+
return
159+
}
160+
161+
// if 'userName' is set and we are the parent process
162+
if !proxy.child {
163+
// parent
164+
listenerTCP, err := net.ListenTCP("tcp", listenTCPAddr)
165+
if err != nil {
166+
dlog.Fatal(err)
167+
}
168+
fdTCP, err := listenerTCP.File() // On Windows, the File method of TCPListener is not implemented.
169+
if err != nil {
170+
dlog.Fatalf("Unable to switch to a different user: %v", err)
171+
}
172+
defer listenerTCP.Close()
173+
FileDescriptors = append(FileDescriptors, fdTCP)
174+
return
175+
}
176+
177+
// child
178+
179+
listenerTCP, err := net.FileListener(os.NewFile(uintptr(3+FileDescriptorNum), "listenerTCP"))
180+
if err != nil {
181+
dlog.Fatalf("Unable to switch to a different user: %v", err)
182+
}
183+
FileDescriptorNum++
184+
185+
dlog.Noticef("Now listening to %v [HTTP]", listenAddrStr)
186+
go proxy.localDoHListener(listenerTCP.(*net.TCPListener))
187+
}
188+
147189
func (proxy *Proxy) StartProxy() {
148190
proxy.questionSizeEstimator = NewQuestionSizeEstimator()
149191
if _, err := crypto_rand.Read(proxy.proxySecretKey[:]); err != nil {
@@ -154,8 +196,12 @@ func (proxy *Proxy) StartProxy() {
154196
proxy.serversInfo.registerServer(registeredServer.name, registeredServer.stamp)
155197
}
156198
for _, listenAddrStr := range proxy.listenAddresses {
157-
proxy.addListener(listenAddrStr)
199+
proxy.addDNSListener(listenAddrStr)
158200
}
201+
for _, listenAddrStr := range proxy.localDoHListenAddresses {
202+
proxy.addLocalDoHListener(listenAddrStr)
203+
}
204+
159205
// if 'userName' is set and we are the parent process drop privilege and exit
160206
if len(proxy.userName) > 0 && !proxy.child {
161207
proxy.dropPrivilege(proxy.userName, FileDescriptors)
@@ -270,6 +316,16 @@ func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) error {
270316
return nil
271317
}
272318

319+
func (proxy *Proxy) localDoHListenerFromAddr(listenAddr *net.TCPAddr) error {
320+
acceptPc, err := net.ListenTCP("tcp", listenAddr)
321+
if err != nil {
322+
return err
323+
}
324+
dlog.Noticef("Now listening to %v [HTTP]", listenAddr)
325+
go proxy.localDoHListener(acceptPc)
326+
return nil
327+
}
328+
273329
func (proxy *Proxy) prepareForRelay(ip net.IP, port int, encryptedQuery *[]byte) {
274330
anonymizedDNSHeader := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00}
275331
relayedQuery := append(anonymizedDNSHeader, ip.To16()...)

0 commit comments

Comments
 (0)