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"`
|
ServerNames []string `toml:"server_names"`
|
||||||
DisabledServerNames []string `toml:"disabled_server_names"`
|
DisabledServerNames []string `toml:"disabled_server_names"`
|
||||||
ListenAddresses []string `toml:"listen_addresses"`
|
ListenAddresses []string `toml:"listen_addresses"`
|
||||||
|
LocalDoHListenAddresses []string `toml:"local_doh_listen_addresses"`
|
||||||
Daemonize bool
|
Daemonize bool
|
||||||
UserName string `toml:"user_name"`
|
UserName string `toml:"user_name"`
|
||||||
ForceTCP bool `toml:"force_tcp"`
|
ForceTCP bool `toml:"force_tcp"`
|
||||||
|
@ -94,6 +95,7 @@ func newConfig() Config {
|
||||||
return Config{
|
return Config{
|
||||||
LogLevel: int(dlog.LogLevel()),
|
LogLevel: int(dlog.LogLevel()),
|
||||||
ListenAddresses: []string{"127.0.0.1:53"},
|
ListenAddresses: []string{"127.0.0.1:53"},
|
||||||
|
LocalDoHListenAddresses: []string{"127.0.0.1:443"},
|
||||||
Timeout: 5000,
|
Timeout: 5000,
|
||||||
KeepAlive: 5,
|
KeepAlive: 5,
|
||||||
CertRefreshDelay: 240,
|
CertRefreshDelay: 240,
|
||||||
|
@ -325,7 +327,7 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
|
||||||
proxy.certRefreshDelayAfterFailure = time.Duration(10 * time.Second)
|
proxy.certRefreshDelayAfterFailure = time.Duration(10 * time.Second)
|
||||||
proxy.certIgnoreTimestamp = config.CertIgnoreTimestamp
|
proxy.certIgnoreTimestamp = config.CertIgnoreTimestamp
|
||||||
proxy.ephemeralKeys = config.EphemeralKeys
|
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")
|
dlog.Debug("No local IP/port configured")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +351,7 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
|
||||||
proxy.serversInfo.lbEstimator = config.LBEstimator
|
proxy.serversInfo.lbEstimator = config.LBEstimator
|
||||||
|
|
||||||
proxy.listenAddresses = config.ListenAddresses
|
proxy.listenAddresses = config.ListenAddresses
|
||||||
|
proxy.localDoHListenAddresses = config.LocalDoHListenAddresses
|
||||||
proxy.daemonize = config.Daemonize
|
proxy.daemonize = config.Daemonize
|
||||||
proxy.pluginBlockIPv6 = config.BlockIPv6
|
proxy.pluginBlockIPv6 = config.BlockIPv6
|
||||||
proxy.cache = config.Cache
|
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
|
certIgnoreTimestamp bool
|
||||||
mainProto string
|
mainProto string
|
||||||
listenAddresses []string
|
listenAddresses []string
|
||||||
|
localDoHListenAddresses []string
|
||||||
daemonize bool
|
daemonize bool
|
||||||
registeredServers []RegisteredServer
|
registeredServers []RegisteredServer
|
||||||
registeredRelays []RegisteredServer
|
registeredRelays []RegisteredServer
|
||||||
|
@ -75,7 +76,7 @@ type Proxy struct {
|
||||||
showCerts bool
|
showCerts bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) addListener(listenAddrStr string) {
|
func (proxy *Proxy) addDNSListener(listenAddrStr string) {
|
||||||
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
|
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dlog.Fatal(err)
|
dlog.Fatal(err)
|
||||||
|
@ -121,7 +122,6 @@ func (proxy *Proxy) addListener(listenAddrStr string) {
|
||||||
FileDescriptors = append(FileDescriptors, fdUDP)
|
FileDescriptors = append(FileDescriptors, fdUDP)
|
||||||
FileDescriptors = append(FileDescriptors, fdTCP)
|
FileDescriptors = append(FileDescriptors, fdTCP)
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// child
|
// child
|
||||||
|
@ -144,6 +144,48 @@ func (proxy *Proxy) addListener(listenAddrStr string) {
|
||||||
go proxy.tcpListener(listenerTCP.(*net.TCPListener))
|
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() {
|
func (proxy *Proxy) StartProxy() {
|
||||||
proxy.questionSizeEstimator = NewQuestionSizeEstimator()
|
proxy.questionSizeEstimator = NewQuestionSizeEstimator()
|
||||||
if _, err := crypto_rand.Read(proxy.proxySecretKey[:]); err != nil {
|
if _, err := crypto_rand.Read(proxy.proxySecretKey[:]); err != nil {
|
||||||
|
@ -154,8 +196,12 @@ func (proxy *Proxy) StartProxy() {
|
||||||
proxy.serversInfo.registerServer(registeredServer.name, registeredServer.stamp)
|
proxy.serversInfo.registerServer(registeredServer.name, registeredServer.stamp)
|
||||||
}
|
}
|
||||||
for _, listenAddrStr := range proxy.listenAddresses {
|
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 'userName' is set and we are the parent process drop privilege and exit
|
||||||
if len(proxy.userName) > 0 && !proxy.child {
|
if len(proxy.userName) > 0 && !proxy.child {
|
||||||
proxy.dropPrivilege(proxy.userName, FileDescriptors)
|
proxy.dropPrivilege(proxy.userName, FileDescriptors)
|
||||||
|
@ -270,6 +316,16 @@ func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) error {
|
||||||
return nil
|
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) {
|
func (proxy *Proxy) prepareForRelay(ip net.IP, port int, encryptedQuery *[]byte) {
|
||||||
anonymizedDNSHeader := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00}
|
anonymizedDNSHeader := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00}
|
||||||
relayedQuery := append(anonymizedDNSHeader, ip.To16()...)
|
relayedQuery := append(anonymizedDNSHeader, ip.To16()...)
|
||||||
|
|
Loading…
Reference in New Issue