Skip to content

Commit

Permalink
Merge: + DNS, Web: Entware: use special directory with the system roo…
Browse files Browse the repository at this point in the history
…t certificates

Close #1311

* commit '0e030154ee4f73d0c1a8e9d092b12be78b0a0ea5':
  - fix tests
  + DNS, Web: Entware: use special directory with the system root certificates
  • Loading branch information
szolin committed Mar 17, 2020
2 parents b345595 + 0e03015 commit 5f328d2
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 10 deletions.
3 changes: 3 additions & 0 deletions dnsforward/dnsforward.go
Expand Up @@ -180,6 +180,8 @@ type ServerConfig struct {
FilteringConfig
TLSConfig

TLSv12Roots *x509.CertPool // list of root CAs for TLSv1.2

// Called when the configuration is changed by HTTP request
ConfigModified func()

Expand Down Expand Up @@ -338,6 +340,7 @@ func (s *Server) Prepare(config *ServerConfig) error {
MinVersion: tls.VersionTLS12,
}
}
upstream.RootCAs = s.conf.TLSv12Roots

if len(proxyConfig.Upstreams) == 0 {
log.Fatal("len(proxyConfig.Upstreams) == 0")
Expand Down
1 change: 1 addition & 0 deletions home/control_tls.go
Expand Up @@ -200,6 +200,7 @@ func verifyCertChain(data *tlsConfigStatus, certChain string, serverName string)

opts := x509.VerifyOptions{
DNSName: serverName,
Roots: Context.tlsRoots,
}

log.Printf("number of certs - %d", len(parsedCerts))
Expand Down
1 change: 1 addition & 0 deletions home/dns.go
Expand Up @@ -175,6 +175,7 @@ func generateServerConfig() dnsforward.ServerConfig {
newconfig.TLSListenAddr = &net.TCPAddr{IP: net.ParseIP(config.DNS.BindHost), Port: config.TLS.PortDNSOverTLS}
}
}
newconfig.TLSv12Roots = Context.tlsRoots

newconfig.FilterHandler = applyAdditionalFiltering
newconfig.GetUpstreamsByClient = getUpstreamsByClient
Expand Down
26 changes: 16 additions & 10 deletions home/home.go
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -78,6 +79,7 @@ type homeContext struct {
pidFileName string // PID file name. Empty if no PID file was created.
disableUpdate bool // If set, don't check for updates
controlLock sync.Mutex
tlsRoots *x509.CertPool // list of root CAs for TLSv1.2
transport *http.Transport
client *http.Client
appSignalChannel chan os.Signal // Channel for receiving OS signals by the console app
Expand Down Expand Up @@ -135,16 +137,6 @@ func run(args options) {
Context.configFilename = "AdGuardHome.yaml"
}

// Init some of the Context fields right away
Context.transport = &http.Transport{
DialContext: customDialContext,
Proxy: getHTTPProxy,
}
Context.client = &http.Client{
Timeout: time.Minute * 5,
Transport: Context.transport,
}

// configure working dir and config path
initWorkingDir(args)

Expand Down Expand Up @@ -172,6 +164,19 @@ func run(args options) {
initConfig()
initServices()

Context.tlsRoots = util.LoadSystemRootCAs()
Context.transport = &http.Transport{
DialContext: customDialContext,
Proxy: getHTTPProxy,
TLSClientConfig: &tls.Config{
RootCAs: Context.tlsRoots,
},
}
Context.client = &http.Client{
Timeout: time.Minute * 5,
Transport: Context.transport,
}

if !Context.firstRun {
// Do the upgrade if necessary
err := upgradeConfig()
Expand Down Expand Up @@ -321,6 +326,7 @@ func httpServerLoop() {
TLSConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS12,
RootCAs: Context.tlsRoots,
},
}

Expand Down
1 change: 1 addition & 0 deletions home/home_test.go
Expand Up @@ -112,6 +112,7 @@ func TestHome(t *testing.T) {

dir := prepareTestDir()
defer func() { _ = os.RemoveAll(dir) }()
_ = os.MkdirAll(filepath.Join(Context.getDataDir(), filterDir), 0755)
fn := filepath.Join(dir, "AdGuardHome.yaml")

assert.True(t, ioutil.WriteFile(fn, []byte(yamlConf), 0644) == nil)
Expand Down
47 changes: 47 additions & 0 deletions util/tls.go
@@ -0,0 +1,47 @@
package util

import (
"crypto/x509"
"io/ioutil"
"os"
"runtime"

"github.com/AdguardTeam/golibs/log"
)

// LoadSystemRootCAs - load root CAs from the system
// Return the x509 certificate pool object
// Return nil if nothing has been found.
// This means that Go.crypto will use its default algorithm to find system root CA list.
// https://github.com/AdguardTeam/AdGuardHome/issues/1311
func LoadSystemRootCAs() *x509.CertPool {
if runtime.GOOS != "linux" {
return nil
}

// Directories with the system root certificates, that aren't supported by Go.crypto
dirs := []string{
"/opt/etc/ssl/certs", // Entware
}
roots := x509.NewCertPool()
for _, dir := range dirs {
fis, err := ioutil.ReadDir(dir)
if err != nil {
if !os.IsNotExist(err) {
log.Error("Opening directory: %s: %s", dir, err)
}
continue
}
rootsAdded := false
for _, fi := range fis {
data, err := ioutil.ReadFile(dir + "/" + fi.Name())
if err == nil && roots.AppendCertsFromPEM(data) {
rootsAdded = true
}
}
if rootsAdded {
return roots
}
}
return nil
}

1 comment on commit 5f328d2

@ryzhovau
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, guys! @Entware team really appriciate that!

Please sign in to comment.