Add a config file

This commit is contained in:
Frank Denis 2018-01-10 12:01:49 +01:00
parent f24884a27a
commit 2822a9781b
4 changed files with 176 additions and 48 deletions

5
.gitignore vendored
View File

@ -22,5 +22,6 @@ vendor
.glide/
# Binaries
dnscrypt-proxy
dnscrypt-proxy2
dnscrypt-proxy/dnscrypt-proxy2
dnscrypt-proxy/dnscrypt-proxy

83
dnscrypt-proxy/config.go Normal file
View File

@ -0,0 +1,83 @@
package main
import (
"errors"
"fmt"
"log"
"time"
"github.com/BurntSushi/toml"
)
type Config struct {
ServerNames []string `toml:"server_names"`
ListenAddresses []string `toml:"listen_addresses"`
Daemonize bool
ForceTCP bool `toml:"force_tcp"`
Timeout int `toml:"timeout_ms"`
CertRefreshDelay int `toml:"cert_refresh_delay"`
ServersConfig map[string]ServerConfig `toml:"servers"`
}
func newConfig() Config {
return Config{
ListenAddresses: []string{"127.0.0.1:53"},
Timeout: 2500,
CertRefreshDelay: 30,
}
}
type ServerConfig struct {
Stamp string
ProviderName string `toml:"provider_name"`
Address string
PublicKey string `toml:"public_key"`
NoLog bool `toml:"no_log"`
DNSSEC bool `toml:"dnssec"`
}
func ConfigLoad(proxy *Proxy, config_file string) error {
config := newConfig()
if _, err := toml.DecodeFile(config_file, &config); err != nil {
log.Println(err)
return err
}
proxy.timeout = time.Duration(config.Timeout) * time.Millisecond
proxy.mainProto = "udp"
if config.ForceTCP {
proxy.mainProto = "tcp"
}
proxy.certRefreshDelay = time.Duration(config.CertRefreshDelay) * time.Minute
if len(config.ListenAddresses) == 0 {
return errors.New("No local IP/port configured")
}
proxy.listenAddresses = config.ListenAddresses
proxy.daemonize = config.Daemonize
if len(config.ServerNames) == 0 {
for serverName := range config.ServersConfig {
config.ServerNames = append(config.ServerNames, serverName)
}
}
if len(config.ServerNames) == 0 {
return errors.New("No servers configured")
}
for _, serverName := range config.ServerNames {
serverConfig, ok := config.ServersConfig[serverName]
if !ok {
return fmt.Errorf("No definitions found for server [%v]", serverName)
}
var stamp ServerStamp
var err error
if len(serverConfig.Stamp) > 0 {
panic("Stamps are not implemented yet")
} else {
stamp, err = NewServerStampFromLegacy(serverConfig.Address, serverConfig.PublicKey, serverConfig.ProviderName)
if err != nil {
return err
}
}
proxy.registeredServers = append(proxy.registeredServers,
RegisteredServer{name: serverName, stamp: stamp})
}
return nil
}

View File

@ -0,0 +1,27 @@
# dnscrypt-proxy configuration
# List of servers to use
# If this line is commented, all registered servers will be used
server_names = ["dnscrypt.org-fr"]
# List of local addresses and ports to listen to. Can be IPv4 and/or IPv6.
listen_addresses = ["127.0.0.1:53", "[::1]:53"]
# Run the server as a background process
daemonize = false
# Always use TCP to connect to upstream servers
force_tcp = false
# Timeout, in milliseconds
timeout = 2500
# Delay, in minutes, after which certificates are reloaded
cert_refresh_delay = 30
# Static list of available servers
[servers]
[servers."dnscrypt.org-fr"]
provider_name = "2.dnscrypt-cert.fr.dnscrypt.org"
address = "212.47.228.136:443"
public_key = "E801:B84E:A606:BFB0:BAC0:CE43:445B:B15E:BA64:B02F:A3C4:AA31:AE10:636A:0790:324D"

View File

