Skip to content

Commit

Permalink
Adding the ability to do TLS client authentication for DoH (#1203)
Browse files Browse the repository at this point in the history
* Adding the ability to do TLS client authentication for DoH

* whitespace nit

* Check for server specific creds before wildcard

* small comma ok idiom change
  • Loading branch information
kev-null committed Mar 9, 2020
1 parent c2271c8 commit c040b13
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
22 changes: 22 additions & 0 deletions dnscrypt-proxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ type Config struct {
BlockedQueryResponse string `toml:"blocked_query_response"`
QueryMeta []string `toml:"query_meta"`
AnonymizedDNS AnonymizedDNSConfig `toml:"anonymized_dns"`
TLSClientAuth TLSClientAuthConfig `toml:"tls_client_auth"`
}

func newConfig() Config {
Expand Down Expand Up @@ -214,6 +215,16 @@ type ServerSummary struct {
Stamp string `json:"stamp"`
}

type TLSClientAuthCredsConfig struct {
ServerName string `toml:"server_name"`
ClientCert string `toml:"client_cert"`
ClientKey string `toml:"client_key"`
}

type TLSClientAuthConfig struct {
Creds []TLSClientAuthCredsConfig `toml:"creds"`
}

type ConfigFlags struct {
List *bool
ListAll *bool
Expand Down Expand Up @@ -472,6 +483,17 @@ func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
}
proxy.routes = &routes
}
configClientCreds := config.TLSClientAuth.Creds
creds := make(map[string]DOHClientCreds)
for _, configClientCred := range configClientCreds {
credFiles := DOHClientCreds{
clientCert: configClientCred.ClientCert,
clientKey: configClientCred.ClientKey,
}
creds[configClientCred.ServerName] = credFiles
}
proxy.dohCreds = &creds

proxy.serversWithBrokenQueryPadding = config.BrokenImplementations.BrokenQueryPadding

if *flags.ListAll {
Expand Down
11 changes: 11 additions & 0 deletions dnscrypt-proxy/example-dnscrypt-proxy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -674,3 +674,14 @@ broken_query_padding = ['cisco', 'cisco-ipv6', 'cisco-familyshield', "quad9-dnsc

# [static.'myserver']
# stamp = 'sdns:AQcAAAAAAAAAAAAQMi5kbnNjcnlwdC1jZXJ0Lg'


################################
# TLS Client Authentication #
################################

[tls_client_auth]

# creds = [
# { server_name='myserver', client_cert='client.crt', client_key='client.key' },
# ]
1 change: 1 addition & 0 deletions dnscrypt-proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type Proxy struct {
routes *map[string][]string
serversWithBrokenQueryPadding []string
showCerts bool
dohCreds *map[string]DOHClientCreds
}

func (proxy *Proxy) addDNSListener(listenAddrStr string) {
Expand Down
15 changes: 15 additions & 0 deletions dnscrypt-proxy/serversInfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ type ServerBugs struct {
incorrectPadding bool
}

type DOHClientCreds struct {
clientCert string
clientKey string
}

type ServerInfo struct {
Proto stamps.StampProtoType
MagicQuery [8]byte
Expand All @@ -54,6 +59,7 @@ type ServerInfo struct {
rtt ewma.MovingAverage
initialRtt int
useGet bool
DOHClientCreds DOHClientCreds
}

type LBStrategy int
Expand Down Expand Up @@ -378,6 +384,15 @@ func fetchDoHServerInfo(proxy *Proxy, name string, stamp stamps.ServerStamp, isN
Path: stamp.Path,
}
body := dohTestPacket(0xcafe)
dohClientCreds, ok := (*proxy.dohCreds)[name]
if !ok {
dohClientCreds, ok = (*proxy.dohCreds)["*"]
}
if ok {
dlog.Noticef("[%s] Cert: %s, Key: %s", name, dohClientCreds.clientCert, dohClientCreds.clientKey)
proxy.xTransport.tlsClientCreds = dohClientCreds
proxy.xTransport.rebuildTransport()
}
useGet := false
if _, _, _, err := proxy.xTransport.DoHQuery(useGet, url, body, proxy.timeout); err != nil {
useGet = true
Expand Down
16 changes: 12 additions & 4 deletions dnscrypt-proxy/xtransport.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type XTransport struct {
tlsCipherSuite []uint16
proxyDialer *netproxy.Dialer
httpProxyFunction func(*http.Request) (*url.URL, error)
tlsClientCreds DOHClientCreds
}

func NewXTransport() *XTransport {
Expand Down Expand Up @@ -156,19 +157,26 @@ func (xTransport *XTransport) rebuildTransport() {
if xTransport.httpProxyFunction != nil {
transport.Proxy = xTransport.httpProxyFunction
}
if xTransport.tlsDisableSessionTickets || xTransport.tlsCipherSuite != nil {
tlsClientConfig := tls.Config{
SessionTicketsDisabled: xTransport.tlsDisableSessionTickets,
tlsClientConfig := tls.Config{}
clientCreds := xTransport.tlsClientCreds
if (clientCreds != DOHClientCreds{}) {
cert, err := tls.LoadX509KeyPair(clientCreds.clientCert, clientCreds.clientKey)
if err != nil {
dlog.Error(err)
}
tlsClientConfig.Certificates = []tls.Certificate{cert}
}
if xTransport.tlsDisableSessionTickets || xTransport.tlsCipherSuite != nil {
tlsClientConfig.SessionTicketsDisabled = xTransport.tlsDisableSessionTickets
if !xTransport.tlsDisableSessionTickets {
tlsClientConfig.ClientSessionCache = tls.NewLRUClientSessionCache(10)
}
if xTransport.tlsCipherSuite != nil {
tlsClientConfig.PreferServerCipherSuites = false
tlsClientConfig.CipherSuites = xTransport.tlsCipherSuite
}
transport.TLSClientConfig = &tlsClientConfig
}
transport.TLSClientConfig = &tlsClientConfig
http2.ConfigureTransport(transport)
xTransport.transport = transport
}
Expand Down

0 comments on commit c040b13

Please sign in to comment.