Pull request 2382: AGDNS-2714-tls-config
Merge in DNS/adguard-home from AGDNS-2714-tls-config to master Squashed commit of the following: commit 073e5ec367db02690e9527602a1da6bfd29321a0 Merge: 18f38c9d44d258972dAuthor: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 16 18:25:23 2025 +0300 Merge branch 'master' into AGDNS-2714-tls-config commit 18f38c9d44337752c6d0f09142658f374de0979f Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Fri Apr 11 15:02:00 2025 +0300 dnsforward: imp docs commit ed56d3c2bc239bdc9af000d847721c4c43d173a3 Merge: 3ef281ea21cc6c00e4Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Apr 10 17:25:08 2025 +0300 Merge branch 'master' into AGDNS-2714-tls-config commit 3ef281ea28dc1fcab0a1291fb3221e6324077a10 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Apr 10 17:24:29 2025 +0300 all: imp docs commit b75f2874a816d4814d218c3b062d532f02e26ca5 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Apr 7 17:16:59 2025 +0300 dnsforward: imp code commit 8ab17b96bca957a172062faaa23b72d5c7ed4d0d Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Fri Apr 4 21:26:37 2025 +0300 all: imp code commit 1abce97b50fe0406dd1ec85b96a0f99b633325cc Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Apr 2 18:22:15 2025 +0300 home: imp code commit debf710f4ebbdfe3e4d2f15b1adcf6b86f8dfc0d Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Apr 1 14:52:21 2025 +0300 home: imp code commit 4aa26f15b721f2a3f32da29b3f664a02bc5a8608 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Tue Apr 1 14:16:16 2025 +0300 all: imp code commit 1a3e72f7a1276f9f797caf9b615f8a552cc9e988 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Mar 31 21:22:40 2025 +0300 all: imp code commit 776ab824aef18ea27b59c02ebfc8620c715a867e Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Mar 27 14:00:33 2025 +0300 home: tls config mu commit 9ebf912f530181043df5c583e82291484996429a Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Mar 26 18:58:47 2025 +0300 all: tls config
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"net/netip"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghalg"
|
||||
@@ -23,6 +24,7 @@ import (
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/AdguardTeam/golibs/netutil"
|
||||
"github.com/AdguardTeam/golibs/timeutil"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/renameio/v2/maybe"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
@@ -263,28 +265,116 @@ type dnsConfig struct {
|
||||
HostsFileEnabled bool `yaml:"hostsfile_enabled"`
|
||||
}
|
||||
|
||||
// tlsConfigSettings is the TLS configuration for DNS-over-TLS, DNS-over-QUIC,
|
||||
// and HTTPS. When adding new properties, update the [tlsConfigSettings.clone]
|
||||
// and [tlsConfigSettings.setPrivateFieldsAndCompare] methods as necessary.
|
||||
type tlsConfigSettings struct {
|
||||
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"` // ForceHTTPS: if true, forces HTTP->HTTPS redirect
|
||||
PortHTTPS uint16 `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
||||
PortDNSOverTLS uint16 `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DoT will be disabled
|
||||
PortDNSOverQUIC uint16 `yaml:"port_dns_over_quic" json:"port_dns_over_quic,omitempty"` // DNS-over-QUIC port. If 0, DoQ will be disabled
|
||||
// Enabled indicates whether encryption (DoT/DoH/HTTPS) is enabled.
|
||||
Enabled bool `yaml:"enabled" json:"enabled"`
|
||||
|
||||
// PortDNSCrypt is the port for DNSCrypt requests. If it's zero,
|
||||
// DNSCrypt is disabled.
|
||||
// ServerName is the hostname of the HTTPS/TLS server.
|
||||
ServerName string `yaml:"server_name" json:"server_name,omitempty"`
|
||||
|
||||
// ForceHTTPS, if true, forces an HTTP to HTTPS redirect.
|
||||
ForceHTTPS bool `yaml:"force_https" json:"force_https"`
|
||||
|
||||
// PortHTTPS is the HTTPS port. If 0, HTTPS will be disabled.
|
||||
PortHTTPS uint16 `yaml:"port_https" json:"port_https,omitempty"`
|
||||
|
||||
// PortDNSOverTLS is the DNS-over-TLS port. If 0, DoT will be disabled.
|
||||
PortDNSOverTLS uint16 `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"`
|
||||
|
||||
// PortDNSOverQUIC is the DNS-over-QUIC port. If 0, DoQ will be disabled.
|
||||
PortDNSOverQUIC uint16 `yaml:"port_dns_over_quic" json:"port_dns_over_quic,omitempty"`
|
||||
|
||||
// PortDNSCrypt is the port for DNSCrypt requests. If it's zero, DNSCrypt
|
||||
// is disabled.
|
||||
PortDNSCrypt uint16 `yaml:"port_dnscrypt" json:"port_dnscrypt"`
|
||||
// DNSCryptConfigFile is the path to the DNSCrypt config file. Must be
|
||||
// set if PortDNSCrypt is not zero.
|
||||
|
||||
// DNSCryptConfigFile is the path to the DNSCrypt config file. Must be set
|
||||
// if PortDNSCrypt is not zero.
|
||||
//
|
||||
// See https://github.com/AdguardTeam/dnsproxy and
|
||||
// https://github.com/ameshkov/dnscrypt.
|
||||
DNSCryptConfigFile string `yaml:"dnscrypt_config_file" json:"dnscrypt_config_file"`
|
||||
|
||||
// Allow DoH queries via unencrypted HTTP (e.g. for reverse proxying)
|
||||
// AllowUnencryptedDoH allows DoH queries via unencrypted HTTP (e.g. for
|
||||
// reverse proxying).
|
||||
//
|
||||
// TODO(s.chzhen): Add this option into the Web UI.
|
||||
AllowUnencryptedDoH bool `yaml:"allow_unencrypted_doh" json:"allow_unencrypted_doh"`
|
||||
|
||||
dnsforward.TLSConfig `yaml:",inline" json:",inline"`
|
||||
// CertificateChain is the PEM-encoded certificate chain. Must be empty if
|
||||
// [tlsConfigSettings.CertificatePath] is provided.
|
||||
CertificateChain string `yaml:"certificate_chain" json:"certificate_chain"`
|
||||
|
||||
// PrivateKey is the PEM-encoded private key. Must be empty if
|
||||
// [tlsConfigSettings.PrivateKeyPath] is provided.
|
||||
PrivateKey string `yaml:"private_key" json:"private_key"`
|
||||
|
||||
// CertificatePath is the path to the certificate file. Must be empty if
|
||||
// [tlsConfigSettings.CertificateChain] is provided.
|
||||
CertificatePath string `yaml:"certificate_path" json:"certificate_path"`
|
||||
|
||||
// PrivateKeyPath is the path to the private key file. Must be empty if
|
||||
// [tlsConfigSettings.PrivateKey] is provided.
|
||||
PrivateKeyPath string `yaml:"private_key_path" json:"private_key_path"`
|
||||
|
||||
// OverrideTLSCiphers, when set, contains the names of the cipher suites to
|
||||
// use. If the slice is empty, the default safe suites are used.
|
||||
OverrideTLSCiphers []string `yaml:"override_tls_ciphers,omitempty" json:"-"`
|
||||
|
||||
// CertificateChainData is the PEM-encoded byte data for the certificate
|
||||
// chain.
|
||||
CertificateChainData []byte `yaml:"-" json:"-"`
|
||||
|
||||
// PrivateKeyData is the PEM-encoded byte data for the private key.
|
||||
PrivateKeyData []byte `yaml:"-" json:"-"`
|
||||
|
||||
// StrictSNICheck controls if the connections with SNI mismatching the
|
||||
// certificate's ones should be rejected.
|
||||
StrictSNICheck bool `yaml:"strict_sni_check" json:"-"`
|
||||
}
|
||||
|
||||
// clone returns a deep copy of c.
|
||||
func (c *tlsConfigSettings) clone() (clone *tlsConfigSettings) {
|
||||
clone = &tlsConfigSettings{}
|
||||
*clone = *c
|
||||
|
||||
clone.OverrideTLSCiphers = slices.Clone(c.OverrideTLSCiphers)
|
||||
clone.CertificateChainData = slices.Clone(c.CertificateChainData)
|
||||
clone.PrivateKeyData = slices.Clone(c.PrivateKeyData)
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
// setPrivateFieldsAndCompare sets any missing properties in conf to match those
|
||||
// in c and returns true if TLS configurations are equal. conf must not be be
|
||||
// nil.
|
||||
// It sets the following properties because these are not accepted from the
|
||||
// frontend:
|
||||
//
|
||||
// [tlsConfigSettings.AllowUnencryptedDoH]
|
||||
// [tlsConfigSettings.DNSCryptConfigFile]
|
||||
// [tlsConfigSettings.OverrideTLSCiphers]
|
||||
// [tlsConfigSettings.PortDNSCrypt]
|
||||
//
|
||||
// The following properties are skipped as they are set by
|
||||
// [tlsManager.loadTLSConfig]:
|
||||
//
|
||||
// [tlsConfigSettings.CertificateChainData]
|
||||
// [tlsConfigSettings.PrivateKeyData]
|
||||
func (c *tlsConfigSettings) setPrivateFieldsAndCompare(conf *tlsConfigSettings) (equal bool) {
|
||||
conf.OverrideTLSCiphers = slices.Clone(c.OverrideTLSCiphers)
|
||||
|
||||
// TODO(s.chzhen): Remove this once the frontend supports it.
|
||||
conf.AllowUnencryptedDoH = c.AllowUnencryptedDoH
|
||||
|
||||
conf.DNSCryptConfigFile = c.DNSCryptConfigFile
|
||||
conf.PortDNSCrypt = c.PortDNSCrypt
|
||||
|
||||
// TODO(a.garipov): Define a custom comparer.
|
||||
return cmp.Equal(c, conf)
|
||||
}
|
||||
|
||||
type queryLogConfig struct {
|
||||
@@ -649,9 +739,8 @@ func (c *configuration) write(tlsMgr *tlsManager) (err error) {
|
||||
}
|
||||
|
||||
if tlsMgr != nil {
|
||||
tlsConf := tlsConfigSettings{}
|
||||
tlsMgr.WriteDiskConfig(&tlsConf)
|
||||
config.TLS = tlsConf
|
||||
tlsConf := tlsMgr.config()
|
||||
config.TLS = *tlsConf
|
||||
}
|
||||
|
||||
if globalContext.stats != nil {
|
||||
|
||||
Reference in New Issue
Block a user