@ -16,39 +16,50 @@ type Proxy struct {
questionSizeEstimator QuestionSizeEstimator
serversInfo ServersInfo
timeout time.Duration
certRefreshDelay time.Duration
mainProto string
listenAddresses []string
daemonize bool
registeredServers []RegisteredServer
}
func main() {
log.SetFlags(0)
stamp, _ := NewServerStampFromLegacy("212.47.228.136:443", "E801:B84E:A606:BFB0:BAC0:CE43:445B:B15E:BA64:B02F:A3C4:AA31:AE10:636A:0790:324D", "2.dnscrypt-cert.fr.dnscrypt.org")
NewProxy("127.0.0.1:5399", "dnscrypt.org-fr", stamp, "udp")
proxy := Proxy{}
if err := ConfigLoad(&proxy, "dnscrypt-proxy.toml"); err != nil {
panic(err)
}
proxy.StartProxy()
}
func NewProxy(listenAddrStr string, serverName string, stamp ServerStamp, mainProto string) {
proxy := Proxy{questionSizeEstimator: NewQuestionSizeEstimator(), timeout: TimeoutMax, mainProto: mainProto}
func (proxy *Proxy) StartProxy() {
proxy.questionSizeEstimator = NewQuestionSizeEstimator()
if _, err := rand.Read(proxy.proxySecretKey[:]); err != nil {
log.Fatal(err)
}
curve25519.ScalarBaseMult(&proxy.proxyPublicKey, &proxy.proxySecretKey)
proxy.serversInfo.registerServer(&proxy, serverName, stamp)
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
if err != nil {
log.Fatal(err)
for _, registeredServer := range proxy.registeredServers {
proxy.serversInfo.registerServer(proxy, registeredServer.name, registeredServer.stamp)
}
listenTCPAddr, err := net.ResolveTCPAddr("tcp", listenAddrStr)
if err != nil {
log.Fatal(err)
for _, listenAddrStr := range proxy.listenAddresses {
listenUDPAddr, err := net.ResolveUDPAddr("udp", listenAddrStr)
if err != nil {
log.Fatal(err)
}
listenTCPAddr, err := net.ResolveTCPAddr("tcp", listenAddrStr)
if err != nil {
log.Fatal(err)
}
if err := proxy.udpListener(listenUDPAddr); err != nil {
log.Fatal(err)
}
if err := proxy.tcpListener(listenTCPAddr); err != nil {
log.Fatal(err)
}
}
go func() {
proxy.udpListener(listenUDPAddr)
}()
go func() {
proxy.tcpListener(listenTCPAddr)
}()
for {
time.Sleep(CertRefreshDelay)
proxy.serversInfo.refresh(&proxy)
proxy.serversInfo.refresh(proxy)
}
}
@ -57,19 +68,22 @@ func (proxy *Proxy) udpListener(listenAddr *net.UDPAddr) error {
if err != nil {
return err
}
defer clientPc.Close()
fmt.Printf("Now listening to %v [UDP]\n", listenAddr)
for {
buffer := make([]byte, MaxDNSPacketSize-1)
length, clientAddr, err := clientPc.ReadFrom(buffer)
if err != nil {
return err
go func() {
defer clientPc.Close()
fmt.Printf("Now listening to %v [UDP]\n", listenAddr)
for {
buffer := make([]byte, MaxDNSPacketSize-1)
length, clientAddr, err := clientPc.ReadFrom(buffer)
if err != nil {
return
}
packet := buffer[:length]
go func() {
proxy.processIncomingQuery(proxy.serversInfo.getOne(), proxy.mainProto, packet, &clientAddr, clientPc)
}()
}
packet := buffer[:length]
go func() {
proxy.processIncomingQuery(proxy.serversInfo.getOne(), proxy.mainProto, packet, &clientAddr, clientPc)
}()
}
}()
return nil
}
func (proxy *Proxy) tcpListener(listenAddr *net.TCPAddr) error {
@ -77,23 +91,26 @@ func (proxy *Proxy) tcpListener(listenAddr *net.TCPAddr) error {
if err != nil {
return err
}
defer acceptPc.Close()
fmt.Printf("Now listening to %v [TCP]\n", listenAddr)
for {
clientPc, err := acceptPc.Accept()
if err != nil {
continue
}
go func() {
defer clientPc.Close()
clientPc.SetDeadline(time.Now().Add(proxy.timeout))
packet, err := ReadPrefixed(clientPc.(*net.TCPConn))
if err != nil || len(packet) < MinDNSPacketSize {
return
go func() {
defer acceptPc.Close()
fmt.Printf("Now listening to %v [TCP]\n", listenAddr)
for {
clientPc, err := acceptPc.Accept()
if err != nil {
continue
}
proxy.processIncomingQuery(proxy.serversInfo.getOne(), "tcp", packet, nil, clientPc)
}()
}
go func() {
defer clientPc.Close()
clientPc.SetDeadline(time.Now().Add(proxy.timeout))
packet, err := ReadPrefixed(clientPc.(*net.TCPConn))
if err != nil || len(packet) < MinDNSPacketSize {
return
}
proxy.processIncomingQuery(proxy.serversInfo.getOne(), "tcp", packet, nil, clientPc)
}()
}
}()
return nil
}
func (proxy *Proxy) exchangeWithUDPServer(serverInfo *ServerInfo, encryptedQuery []byte, clientNonce []byte) ([]byte, error) {