diff options
author | Fernando Barillas | 2018-07-19 23:04:53 -0700 |
---|---|---|
committer | Fernando Barillas | 2018-07-20 21:12:20 -0700 |
commit | ee4f051b612385236836d44c2ecad55a794d4efa (patch) | |
tree | c3ee7abfaef2082a305fdfd592879165983815c7 | |
parent | 54c974631fdc6c638a6f097e5d32e3d83a2e804d (diff) | |
download | aur-ee4f051b612385236836d44c2ecad55a794d4efa.tar.gz |
Disable telemetry collection
-rw-r--r-- | .SRCINFO | 10 | ||||
-rw-r--r-- | 01-disable-telemetry.patch | 291 | ||||
-rw-r--r-- | 02-disable-telemetry-collection.patch | 266 | ||||
-rw-r--r-- | PKGBUILD | 24 |
4 files changed, 583 insertions, 8 deletions
@@ -1,4 +1,4 @@ -pkgbase = caddy +pkgbase = caddy-no-telemetry pkgdesc = HTTP/2 Web Server with Automatic HTTPS pkgver = 0.11.0 pkgrel = 1 @@ -12,6 +12,8 @@ pkgbase = caddy license = Apache makedepends = go>=1.8.1 makedepends = git + provides = caddy + conflicts = caddy backup = etc/caddy/caddy.conf source = https://github.com/mholt/caddy/archive/v0.11.0/caddy-0.11.0.tar.gz source = https://caddyserver.com/resources/images/brand/caddy-at-your-service-white.svg @@ -20,6 +22,8 @@ pkgbase = caddy source = caddy.tmpfiles source = caddy.conf source = plugins.go + source = 01-disable-telemetry.patch + source = 02-disable-telemetry-collection.patch sha256sums = 81e593d258460a9f5c6b5a5f46890a08b6b1ce15f5c0fc7bcaf09826368c3a1a sha256sums = e679dd79fd92dc351fc190c7af529c73e3896986aaa6b7c0ae01e561398d6b85 sha256sums = 6db7aec45e95bbbf770ce4d120a60d8e4992d2262a8ebf668521179279aa5ae7 @@ -27,6 +31,8 @@ pkgbase = caddy sha256sums = c8f002f5ba59985a643600dc3c871e18e110903aa945ef3f2da7c9edd39fbd7a sha256sums = 80520b80ccabf077a3269f6a1bf55faa3811ef5adce115131b35ef2044d37b64 sha256sums = f5a0fbb961e7c9ecf99e88d0959a3164cbea54660c1c08c3ba3cdf1d45563929 + sha256sums = 1e6fcfb06704babdf5a5fea52d94bb9055182f48114999662c449d3cc3090cab + sha256sums = 4fe4cc982322e7eec8ff187c22ff8a58db8a894da8aba038697e15a49b36fc52 -pkgname = caddy +pkgname = caddy-no-telemetry diff --git a/01-disable-telemetry.patch b/01-disable-telemetry.patch new file mode 100644 index 000000000000..d4dd1e82eeee --- /dev/null +++ b/01-disable-telemetry.patch @@ -0,0 +1,291 @@ +diff --git a/telemetry/telemetry.go b/telemetry/telemetry.go +index 59ab75b..dad7216 100644 +--- a/telemetry/telemetry.go ++++ b/telemetry/telemetry.go +@@ -33,16 +33,7 @@ + package telemetry + + import ( +- "bytes" +- "encoding/json" +- "fmt" +- "io/ioutil" +- "log" +- "math/rand" + "net/http" +- "runtime" +- "strconv" +- "strings" + "sync" + "time" + +@@ -52,10 +43,6 @@ import ( + // logEmit calls emit and then logs the error, if any. + // See docs for emit. + func logEmit(final bool) { +- err := emit(final) +- if err != nil { +- log.Printf("[ERROR] Sending telemetry: %v", err) +- } + } + + // emit sends an update to the telemetry server. +@@ -63,184 +50,15 @@ func logEmit(final bool) { + // If final is true, no future updates will be scheduled. + // Otherwise, the next update will be scheduled. + func emit(final bool) error { +- if !enabled { +- return fmt.Errorf("telemetry not enabled") +- } +- +- // some metrics are updated/set at time of emission +- setEmitTimeMetrics() +- +- // ensure only one update happens at a time; +- // skip update if previous one still in progress +- updateMu.Lock() +- if updating { +- updateMu.Unlock() +- log.Println("[NOTICE] Skipping this telemetry update because previous one is still working") +- return nil +- } +- updating = true +- updateMu.Unlock() +- defer func() { +- updateMu.Lock() +- updating = false +- updateMu.Unlock() +- }() +- +- // terminate any pending update if this is the last one +- if final { +- stopUpdateTimer() +- } +- +- payloadBytes, err := makePayloadAndResetBuffer() +- if err != nil { +- return err +- } +- +- // this will hold the server's reply +- var reply Response +- +- // transmit the payload - use a loop to retry in case of failure +- for i := 0; i < 4; i++ { +- if i > 0 && err != nil { +- // don't hammer the server; first failure might have been +- // a fluke, but back off more after that +- log.Printf("[WARNING] Sending telemetry (attempt %d): %v - backing off and retrying", i, err) +- time.Sleep(time.Duration((i+1)*(i+1)*(i+1)) * time.Second) +- } +- +- // send it +- var resp *http.Response +- resp, err = httpClient.Post(endpoint+instanceUUID.String(), "application/json", bytes.NewReader(payloadBytes)) +- if err != nil { +- continue +- } +- +- // check for any special-case response codes +- if resp.StatusCode == http.StatusGone { +- // the endpoint has been deprecated and is no longer servicing clients +- err = fmt.Errorf("telemetry server replied with HTTP %d; upgrade required", resp.StatusCode) +- if clen := resp.Header.Get("Content-Length"); clen != "0" && clen != "" { +- bodyBytes, readErr := ioutil.ReadAll(resp.Body) +- if readErr != nil { +- log.Printf("[ERROR] Reading response body from server: %v", readErr) +- } +- err = fmt.Errorf("%v - %s", err, bodyBytes) +- } +- resp.Body.Close() +- reply.Stop = true +- break +- } +- if resp.StatusCode == http.StatusUnavailableForLegalReasons { +- // the endpoint is unavailable, at least to this client, for legal reasons (!) +- err = fmt.Errorf("telemetry server replied with HTTP %d %s: please consult the project website and developers for guidance", resp.StatusCode, resp.Status) +- if clen := resp.Header.Get("Content-Length"); clen != "0" && clen != "" { +- bodyBytes, readErr := ioutil.ReadAll(resp.Body) +- if readErr != nil { +- log.Printf("[ERROR] Reading response body from server: %v", readErr) +- } +- err = fmt.Errorf("%v - %s", err, bodyBytes) +- } +- resp.Body.Close() +- reply.Stop = true +- break +- } +- +- // okay, ensure we can interpret the response +- if ct := resp.Header.Get("Content-Type"); (resp.StatusCode < 300 || resp.StatusCode >= 400) && +- !strings.Contains(ct, "json") { +- err = fmt.Errorf("telemetry server replied with unknown content-type: '%s' and HTTP %s", ct, resp.Status) +- resp.Body.Close() +- continue +- } +- +- // read the response body +- err = json.NewDecoder(resp.Body).Decode(&reply) +- resp.Body.Close() // close response body as soon as we're done with it +- if err != nil { +- continue +- } +- +- // update the list of enabled/disabled keys, if any +- for _, key := range reply.EnableKeys { +- disabledMetricsMu.Lock() +- // only re-enable this metric if it is temporarily disabled +- if temp, ok := disabledMetrics[key]; ok && temp { +- delete(disabledMetrics, key) +- } +- disabledMetricsMu.Unlock() +- } +- for _, key := range reply.DisableKeys { +- disabledMetricsMu.Lock() +- disabledMetrics[key] = true // all remotely-disabled keys are "temporarily" disabled +- disabledMetricsMu.Unlock() +- } +- +- // make sure we didn't send the update too soon; if so, +- // just wait and try again -- this is a special case of +- // error that we handle differently, as you can see +- if resp.StatusCode == http.StatusTooManyRequests { +- if reply.NextUpdate <= 0 { +- raStr := resp.Header.Get("Retry-After") +- if ra, err := strconv.Atoi(raStr); err == nil { +- reply.NextUpdate = time.Duration(ra) * time.Second +- } +- } +- if !final { +- log.Printf("[NOTICE] Sending telemetry: we were too early; waiting %s before trying again", reply.NextUpdate) +- time.Sleep(reply.NextUpdate) +- continue +- } +- } else if resp.StatusCode >= 400 { +- err = fmt.Errorf("telemetry server returned status code %d", resp.StatusCode) +- continue +- } +- +- break +- } +- if err == nil && !final { +- // (remember, if there was an error, we return it +- // below, so it WILL get logged if it's supposed to) +- log.Println("[INFO] Sending telemetry: success") +- } +- +- // even if there was an error after all retries, we should +- // schedule the next update using our default update +- // interval because the server might be healthy later +- +- // ensure we won't slam the telemetry server; add a little variance +- if reply.NextUpdate < 1*time.Second { +- reply.NextUpdate = defaultUpdateInterval + time.Duration(rand.Int63n(int64(1*time.Minute))) +- } +- +- // schedule the next update (if this wasn't the last one and +- // if the remote server didn't tell us to stop sending) +- if !final && !reply.Stop { +- updateTimerMu.Lock() +- updateTimer = time.AfterFunc(reply.NextUpdate, func() { +- logEmit(false) +- }) +- updateTimerMu.Unlock() +- } +- +- return err ++ return nil + } + + func stopUpdateTimer() { +- updateTimerMu.Lock() +- updateTimer.Stop() +- updateTimer = nil +- updateTimerMu.Unlock() + } + + // setEmitTimeMetrics sets some metrics that should + // be recorded just before emitting. + func setEmitTimeMetrics() { +- Set("goroutines", runtime.NumGoroutine()) +- +- var mem runtime.MemStats +- runtime.ReadMemStats(&mem) +- SetNested("memory", "heap_alloc", mem.HeapAlloc) +- SetNested("memory", "sys", mem.Sys) + } + + // makePayloadAndResetBuffer prepares a payload +@@ -250,15 +68,7 @@ func setEmitTimeMetrics() { + // resulting byte slice is lost, the payload is + // gone with it. + func makePayloadAndResetBuffer() ([]byte, error) { +- bufCopy := resetBuffer() +- +- // encode payload in preparation for transmission +- payload := Payload{ +- InstanceID: instanceUUID.String(), +- Timestamp: time.Now().UTC(), +- Data: bufCopy, +- } +- return json.Marshal(payload) ++ return []byte{}, nil + } + + // resetBuffer makes a local pointer to the buffer, +@@ -268,12 +78,7 @@ func makePayloadAndResetBuffer() ([]byte, error) { + // the original map so the old buffer value can be + // used locally. + func resetBuffer() map[string]interface{} { +- bufferMu.Lock() +- bufCopy := buffer +- buffer = make(map[string]interface{}) +- bufferItemCount = 0 +- bufferMu.Unlock() +- return bufCopy ++ return map[string]interface{}{} + } + + // Response contains the body of a response from the +@@ -324,13 +129,6 @@ type Payload struct { + // Int returns the value of the data keyed by key + // if it is an integer; otherwise it returns 0. + func (p Payload) Int(key string) int { +- val, _ := p.Data[key] +- switch p.Data[key].(type) { +- case int: +- return val.(int) +- case float64: // after JSON-decoding, int becomes float64... +- return int(val.(float64)) +- } + return 0 + } + +@@ -345,17 +143,7 @@ type countingSet map[interface{}]int + // are JSON object values instead of keys, since keys + // are difficult to query in databases. + func (s countingSet) MarshalJSON() ([]byte, error) { +- type Item struct { +- Value interface{} `json:"value"` +- Count int `json:"count"` +- } +- var list []Item +- +- for k, v := range s { +- list = append(list, Item{Value: k, Count: v}) +- } +- +- return json.Marshal(list) ++ return []byte{}, nil + } + + var ( +@@ -415,7 +203,7 @@ var ( + const ( + // endpoint is the base URL to remote telemetry server; + // the instance ID will be appended to it. +- endpoint = "https://telemetry.caddyserver.com/v1/update/" ++ endpoint = "" + + // defaultUpdateInterval is how long to wait before emitting + // more telemetry data if all retires fail. This value is diff --git a/02-disable-telemetry-collection.patch b/02-disable-telemetry-collection.patch new file mode 100644 index 000000000000..5791edff0b17 --- /dev/null +++ b/02-disable-telemetry-collection.patch @@ -0,0 +1,266 @@ +diff --git a/collection.go b/collection.go +index 07cf0dc..f05672f 100644 +--- a/collection.go ++++ b/collection.go +@@ -15,11 +15,6 @@ + package telemetry + + import ( +- "fmt" +- "hash/fnv" +- "log" +- "strings" +- + "github.com/google/uuid" + ) + +@@ -36,20 +31,6 @@ import ( + // argument will be permanently disabled for the + // lifetime of the process. + func Init(instanceID uuid.UUID, disabledMetricsKeys []string) { +- if enabled { +- panic("already initialized") +- } +- if str := instanceID.String(); str == "" || +- str == "00000000-0000-0000-0000-000000000000" { +- panic("empty UUID") +- } +- instanceUUID = instanceID +- disabledMetricsMu.Lock() +- for _, key := range disabledMetricsKeys { +- disabledMetrics[strings.TrimSpace(key)] = false +- } +- disabledMetricsMu.Unlock() +- enabled = true + } + + // StartEmitting sends the current payload and begins the +@@ -62,22 +43,6 @@ func Init(instanceID uuid.UUID, disabledMetricsKeys []string) { + // This function panics if it was called more than once. + // It is a no-op if this package was not initialized. + func StartEmitting() { +- if !enabled { +- return +- } +- updateTimerMu.Lock() +- if updateTimer != nil { +- updateTimerMu.Unlock() +- panic("updates already started") +- } +- updateTimerMu.Unlock() +- updateMu.Lock() +- if updating { +- updateMu.Unlock() +- panic("update already in progress") +- } +- updateMu.Unlock() +- go logEmit(false) + } + + // StopEmitting sends the current payload and terminates +@@ -90,21 +55,10 @@ func StartEmitting() { + // you want to guarantee no blocking at critical times + // like exiting the program. + func StopEmitting() { +- if !enabled { +- return +- } +- updateTimerMu.Lock() +- if updateTimer == nil { +- updateTimerMu.Unlock() +- return +- } +- updateTimerMu.Unlock() +- logEmit(true) // likely too early; may take minutes to return + } + + // Reset empties the current payload buffer. + func Reset() { +- resetBuffer() + } + + // Set puts a value in the buffer to be included +@@ -116,19 +70,6 @@ func Reset() { + // go keyword after the call to SendHello so it + // doesn't block crucial code. + func Set(key string, val interface{}) { +- if !enabled || isDisabled(key) { +- return +- } +- bufferMu.Lock() +- if _, ok := buffer[key]; !ok { +- if bufferItemCount >= maxBufferItems { +- bufferMu.Unlock() +- return +- } +- bufferItemCount++ +- } +- buffer[key] = val +- bufferMu.Unlock() + } + + // SetNested puts a value in the buffer to be included +@@ -140,36 +81,6 @@ func Set(key string, val interface{}) { + // go keyword after the call to SendHello so it + // doesn't block crucial code. + func SetNested(key, subkey string, val interface{}) { +- if !enabled || isDisabled(key) { +- return +- } +- bufferMu.Lock() +- if topLevel, ok1 := buffer[key]; ok1 { +- topLevelMap, ok2 := topLevel.(map[string]interface{}) +- if !ok2 { +- bufferMu.Unlock() +- log.Printf("[PANIC] Telemetry: key %s is already used for non-nested-map value", key) +- return +- } +- if _, ok3 := topLevelMap[subkey]; !ok3 { +- // don't exceed max buffer size +- if bufferItemCount >= maxBufferItems { +- bufferMu.Unlock() +- return +- } +- bufferItemCount++ +- } +- topLevelMap[subkey] = val +- } else { +- // don't exceed max buffer size +- if bufferItemCount >= maxBufferItems { +- bufferMu.Unlock() +- return +- } +- bufferItemCount++ +- buffer[key] = map[string]interface{}{subkey: val} +- } +- bufferMu.Unlock() + } + + // Append appends value to a list named key. +@@ -177,29 +88,6 @@ func SetNested(key, subkey string, val interface{}) { + // If key maps to a type that is not a list, + // a panic is logged, and this is a no-op. + func Append(key string, value interface{}) { +- if !enabled || isDisabled(key) { +- return +- } +- bufferMu.Lock() +- if bufferItemCount >= maxBufferItems { +- bufferMu.Unlock() +- return +- } +- // TODO: Test this... +- bufVal, inBuffer := buffer[key] +- sliceVal, sliceOk := bufVal.([]interface{}) +- if inBuffer && !sliceOk { +- bufferMu.Unlock() +- log.Printf("[PANIC] Telemetry: key %s already used for non-slice value", key) +- return +- } +- if sliceVal == nil { +- buffer[key] = []interface{}{value} +- } else if sliceOk { +- buffer[key] = append(sliceVal, value) +- } +- bufferItemCount++ +- bufferMu.Unlock() + } + + // AppendUnique adds value to a set named key. +@@ -213,30 +101,6 @@ func Append(key string, value interface{}) { + // that is not a counting set, a panic is logged, + // and this is a no-op. + func AppendUnique(key string, value interface{}) { +- if !enabled || isDisabled(key) { +- return +- } +- bufferMu.Lock() +- bufVal, inBuffer := buffer[key] +- setVal, setOk := bufVal.(countingSet) +- if inBuffer && !setOk { +- bufferMu.Unlock() +- log.Printf("[PANIC] Telemetry: key %s already used for non-counting-set value", key) +- return +- } +- if setVal == nil { +- // ensure the buffer is not too full, then add new unique value +- if bufferItemCount >= maxBufferItems { +- bufferMu.Unlock() +- return +- } +- buffer[key] = countingSet{value: 1} +- bufferItemCount++ +- } else if setOk { +- // unique value already exists, so just increment counter +- setVal[value]++ +- } +- bufferMu.Unlock() + } + + // Add adds amount to a value named key. +@@ -245,46 +109,22 @@ func AppendUnique(key string, value interface{}) { + // is not an integer, a panic is logged, + // and this is a no-op. + func Add(key string, amount int) { +- atomicAdd(key, amount) + } + + // Increment is a shortcut for Add(key, 1) + func Increment(key string) { +- atomicAdd(key, 1) + } + + // atomicAdd adds amount (negative to subtract) + // to key. + func atomicAdd(key string, amount int) { +- if !enabled || isDisabled(key) { +- return +- } +- bufferMu.Lock() +- bufVal, inBuffer := buffer[key] +- intVal, intOk := bufVal.(int) +- if inBuffer && !intOk { +- bufferMu.Unlock() +- log.Printf("[PANIC] Telemetry: key %s already used for non-integer value", key) +- return +- } +- if !inBuffer { +- if bufferItemCount >= maxBufferItems { +- bufferMu.Unlock() +- return +- } +- bufferItemCount++ +- } +- buffer[key] = intVal + amount +- bufferMu.Unlock() + } + + // FastHash hashes input using a 32-bit hashing algorithm + // that is fast, and returns the hash as a hex-encoded string. + // Do not use this for cryptographic purposes. + func FastHash(input []byte) string { +- h := fnv.New32a() +- h.Write(input) +- return fmt.Sprintf("%x", h.Sum32()) ++ return "" + } + + // isDisabled returns whether key is +@@ -292,16 +132,5 @@ func FastHash(input []byte) string { + // functions should call this and not + // save the value if this returns true. + func isDisabled(key string) bool { +- // for keys that are augmented with data, such as +- // "tls_client_hello_ua:<hash>", just +- // check the prefix "tls_client_hello_ua" +- checkKey := key +- if idx := strings.Index(key, ":"); idx > -1 { +- checkKey = key[:idx] +- } +- +- disabledMetricsMu.RLock() +- _, ok := disabledMetrics[checkKey] +- disabledMetricsMu.RUnlock() +- return ok ++ return true + } @@ -1,11 +1,13 @@ -# Maintainer: Wei Congrui < crvv.mail at gmail dot com > +# Maintainer: Fernando Barillas < aur at fbis251 dot com > +# Contributor: Wei Congrui < crvv.mail at gmail dot com > # Contributor: Carl George < arch at cgtx dot us > # Contributor: Eric Engeström <eric at engestrom dot ch> # Contributor: Andreas Linz <klingt.net at gmail dot com> _gopkgname='github.com/mholt/caddy' +_name="caddy" -pkgname=caddy +pkgname="${_name}-no-telemetry" pkgver=0.11.0 pkgrel=1 pkgdesc='HTTP/2 Web Server with Automatic HTTPS' @@ -13,22 +15,28 @@ arch=('x86_64' 'i686' 'armv6h' 'armv7h' 'aarch64') url='https://caddyserver.com' license=('Apache') backup=('etc/caddy/caddy.conf') +provides=("$_name") +conflicts=("$_name") install='caddy.install' makedepends=('go>=1.8.1' 'git') -source=("https://$_gopkgname/archive/v$pkgver/$pkgname-$pkgver.tar.gz" +source=("https://$_gopkgname/archive/v$pkgver/$_name-$pkgver.tar.gz" 'https://caddyserver.com/resources/images/brand/caddy-at-your-service-white.svg' 'index.html' 'caddy.service' 'caddy.tmpfiles' 'caddy.conf' - 'plugins.go') + 'plugins.go' + '01-disable-telemetry.patch' + '02-disable-telemetry-collection.patch') sha256sums=('81e593d258460a9f5c6b5a5f46890a08b6b1ce15f5c0fc7bcaf09826368c3a1a' 'e679dd79fd92dc351fc190c7af529c73e3896986aaa6b7c0ae01e561398d6b85' '6db7aec45e95bbbf770ce4d120a60d8e4992d2262a8ebf668521179279aa5ae7' '0466a41290db84402ca41cf32c0fc5b66b112a9d85b71d1619ae97b5a3dd2740' 'c8f002f5ba59985a643600dc3c871e18e110903aa945ef3f2da7c9edd39fbd7a' '80520b80ccabf077a3269f6a1bf55faa3811ef5adce115131b35ef2044d37b64' - 'f5a0fbb961e7c9ecf99e88d0959a3164cbea54660c1c08c3ba3cdf1d45563929') + 'f5a0fbb961e7c9ecf99e88d0959a3164cbea54660c1c08c3ba3cdf1d45563929' + '1e6fcfb06704babdf5a5fea52d94bb9055182f48114999662c449d3cc3090cab' + '4fe4cc982322e7eec8ff187c22ff8a58db8a894da8aba038697e15a49b36fc52') patch_plugins() { IFS='' @@ -46,7 +54,7 @@ prepare() { export GOPATH="$srcdir/build" rm -rf "$GOPATH/src/$gopkgname" mkdir --parents `dirname "$GOPATH/src/$_gopkgname"` - mv -Tv "$srcdir/$pkgname-$pkgver" "$GOPATH/src/$_gopkgname" + mv -Tv "$srcdir/$_name-$pkgver" "$GOPATH/src/$_gopkgname" if [ ${#plugins[@]} -gt 0 ]; then echo enabled plugins: ${plugins[@]} @@ -55,6 +63,10 @@ prepare() { mv run1.go run.go go get -v -d $_gopkgname/caddy/caddymain fi + + # Disable telemetry collection + patch -Np1 -i "${srcdir}/01-disable-telemetry.patch" "${srcdir}/build/src/github.com/mholt/caddy/telemetry/telemetry.go" + patch -Np1 -i "${srcdir}/02-disable-telemetry-collection.patch" "${srcdir}/build/src/github.com/mholt/caddy/telemetry/collection.go" } build() { |