From: Sergey Matveev <stargrave@stargrave.org>
Date: Sat, 11 Sep 2021 12:17:31 +0000 (+0300)
Subject: Ability to dynamically control list of spying domains
X-Git-Tag: v0.1.0~67
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=2df541457d24653f0fb789bfdc8de828c03f4f6c;p=tofuproxy.git

Ability to dynamically control list of spying domains
---

diff --git a/caches/caches.go b/caches/caches.go
index f451da4..39dfd34 100644
--- a/caches/caches.go
+++ b/caches/caches.go
@@ -17,4 +17,7 @@ var (
 
 	TLSAuthCache  = make(map[string]*tls.Certificate)
 	TLSAuthCacheM sync.RWMutex
+
+	Spies  = make([]string, 0)
+	SpiesM sync.RWMutex
 )
diff --git a/doc/usage.texi b/doc/usage.texi
index 8942839..eb88636 100644
--- a/doc/usage.texi
+++ b/doc/usage.texi
@@ -52,6 +52,13 @@ main.go:70: listening: [::1]:8080 dns: [::1]:53 certs: ./certs ccerts: ./ccerts
 If you want to use TLS client certificates, then place them to
 @file{-ccerts} directory.
 
+@item
+Load spying domains to reject to with:
+
+@example
+$ cat spies.txt > fifos/add-spies
+@end example
+
 @item Watch logs:
 
 @example
diff --git a/fifos/ensure.do b/fifos/ensure.do
index 5e5cc7e..6af361f 100644
--- a/fifos/ensure.do
+++ b/fifos/ensure.do
@@ -1,7 +1,8 @@
 for f in cert dane err http-auth non-ok ok redir req tls tls-auth various ; do
     [ -p log-$f ] || mkfifo log-$f
 done
-for f in accepted http-auth rejected tls-auth ; do
+for f in accepted http-auth rejected spies tls-auth ; do
     [ -p list-$f ] || mkfifo list-$f
     [ -p del-$f ] || mkfifo del-$f
 done
+[ -p add-spies ] || mkfifo add-spies
diff --git a/fifos/spies.go b/fifos/spies.go
new file mode 100644
index 0000000..0b6aa57
--- /dev/null
+++ b/fifos/spies.go
@@ -0,0 +1,73 @@
+/*
+tofuproxy -- HTTP proxy with TLS certificates management
+Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package fifos
+
+import (
+	"bufio"
+	"log"
+	"os"
+
+	"go.stargrave.org/tofuproxy/caches"
+)
+
+func listSpies(p string) {
+	for {
+		fd, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+		if err != nil {
+			log.Fatalln(err)
+		}
+		caches.SpiesM.RLock()
+		for _, spy := range caches.Spies {
+			if _, err = fd.WriteString(spy + "\n"); err != nil {
+				break
+			}
+		}
+		caches.SpiesM.RUnlock()
+		fd.Close()
+	}
+}
+
+func addSpy(p string) {
+	for {
+		fd, err := os.OpenFile(p, os.O_RDONLY, os.FileMode(0666))
+		if err != nil {
+			log.Fatalln(err)
+		}
+		hosts := make(map[string]struct{})
+		scanner := bufio.NewScanner(fd)
+		for scanner.Scan() {
+			t := scanner.Text()
+			if len(t) > 0 {
+				hosts[t] = struct{}{}
+			}
+		}
+		fd.Close()
+		for host := range hosts {
+			log.Printf("%s: adding host %s\n", p, host)
+		}
+		caches.SpiesM.Lock()
+		for _, spy := range caches.Spies {
+			hosts[spy] = struct{}{}
+		}
+		caches.Spies = caches.Spies[:0]
+		for host := range hosts {
+			caches.Spies = append(caches.Spies, host)
+		}
+		caches.SpiesM.Unlock()
+	}
+}
diff --git a/fifos/start.go b/fifos/start.go
index f37abe6..a005c64 100644
--- a/fifos/start.go
+++ b/fifos/start.go
@@ -22,6 +22,7 @@ func Start(fifos string) {
 	go listAccepted(filepath.Join(fifos, "list-accepted"))
 	go listHTTPAuth(filepath.Join(fifos, "list-http-auth"))
 	go listRejected(filepath.Join(fifos, "list-rejected"))
+	go listSpies(filepath.Join(fifos, "list-spies"))
 	go listTLSAuth(filepath.Join(fifos, "list-tls-auth"))
 
 	go del(
@@ -40,4 +41,18 @@ func Start(fifos string) {
 		&caches.TLSAuthCacheM, func(host string) { delete(caches.TLSAuthCache, host) },
 		filepath.Join(fifos, "del-tls-auth"),
 	)
+
+	go addSpy(filepath.Join(fifos, "add-spies"))
+	go del(
+		&caches.SpiesM, func(host string) {
+			for i, spy := range caches.Spies {
+				if spy == host {
+					caches.Spies[i] = caches.Spies[len(caches.Spies)-1]
+					caches.Spies = caches.Spies[:len(caches.Spies)-1]
+					return
+				}
+			}
+		},
+		filepath.Join(fifos, "del-spies"),
+	)
 }
diff --git a/rounds/spy.go b/rounds/spy.go
index cb12480..e830701 100644
--- a/rounds/spy.go
+++ b/rounds/spy.go
@@ -22,31 +22,14 @@ import (
 	"net/http"
 	"strings"
 
+	"go.stargrave.org/tofuproxy/caches"
 	"go.stargrave.org/tofuproxy/fifos"
 )
 
-var spyDomains = []string{
-	"google-analytics.com",
-	"goo.gl",
-	"ads.google.com",
-	"googletagmanager.com",
-	"facebook.com",
-	"facebook.net",
-	"fbcdn.com",
-	"fbcdn.net",
-	"advertising.yandex.ru",
-	"an.yandex.ru",
-	"awaps.yandex.ru",
-	"bs.yandex.ru",
-	"informer.yandex.ru",
-	"mc.yandex.ru",
-	"metrika.yandex.ru",
-	"doubleclick.net",
-	"tns-counter.ru",
-}
-
 func IsSpy(host string) bool {
-	for _, spy := range spyDomains {
+	caches.SpiesM.RLock()
+	defer caches.SpiesM.RUnlock()
+	for _, spy := range caches.Spies {
 		if strings.HasSuffix(host, spy) {
 			return true
 		}
diff --git a/spies.txt b/spies.txt
new file mode 100644
index 0000000..73887a3
--- /dev/null
+++ b/spies.txt
@@ -0,0 +1,18 @@
+google-analytics.com
+goo.gl
+ads.google.com
+googletagmanager.com
+facebook.com
+facebook.net
+fbcdn.com
+fbcdn.net
+advertising.yandex.ru
+an.yandex.ru
+awaps.yandex.ru
+bs.yandex.ru
+informer.yandex.ru
+mc.yandex.ru
+metrika.yandex.ru
+doubleclick.net
+tns-counter.ru
+counter.rambler.ru