Merge: + DNS: TLS handshake: terminate handshake on bad SNI
Close #1014 Squashed commit of the following: commit 759248efc0587ff2f288996c47739e602c557a76 Author: Simon Zolin <s.zolin@adguard.com> Date: Thu Dec 12 19:26:46 2019 +0300 support empty ServerName commit 68afecd5eca5ae66262b12dcb414b50efe88dc02 Author: Simon Zolin <s.zolin@adguard.com> Date: Wed Dec 11 14:40:22 2019 +0300 + DNS: TLS handshake: terminate handshake on bad SNI
This commit is contained in:
parent
aa202277fb
commit
c8c76ae12b
|
@ -147,14 +147,16 @@ type FilteringConfig struct {
|
||||||
// TLSConfig is the TLS configuration for HTTPS, DNS-over-HTTPS, and DNS-over-TLS
|
// TLSConfig is the TLS configuration for HTTPS, DNS-over-HTTPS, and DNS-over-TLS
|
||||||
type TLSConfig struct {
|
type TLSConfig struct {
|
||||||
TLSListenAddr *net.TCPAddr `yaml:"-" json:"-"`
|
TLSListenAddr *net.TCPAddr `yaml:"-" json:"-"`
|
||||||
|
ServerName string `yaml:"server_name" json:"server_name,omitempty"` // ServerName is the hostname of your HTTPS/TLS server
|
||||||
CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"` // PEM-encoded certificates chain
|
CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"` // PEM-encoded certificates chain
|
||||||
PrivateKey string `yaml:"private_key" json:"private_key"` // PEM-encoded private key
|
PrivateKey string `yaml:"private_key" json:"private_key"` // PEM-encoded private key
|
||||||
|
|
||||||
CertificatePath string `yaml:"certificate_path" json:"certificate_path"` // certificate file name
|
CertificatePath string `yaml:"certificate_path" json:"certificate_path"` // certificate file name
|
||||||
PrivateKeyPath string `yaml:"private_key_path" json:"private_key_path"` // private key file name
|
PrivateKeyPath string `yaml:"private_key_path" json:"private_key_path"` // private key file name
|
||||||
|
|
||||||
CertificateChainData []byte `yaml:"-" json:"-"`
|
CertificateChainData []byte `yaml:"-" json:"-"`
|
||||||
PrivateKeyData []byte `yaml:"-" json:"-"`
|
PrivateKeyData []byte `yaml:"-" json:"-"`
|
||||||
|
Cert tls.Certificate `yaml:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerConfig represents server configuration.
|
// ServerConfig represents server configuration.
|
||||||
|
@ -294,13 +296,13 @@ func (s *Server) Prepare(config *ServerConfig) error {
|
||||||
|
|
||||||
if s.conf.TLSListenAddr != nil && len(s.conf.CertificateChainData) != 0 && len(s.conf.PrivateKeyData) != 0 {
|
if s.conf.TLSListenAddr != nil && len(s.conf.CertificateChainData) != 0 && len(s.conf.PrivateKeyData) != 0 {
|
||||||
proxyConfig.TLSListenAddr = s.conf.TLSListenAddr
|
proxyConfig.TLSListenAddr = s.conf.TLSListenAddr
|
||||||
keypair, err := tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
|
s.conf.Cert, err = tls.X509KeyPair(s.conf.CertificateChainData, s.conf.PrivateKeyData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorx.Decorate(err, "Failed to parse TLS keypair")
|
return errorx.Decorate(err, "Failed to parse TLS keypair")
|
||||||
}
|
}
|
||||||
proxyConfig.TLSConfig = &tls.Config{
|
proxyConfig.TLSConfig = &tls.Config{
|
||||||
Certificates: []tls.Certificate{keypair},
|
GetCertificate: s.onGetCertificate,
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,6 +320,16 @@ func (s *Server) Prepare(config *ServerConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by 'tls' package when Client Hello is received
|
||||||
|
// If the server name (from SNI) supplied by client is incorrect - we terminate the ongoing TLS handshake.
|
||||||
|
func (s *Server) onGetCertificate(ch *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
|
if len(s.conf.ServerName) != 0 && ch.ServerName != s.conf.ServerName {
|
||||||
|
log.Info("DNS: TLS: unknown SNI in Client Hello: %s", ch.ServerName)
|
||||||
|
return nil, fmt.Errorf("Invalid SNI")
|
||||||
|
}
|
||||||
|
return &s.conf.Cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Stop stops the DNS server
|
// Stop stops the DNS server
|
||||||
func (s *Server) Stop() error {
|
func (s *Server) Stop() error {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
|
|
|
@ -111,11 +111,10 @@ type dnsConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type tlsConfigSettings struct {
|
type tlsConfigSettings struct {
|
||||||
Enabled bool `yaml:"enabled" json:"enabled"` // Enabled is the encryption (DOT/DOH/HTTPS) status
|
Enabled bool `yaml:"enabled" json:"enabled"` // Enabled is the encryption (DOT/DOH/HTTPS) status
|
||||||
ServerName string `yaml:"server_name" json:"server_name,omitempty"` // ServerName is the hostname of your HTTPS/TLS server
|
ForceHTTPS bool `yaml:"force_https" json:"force_https,omitempty"` // ForceHTTPS: if true, forces HTTP->HTTPS redirect
|
||||||
ForceHTTPS bool `yaml:"force_https" json:"force_https,omitempty"` // ForceHTTPS: if true, forces HTTP->HTTPS redirect
|
PortHTTPS int `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
||||||
PortHTTPS int `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
PortDNSOverTLS int `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DOT will be disabled
|
||||||
PortDNSOverTLS int `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DOT will be disabled
|
|
||||||
|
|
||||||
dnsforward.TLSConfig `yaml:",inline" json:",inline"`
|
dnsforward.TLSConfig `yaml:",inline" json:",inline"`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue