From f5df03119f36d3871e9feb2bf8092c653220b00c Mon Sep 17 00:00:00 2001 From: Myles Horton Date: Thu, 13 Aug 2015 12:32:50 -0700 Subject: [PATCH 1/2] Tweaking server side to always report and use IP and country from CloudFlare closes #2941 --- src/github.com/getlantern/enproxy/proxy.go | 3 ++ .../getlantern/enproxy/proxy_test.go | 39 +++++++++++++++++ .../getlantern/flashlight/server/server.go | 42 ++++++++++++------- .../flashlight/server/server_test.go | 40 ++++++++++++++++++ testpackages.txt | 1 + 5 files changed, 110 insertions(+), 15 deletions(-) create mode 100644 src/github.com/getlantern/enproxy/proxy_test.go create mode 100644 src/github.com/getlantern/flashlight/server/server_test.go diff --git a/src/github.com/getlantern/enproxy/proxy.go b/src/github.com/getlantern/enproxy/proxy.go index 9cf7b6c14b..98a177d476 100644 --- a/src/github.com/getlantern/enproxy/proxy.go +++ b/src/github.com/getlantern/enproxy/proxy.go @@ -130,6 +130,9 @@ func (p *Proxy) Serve(l net.Listener) error { // ServeHTTP: implements the http.Handler interface func (p *Proxy) ServeHTTP(resp http.ResponseWriter, req *http.Request) { + resp.Header().Set("Lantern-IP", req.Header.Get("X-Forwarded-For")) + resp.Header().Set("Lantern-Country", req.Header.Get("Cf-Ipcountry")) + if req.Method == "HEAD" { // Just respond OK to HEAD requests (used for health checks) resp.WriteHeader(200) diff --git a/src/github.com/getlantern/enproxy/proxy_test.go b/src/github.com/getlantern/enproxy/proxy_test.go new file mode 100644 index 0000000000..adee869437 --- /dev/null +++ b/src/github.com/getlantern/enproxy/proxy_test.go @@ -0,0 +1,39 @@ +package enproxy + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +func TestBanned(t *testing.T) { + + proxy := &Proxy{} + + w := httptest.NewRecorder() + + req, err := http.NewRequest("GET", "http://example.com/foo", nil) + if err != nil { + t.Fatal(err) + } + + xff := "7.7.7.7" + req.Header.Set("X-Forwarded-For", xff) + + ipc := "US" + req.Header.Set("Cf-Ipcountry", ipc) + + proxy.ServeHTTP(w, req) + + ip := w.Header().Get("Lantern-IP") + country := w.Header().Get("Lantern-Country") + + log.Debugf("Testing IP: %v", ip) + log.Debugf("Testing country: %v", country) + if ip != xff { + t.Fatalf("Unexpected ip: %v", ip) + } + if country != ipc { + t.Fatalf("Unexpected country: %v", country) + } +} diff --git a/src/github.com/getlantern/flashlight/server/server.go b/src/github.com/getlantern/flashlight/server/server.go index e7aef1bc22..89b80b3a53 100644 --- a/src/github.com/getlantern/flashlight/server/server.go +++ b/src/github.com/getlantern/flashlight/server/server.go @@ -271,10 +271,34 @@ func (server *Server) checkForDisallowedPort(addr string) error { } func (server *Server) checkForBannedCountry(req *http.Request) error { + country := req.Header.Get("Cf-Ipcountry") + if country == "" { + var err error + if country, err = server.lookupCountry(req); err != nil { + log.Errorf("Could not find country %v", err) + return nil + } + } + + countryBanned := false + for _, banned := range server.BannedCountries { + if country == strings.ToUpper(banned) { + countryBanned = true + break + } + } + if countryBanned { + return fmt.Errorf("Not accepting connections from country %v", country) + } + + return nil +} + +func (server *Server) lookupCountry(req *http.Request) (string, error) { clientIp := getClientIp(req) if clientIp == "" { log.Debug("Unable to determine client ip for geolookup") - return nil + return "", nil } country := "" @@ -287,24 +311,12 @@ func (server *Server) checkForBannedCountry(req *http.Request) error { city, _, err := geolookup.LookupIPWithClient(clientIp, nil) if err != nil { log.Debugf("Unable to perform geolookup for ip %v: %v", clientIp, err) - return nil + return country, err } country = strings.ToUpper(city.Country.IsoCode) server.geoCache.Add(clientIp, country) } - - countryBanned := false - for _, banned := range server.BannedCountries { - if country == strings.ToUpper(banned) { - countryBanned = true - break - } - } - if countryBanned { - return fmt.Errorf("Not accepting connections from country %v", country) - } - - return nil + return country, nil } func mapPort(addr string, port int) error { diff --git a/src/github.com/getlantern/flashlight/server/server_test.go b/src/github.com/getlantern/flashlight/server/server_test.go new file mode 100644 index 0000000000..00ee761bfd --- /dev/null +++ b/src/github.com/getlantern/flashlight/server/server_test.go @@ -0,0 +1,40 @@ +package server + +import ( + "net/http" + "testing" + + "github.com/getlantern/fronted" +) + +func TestBanned(t *testing.T) { + + srv := &Server{ + Addr: "127.0.0.1", + ReadTimeout: 0, // don't timeout + WriteTimeout: 0, + CertContext: &fronted.CertContext{}, + AllowedPorts: []int{80, 443, 8080, 8443, 5222, 5223, 5228}, + + // We've observed high resource consumption from these countries for + // purposes unrelated to Lantern's mission, so we disallow them. + BannedCountries: []string{"PH"}, + } + + req, err := http.NewRequest("GET", "http://test.com/foo", nil) + if err != nil { + log.Fatal(err) + } + req.Header.Set("Cf-Ipcountry", "PH") + + err = srv.checkForBannedCountry(req) + if err == nil { + t.Fatalf("Should be banned: %v", err) + } + + req.Header.Set("Cf-Ipcountry", "US") + err = srv.checkForBannedCountry(req) + if err != nil { + t.Fatalf("Should not be banned: %v", err) + } +} diff --git a/testpackages.txt b/testpackages.txt index 41207c265f..ce1b808a17 100644 --- a/testpackages.txt +++ b/testpackages.txt @@ -14,6 +14,7 @@ github.com/getlantern/fdcount github.com/getlantern/flashlight github.com/getlantern/flashlight/logging github.com/getlantern/flashlight/pubsub +github.com/getlantern/flashlight/server github.com/getlantern/flashlight/statreporter github.com/getlantern/fronted github.com/getlantern/geolookup From 6743d40381a7359d20568da134787eadd638abd9 Mon Sep 17 00:00:00 2001 From: Myles Horton Date: Thu, 13 Aug 2015 12:57:37 -0700 Subject: [PATCH 2/2] method name --- src/github.com/getlantern/enproxy/proxy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/github.com/getlantern/enproxy/proxy_test.go b/src/github.com/getlantern/enproxy/proxy_test.go index adee869437..5cd1966dde 100644 --- a/src/github.com/getlantern/enproxy/proxy_test.go +++ b/src/github.com/getlantern/enproxy/proxy_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -func TestBanned(t *testing.T) { +func TestCustomHeaders(t *testing.T) { proxy := &Proxy{}