Adding the ability to do TLS client authentication for DoH (#1203)

* Adding the ability to do TLS client authentication for DoH

* whitespace nit

* Check for server specific creds before wildcard

* small comma ok idiom change
This commit is contained in:
Kevin O'Sullivan 2020-03-09 21:11:53 +00:00 committed by GitHub
parent c2271c8079
commit c040b13d59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 61 additions and 4 deletions

View File

@ -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 {
@ -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
@ -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 {

View File

@ -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' },
# ]

View File

@ -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) {

View File

@ -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
@ -54,6 +59,7 @@ type ServerInfo struct {
rtt ewma.MovingAverage
initialRtt int
useGet bool
DOHClientCreds DOHClientCreds
}
type LBStrategy int
@ -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

View File

@ -59,6 +59,7 @@ type XTransport struct {
tlsCipherSuite []uint16
proxyDialer *netproxy.Dialer
httpProxyFunction func(*http.Request) (*url.URL, error)
tlsClientCreds DOHClientCreds
}
func NewXTransport() *XTransport {
@ -156,10 +157,17 @@ 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)
}
@ -167,8 +175,8 @@ func (xTransport *XTransport) rebuildTransport() {
tlsClientConfig.PreferServerCipherSuites = false
tlsClientConfig.CipherSuites = xTransport.tlsCipherSuite
}
transport.TLSClientConfig = &tlsClientConfig
}
transport.TLSClientConfig = &tlsClientConfig
http2.ConfigureTransport(transport)
xTransport.transport = transport
}