First bits towards providing access over DoH in addition to DNS
Mainly to deal with the Firefox+ESNI situation
This commit is contained in:
parent
30b5507bf4
commit
f249813cc5
|
@ -33,6 +33,7 @@ type Config struct {
|
|||
ServerNames []string `toml:"server_names"`
|
||||
DisabledServerNames []string `toml:"disabled_server_names"`
|
||||
ListenAddresses []string `toml:"listen_addresses"`
|
||||
LocalDoHListenAddresses []string `toml:"local_doh_listen_addresses"`
|
||||
Daemonize bool
|
||||
UserName string `toml:"user_name"`
|
||||
ForceTCP bool `toml:"force_tcp"`
|
||||
|
@ -94,6 +95,7 @@ func newConfig() Config {
|
|||
return Config{
|
||||
LogLevel: int(dlog.LogLevel()),
|
||||
ListenAddresses: []string{"127.0.0.1:53"},
|
||||
LocalDoHListenAddresses: []string{"127.0.0.1:443"},
|
||||
Timeout: 5000,
|
||||
KeepAlive: 5,
|
||||
CertRefreshDelay: 240,
|
||||
|
@ -325,7 +327,7 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
|
|||
proxy.certRefreshDelayAfterFailure = time.Duration(10 * time.Second)
|
||||
proxy.certIgnoreTimestamp = config.CertIgnoreTimestamp
|
||||
proxy.ephemeralKeys = config.EphemeralKeys
|
||||
if len(config.ListenAddresses) == 0 {
|
||||
if len(config.ListenAddresses) == 0 && len(config.LocalDoHListenAddresses) == 0 {
|
||||
dlog.Debug("No local IP/port configured")
|
||||
}
|
||||
|
||||
|
@ -349,6 +351,7 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
|
|||
proxy.serversInfo.lbEstimator = config.LBEstimator
|
||||
|
||||
proxy.listenAddresses = config.ListenAddresses
|
||||
proxy.localDoHListenAddresses = config.LocalDoHListenAddresses
|
||||
proxy.daemonize = config.Daemonize
|
||||
proxy.pluginBlockIPv6 = config.BlockIPv6
|
||||
proxy.cache = config.Cache
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/jedisct1/dlog"
|
||||
)
|
||||
|
||||
type localDoHHandler struct {
|
||||
}
|
||||
|
||||
func (handler localDoHHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
dataType := "application/dns-message"
|
||||
if request.Header.Get("Content-Type") != dataType {
|
||||
writer.WriteHeader(400)
|
||||
return
|
||||
}
|
||||
writer.WriteHeader(200)
|
||||
writer.Header().Add("Server", "dnscrypt-proxy")
|
||||
writer.Header().Add("Content-Type", "application/dns-message")
|
||||
writer.Write([]byte("OK\n"))
|
||||
}
|
||||
|
||||
func (proxy *Proxy) localDoHListener(acceptPc *net.TCPListener) {
|
||||
defer acceptPc.Close()
|
||||
httpServer := &http.Server{ReadTimeout: proxy.timeout, WriteTimeout: proxy.timeout, Handler: localDoHHandler{}}
|
||||
if err := httpServer.Serve(acceptPc); err != nil {
|
||||
dlog.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ type Proxy struct {
|
|||
certIgnoreTimestamp bool
|
||||
mainProto string
|
||||
listenAddresses []string
|
||||
localDoHListenAddresses []string
|
||||
daemonize bool
|
||||
registeredServers []RegisteredServer
|
||||
registeredRelays []RegisteredServer
|
||||
|
@ -75,7 +76,7 @@ type Proxy struct {
|
|||
showCerts bool
|
||||
}
|
||||
|
||||
func (proxy *Proxy) addListener(listenAddrStr string) {
|
||||
func (proxy *Proxy) addDNSListener(listenAddrStr string) {
|
||||
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
|
||||
if err != nil {
|
||||
dlog.Fatal(err)
|
||||
|
@ -121,7 +122,6 @@ func (proxy *Proxy) addListener(listenAddrStr string) {
|
|||
FileDescriptors = append(FileDescriptors, fdUDP)
|
||||
FileDescriptors = append(FileDescriptors, fdTCP)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
// child
|
||||
|
@ -144,6 +144,48 @@ func (proxy *Proxy) addListener(listenAddrStr string) {
|
|||
go proxy.tcpListener(listenerTCP.(*net.TCPListener))
|
||||
}
|
||||
|
||||
func (proxy *Proxy) addLocalDoHListener(listenAddrStr string) {
|
||||
listenTCPAddr, err := net.ResolveTCPAddr("tcp", listenAddrStr)
|
||||
if err != nil {
|
||||
dlog.Fatal(err)
|
||||
}
|
||||
|
||||
// if 'userName' is not set, continue as before
|
||||
if len(proxy.userName) <= 0 {
|
||||
if err := proxy.localDoHListenerFromAddr(listenTCPAddr); err != nil {
|
||||
dlog.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// if 'userName' is set and we are the parent process
|
||||
if !proxy.child {
|
||||
// parent
|
||||
listenerTCP, err := net.ListenTCP("tcp", listenTCPAddr)
|
||||
if err != nil {
|
||||
dlog.Fatal(err)
|
||||
}
|
||||
fdTCP, err := listenerTCP.File() // On Windows, the File method of TCPListener is not implemented.
|
||||
if err != nil {
|
||||
dlog.Fatalf("Unable to switch to a different user: %v", err)
|
||||
}
|
||||
defer listenerTCP.Close()
|
||||
FileDescriptors = append(FileDescriptors, fdTCP)
|
||||
return
|
||||
}
|
||||
|
||||
// child
|
||||
|
||||
listenerTCP, err := net.FileListener(os.NewFile(uintptr(3+FileDescriptorNum), "listenerTCP"))
|
||||
if err != nil {
|
||||
dlog.Fatalf("Unable to switch to a different user: %v", err)
|
||||
}
|
||||
FileDescriptorNum++
|
||||
|
||||
dlog.Noticef("Now listening to %v [HTTP]", listenAddrStr)
|
||||
go proxy.localDoHListener(listenerTCP.(*net.TCPListener))
|
||||
}
|
||||
|
||||
func (proxy *Proxy) StartProxy() {
|
||||
proxy.questionSizeEstimator = NewQuestionSizeEstimator()
|
||||
if _, err := crypto_rand.Read(proxy.proxySecretKey[:]); err != nil {
|
||||
|
@ -154,8 +196,12 @@ func (proxy *Proxy) StartProxy() {
|
|||
proxy.serversInfo.registerServer(registeredServer.name, registeredServer.stamp)
|
||||
}
|
||||
for _, listenAddrStr := range proxy.listenAddresses {
|
||||
proxy.addListener(listenAddrStr)
|
||||
proxy.addDNSListener(listenAddrStr)
|
||||
}
|
||||
for _, listenAddrStr := range proxy.localDoHListenAddresses {
|
||||
proxy.addLocalDoHListener(listenAddrStr)
|
||||
}
|
||||
|
||||
// if 'userName' is set and we are the parent process drop privilege and exit
|
||||
if len(proxy.userName) > 0 && !proxy.child {
|
||||
proxy.dropPrivilege(proxy.userName, FileDescriptors)
|
||||
|
@ -270,6 +316,16 @@ func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (proxy *Proxy) localDoHListenerFromAddr(listenAddr *net.TCPAddr) error {
|
||||
acceptPc, err := net.ListenTCP("tcp", listenAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dlog.Noticef("Now listening to %v [HTTP]", listenAddr)
|
||||
go proxy.localDoHListener(acceptPc)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (proxy *Proxy) prepareForRelay(ip net.IP, port int, encryptedQuery *[]byte) {
|
||||
anonymizedDNSHeader := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00}
|
||||
relayedQuery := append(anonymizedDNSHeader, ip.To16()...)
|
||||
|
|
Loading…
Reference in New Issue