From aff0f3d3b6e59acdcfb006be91639e4660df22d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Adamski?= Date: Wed, 23 Apr 2025 19:34:09 +0200 Subject: [PATCH] check FQDN --- announce.go | 13 +++++++++---- announce_test.go | 6 +++++- go.mod | 11 +++++------ go.sum | 12 ++++++------ main.go | 7 ++++++- middleware.go | 4 +++- 6 files changed, 34 insertions(+), 19 deletions(-) diff --git a/announce.go b/announce.go index d7af43e..e404dde 100644 --- a/announce.go +++ b/announce.go @@ -17,7 +17,8 @@ type AnnounceResponse struct { Complete int `bencode:"complete"` Incomplete int `bencode:"incomplete"` Peers []byte `bencode:"peers"` - PeersIPv6 []byte `bencode:"peers_ipv6"` + PeersIPv6 []byte `bencode:"peers6,omitempty"` + ExternalIP []byte `bencode:"external ip,omitempty"` } func announce(w http.ResponseWriter, r *http.Request) { @@ -65,6 +66,7 @@ func announce(w http.ResponseWriter, r *http.Request) { Incomplete: numLeechers, Peers: peersIPv4, PeersIPv6: peersIPv6, + ExternalIP: ip.To4(), } w.Header().Add("X-PrivTracker", fmt.Sprintf("s:%d l:%d", numSeeders, numLeechers)) if err := bencode.Marshal(w, resp); err != nil { @@ -81,12 +83,15 @@ func getRemoteIP(r *http.Request) net.IP { ip := net.ParseIP(addr) if ip.IsPrivate() { ips := strings.Split(r.Header.Get("X-Forwarded-For"), ",") - if len(ips) > 0 { - ipForwarded := net.ParseIP(strings.TrimSpace(ips[0])) - if ipForwarded != nil { + for _, maybeIP := range ips { + ipForwarded := net.ParseIP(strings.TrimSpace(maybeIP)) + if !ipForwarded.IsPrivate() { ip = ipForwarded + break } } + if len(ips) > 0 { + } } return ip } diff --git a/announce_test.go b/announce_test.go index 1a34a2a..91085b0 100644 --- a/announce_test.go +++ b/announce_test.go @@ -1,6 +1,7 @@ package main import ( + "net/http" "net/http/httptest" "testing" ) @@ -9,9 +10,12 @@ func BenchmarkAnnounce(b *testing.B) { server := httptest.NewServer(router()) client := server.Client() for i := 0; i < b.N; i++ { - _, err := client.Get(server.URL + "/test/announce?port=1234") + resp, err := client.Get(server.URL + "/test/announce?port=1234") if err != nil { b.Fatal(err) } + if resp.StatusCode != http.StatusOK { + b.Fatalf("unexpected status code: %d", resp.StatusCode) + } } } diff --git a/go.mod b/go.mod index db7cec2..3287f57 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,12 @@ module github.com/meehow/privtracker -go 1.22 +go 1.24.0 require ( github.com/jackpal/bencode-go v1.0.2 - golang.org/x/crypto v0.32.0 + golang.org/x/crypto v0.37.0 + golang.org/x/net v0.39.0 + ) -require ( - golang.org/x/net v0.21.0 // indirect - golang.org/x/text v0.21.0 // indirect -) +require golang.org/x/text v0.24.0 // indirect diff --git a/go.sum b/go.sum index aba7d1d..053ef94 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,8 @@ github.com/jackpal/bencode-go v1.0.2 h1:LcCNfZ344u0LpBPOZNjpCLps/wUOuN4r87Fy9+5yU8g= github.com/jackpal/bencode-go v1.0.2/go.mod h1:6jI9mUjO3GQbZti3JizEfxTzRfWOM8oBBcwbwlTfceI= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= diff --git a/main.go b/main.go index d64e4d2..7cb1092 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "path/filepath" "golang.org/x/crypto/acme/autocert" + "golang.org/x/net/publicsuffix" ) func main() { @@ -20,7 +21,7 @@ func main() { handler := router(recoveryMiddleware, headersMiddleware, logRequestMiddleware) if port == "443" { go redirect80() - fmt.Println("PrivTracker listening on https://0.0.0.0/") + fmt.Println("PrivTracker listening on https://0.0.0.0/ (please use your FQDN to access this server)") log.Fatal(http.Serve(autocertListener(), handler)) } else { fmt.Printf("PrivTracker listening on http://0.0.0.0:%s/\n", port) @@ -59,6 +60,10 @@ func autocertListener() net.Listener { func redirect(w http.ResponseWriter, r *http.Request) { url := fmt.Sprintf("https://%s/", r.Host) + if _, icann := publicsuffix.PublicSuffix(r.Host); !icann { + // fallback in case we can't get FQDN + url = "https://privtracker.com/" + } http.Redirect(w, r, url, http.StatusMovedPermanently) } diff --git a/middleware.go b/middleware.go index b7fff84..f32135a 100644 --- a/middleware.go +++ b/middleware.go @@ -40,7 +40,9 @@ func logRequestMiddleware(next http.Handler) http.Handler { func headersMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Strict-Transport-Security", "max-age=31536000") // hsts + if r.TLS != nil { + w.Header().Set("Strict-Transport-Security", "max-age=31536000") // hsts + } w.Header().Set("Server", "PrivTracker") next.ServeHTTP(w, r) })