From f7fd29b2461d80d34ace5d6224436b75e40975be Mon Sep 17 00:00:00 2001 From: Srijan Srivastava <79690889+SrijanSriv@users.noreply.github.com> Date: Wed, 9 Feb 2022 16:24:19 +0530 Subject: [PATCH] geolocate: add cloudflare-based IP lookup (#676) Cloudflare hosted services provide a certain service of `/cdn-cgi/trace` with their base url (for example, `www.cloudflare.com` or `www.nginx.com`), which can be used to obtain `ip` in the probe's `geolocate` feature. The same feature was added in this pr, hence, increasing the number of `baseURL`s in `geolocate`. Co-authored-by: Simone Basso --- internal/engine/geolocate/cloudflare.go | 33 ++++++++++++++++++++ internal/engine/geolocate/cloudflare_test.go | 26 +++++++++++++++ internal/engine/geolocate/iplookup.go | 4 +++ 3 files changed, 63 insertions(+) create mode 100644 internal/engine/geolocate/cloudflare.go create mode 100644 internal/engine/geolocate/cloudflare_test.go diff --git a/internal/engine/geolocate/cloudflare.go b/internal/engine/geolocate/cloudflare.go new file mode 100644 index 0000000..61664e9 --- /dev/null +++ b/internal/engine/geolocate/cloudflare.go @@ -0,0 +1,33 @@ +package geolocate + +import ( + "context" + "net/http" + "regexp" + "strings" + + "github.com/ooni/probe-cli/v3/internal/engine/httpheader" + "github.com/ooni/probe-cli/v3/internal/httpx" + "github.com/ooni/probe-cli/v3/internal/model" +) + +func cloudflareIPLookup( + ctx context.Context, + httpClient *http.Client, + logger model.Logger, + userAgent string, +) (string, error) { + data, err := (&httpx.APIClientTemplate{ + BaseURL: "https://www.cloudflare.com", + HTTPClient: httpClient, + Logger: logger, + UserAgent: httpheader.CLIUserAgent(), + }).WithBodyLogging().Build().FetchResource(ctx, "/cdn-cgi/trace") + if err != nil { + return DefaultProbeIP, err + } + r := regexp.MustCompile("(?:ip)=(.*)") + ip := strings.Trim(string(r.Find(data)), "ip=") + logger.Debugf("cloudflare: body: %s", ip) + return ip, nil +} diff --git a/internal/engine/geolocate/cloudflare_test.go b/internal/engine/geolocate/cloudflare_test.go new file mode 100644 index 0000000..a3a9ef3 --- /dev/null +++ b/internal/engine/geolocate/cloudflare_test.go @@ -0,0 +1,26 @@ +package geolocate + +import ( + "context" + "net" + "net/http" + "testing" + + "github.com/apex/log" + "github.com/ooni/probe-cli/v3/internal/engine/httpheader" +) + +func TestIPLookupWorksUsingcloudlflare(t *testing.T) { + ip, err := cloudflareIPLookup( + context.Background(), + http.DefaultClient, + log.Log, + httpheader.UserAgent(), + ) + if err != nil { + t.Fatal(err) + } + if net.ParseIP(ip) == nil { + t.Fatalf("not an IP address: '%s'", ip) + } +} diff --git a/internal/engine/geolocate/iplookup.go b/internal/engine/geolocate/iplookup.go index 4cb46f0..52438a0 100644 --- a/internal/engine/geolocate/iplookup.go +++ b/internal/engine/geolocate/iplookup.go @@ -40,6 +40,10 @@ var ( name: "avast", fn: avastIPLookup, }, + { + name: "cloudflare", + fn: cloudflareIPLookup, + }, { name: "ipconfig", fn: ipConfigIPLookup,