1
0
mirror of https://github.com/fumiama/terasu-cloudflared.git synced 2026-06-06 01:20:24 +08:00

AUTH-2588 add DoH to service mode

This commit is contained in:
Dalton
2020-05-01 10:30:50 -05:00
committed by Dalton Cherry
parent 2c878c47ed
commit 2b7fbbb7b7
11 changed files with 406 additions and 81 deletions

View File

@@ -28,14 +28,16 @@ type FileManager struct {
notifier Notifier
configPath string
logger *logrus.Logger
ReadConfig func(string) (Root, error)
}
// NewFileManager creates a config manager
func NewFileManager(watcher watcher.Notifier, configPath string, logger *logrus.Logger) (Manager, error) {
func NewFileManager(watcher watcher.Notifier, configPath string, logger *logrus.Logger) (*FileManager, error) {
m := &FileManager{
watcher: watcher,
configPath: configPath,
logger: logger,
ReadConfig: readConfigFromPath,
}
err := watcher.Add(configPath)
return m, err
@@ -58,11 +60,20 @@ func (m *FileManager) Start(notifier Notifier) error {
// GetConfig reads the yaml file from the disk
func (m *FileManager) GetConfig() (Root, error) {
if m.configPath == "" {
return m.ReadConfig(m.configPath)
}
// Shutdown stops the watcher
func (m *FileManager) Shutdown() {
m.watcher.Shutdown()
}
func readConfigFromPath(configPath string) (Root, error) {
if configPath == "" {
return Root{}, errors.New("unable to find config file")
}
file, err := os.Open(m.configPath)
file, err := os.Open(configPath)
if err != nil {
return Root{}, err
}
@@ -76,11 +87,6 @@ func (m *FileManager) GetConfig() (Root, error) {
return config, nil
}
// Shutdown stops the watcher
func (m *FileManager) Shutdown() {
m.watcher.Shutdown()
}
// File change notifications from the watcher
// WatcherItemDidChange triggers when the yaml config is updated

View File

@@ -1,15 +1,12 @@
package config
import (
"bufio"
"os"
"testing"
"time"
"github.com/cloudflare/cloudflared/log"
"github.com/cloudflare/cloudflared/watcher"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v2"
)
type mockNotifier struct {
@@ -20,17 +17,27 @@ func (n *mockNotifier) ConfigDidUpdate(c Root) {
n.configs = append(n.configs, c)
}
func writeConfig(t *testing.T, f *os.File, c *Root) {
f.Sync()
b, err := yaml.Marshal(c)
assert.NoError(t, err)
type mockFileWatcher struct {
path string
notifier watcher.Notification
ready chan struct{}
}
w := bufio.NewWriter(f)
_, err = w.Write(b)
assert.NoError(t, err)
func (w *mockFileWatcher) Start(n watcher.Notification) {
w.notifier = n
w.ready <- struct{}{}
}
err = w.Flush()
assert.NoError(t, err)
func (w *mockFileWatcher) Add(string) error {
return nil
}
func (w *mockFileWatcher) Shutdown() {
}
func (w *mockFileWatcher) TriggerChange() {
w.notifier.WatcherItemDidChange(w.path)
}
func TestConfigChanged(t *testing.T) {
@@ -52,22 +59,24 @@ func TestConfigChanged(t *testing.T) {
},
},
}
writeConfig(t, f, c)
configRead := func(configPath string) (Root, error) {
return *c, nil
}
wait := make(chan struct{})
w := &mockFileWatcher{path: filePath, ready: wait}
w, err := watcher.NewFile()
assert.NoError(t, err)
logger := log.CreateLogger()
service, err := NewFileManager(w, filePath, logger)
service.ReadConfig = configRead
assert.NoError(t, err)
n := &mockNotifier{}
go service.Start(n)
<-wait
c.Forwarders = append(c.Forwarders, Forwarder{URL: "add.daltoniam.com", Listener: "127.0.0.1:8081"})
writeConfig(t, f, c)
w.TriggerChange()
// give it time to trigger
time.Sleep(10 * time.Millisecond)
service.Shutdown()
assert.Len(t, n.configs, 2, "did not get 2 config updates as expected")

View File

@@ -4,6 +4,7 @@ import (
"crypto/md5"
"fmt"
"io"
"strings"
)
// Forwarder represents a client side listener to forward traffic to the edge
@@ -19,6 +20,15 @@ type Tunnel struct {
ProtocolType string `json:"type"`
}
// DNSResolver represents a client side DNS resolver
type DNSResolver struct {
Enabled bool `json:"enabled"`
Address string `json:"address"`
Port uint16 `json:"port"`
Upstreams []string `json:"upstreams"`
Bootstraps []string `json:"bootstraps"`
}
// Root is the base options to configure the service
type Root struct {
OrgKey string `json:"org_key"`
@@ -26,6 +36,7 @@ type Root struct {
CheckinInterval int `json:"checkin_interval"`
Forwarders []Forwarder `json:"forwarders,omitempty"`
Tunnels []Tunnel `json:"tunnels,omitempty"`
Resolver DNSResolver `json:"resolver"`
}
// Hash returns the computed values to see if the forwarder values change
@@ -35,3 +46,51 @@ func (f *Forwarder) Hash() string {
io.WriteString(h, f.Listener)
return fmt.Sprintf("%x", h.Sum(nil))
}
// Hash returns the computed values to see if the forwarder values change
func (r *DNSResolver) Hash() string {
h := md5.New()
io.WriteString(h, r.Address)
io.WriteString(h, strings.Join(r.Bootstraps, ","))
io.WriteString(h, strings.Join(r.Upstreams, ","))
io.WriteString(h, fmt.Sprintf("%d", r.Port))
io.WriteString(h, fmt.Sprintf("%v", r.Enabled))
return fmt.Sprintf("%x", h.Sum(nil))
}
// EnabledOrDefault returns the enabled property
func (r *DNSResolver) EnabledOrDefault() bool {
return r.Enabled
}
// AddressOrDefault returns the address or returns the default if empty
func (r *DNSResolver) AddressOrDefault() string {
if r.Address != "" {
return r.Address
}
return "localhost"
}
// PortOrDefault return the port or returns the default if 0
func (r *DNSResolver) PortOrDefault() uint16 {
if r.Port > 0 {
return r.Port
}
return 53
}
// UpstreamsOrDefault returns the upstreams or returns the default if empty
func (r *DNSResolver) UpstreamsOrDefault() []string {
if len(r.Upstreams) > 0 {
return r.Upstreams
}
return []string{"https://1.1.1.1/dns-query", "https://1.0.0.1/dns-query"}
}
// BootstrapsOrDefault returns the bootstraps or returns the default if empty
func (r *DNSResolver) BootstrapsOrDefault() []string {
if len(r.Bootstraps) > 0 {
return r.Bootstraps
}
return []string{"https://162.159.36.1/dns-query", "https://162.159.46.1/dns-query", "https://[2606:4700:4700::1111]/dns-query", "https://[2606:4700:4700::1001]/dns-query"}
}