소스 검색

Added cookiejar to uptime monitor to follow poorly implemented redirect logic

Toby Chui 9 달 전
부모
커밋
1e3576f7da
4개의 변경된 파일58개의 추가작업 그리고 6개의 파일을 삭제
  1. 3 3
      mod/dynamicproxy/dpcore/dpcore.go
  2. 32 0
      mod/dynamicproxy/dpcore/utils.go
  3. 22 2
      mod/uptime/uptime.go
  4. 1 1
      tools/provider_config_updater/lego

+ 3 - 3
mod/dynamicproxy/dpcore/dpcore.go

@@ -348,9 +348,9 @@ func (p *ReverseProxy) ProxyHTTP(rw http.ResponseWriter, req *http.Request, rrr
 	p.Director(outreq)
 	outreq.Close = false
 
-	if !rrr.UseTLS {
-		//This seems to be routing to external sites
-		//Do not keep the original host
+	//Only skip origin rewrite iff proxy target require TLS and it is external domain name like github.com
+	if !(rrr.UseTLS && isExternalDomainName(rrr.ProxyDomain)) {
+		// Always use the original host, see issue #164
 		outreq.Host = rrr.OriginalHost
 	}
 

+ 32 - 0
mod/dynamicproxy/dpcore/utils.go

@@ -1,6 +1,7 @@
 package dpcore
 
 import (
+	"net"
 	"net/url"
 	"strings"
 )
@@ -60,3 +61,34 @@ func replaceLocationHost(urlString string, rrr *ResponseRewriteRuleSet, useTLS b
 func ReplaceLocationHost(urlString string, rrr *ResponseRewriteRuleSet, useTLS bool) (string, error) {
 	return replaceLocationHost(urlString, rrr, useTLS)
 }
+
+// isExternalDomainName check and return if the hostname is external domain name (e.g. github.com)
+// instead of internal (like 192.168.1.202:8443 (ip address) or domains end with .local or .internal)
+func isExternalDomainName(hostname string) bool {
+	host, _, err := net.SplitHostPort(hostname)
+	if err != nil {
+		//hostname doesnt contain port
+		ip := net.ParseIP(hostname)
+		if ip != nil {
+			//IP address, not a domain name
+			return false
+		}
+	} else {
+		//Hostname contain port, use hostname without port to check if it is ip
+		ip := net.ParseIP(host)
+		if ip != nil {
+			//IP address, not a domain name
+			return false
+		}
+	}
+
+	//Check if it is internal DNS assigned domains
+	internalDNSTLD := []string{".local", ".internal", ".localhost", ".home.arpa"}
+	for _, tld := range internalDNSTLD {
+		if strings.HasSuffix(strings.ToLower(hostname), tld) {
+			return false
+		}
+	}
+
+	return true
+}

+ 22 - 2
mod/uptime/uptime.go

@@ -4,9 +4,11 @@ import (
 	"encoding/json"
 	"log"
 	"net/http"
+	"net/http/cookiejar"
 	"strings"
 	"time"
 
+	"golang.org/x/net/publicsuffix"
 	"imuslab.com/zoraxy/mod/utils"
 )
 
@@ -217,11 +219,24 @@ func getWebsiteStatusWithLatency(url string) (bool, int64, int) {
 }
 
 func getWebsiteStatus(url string) (int, error) {
+	// Create a one-time use cookie jar to store cookies
+	jar, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
+	if err != nil {
+		log.Fatal(err)
+	}
+
 	client := http.Client{
+		Jar:     jar,
 		Timeout: 10 * time.Second,
 	}
 
-	resp, err := client.Get(url)
+	req, _ := http.NewRequest("GET", url, nil)
+	req.Header = http.Header{
+		"User-Agent": {"zoraxy-uptime/1.1"},
+	}
+
+	resp, err := client.Do(req)
+	//resp, err := client.Get(url)
 	if err != nil {
 		//Try replace the http with https and vise versa
 		rewriteURL := ""
@@ -231,7 +246,12 @@ func getWebsiteStatus(url string) (int, error) {
 			rewriteURL = strings.ReplaceAll(url, "http://", "https://")
 		}
 
-		resp, err = client.Get(rewriteURL)
+		req, _ := http.NewRequest("GET", rewriteURL, nil)
+		req.Header = http.Header{
+			"User-Agent": {"zoraxy-uptime/1.1"},
+		}
+
+		resp, err := client.Do(req)
 		if err != nil {
 			if strings.Contains(err.Error(), "http: server gave HTTP response to HTTPS client") {
 				//Invalid downstream reverse proxy settings, but it is online

+ 1 - 1
tools/provider_config_updater/lego

@@ -1 +1 @@
-Subproject commit d39d57fbc931ddd6f9f914bc2e245acb0a6c3e43
+Subproject commit 92bde4cd56379551a1ea26354869f98c7b5581ec