From 44ac7144ecd35dc216cc49d2560d41c3cb4dbd2d Mon Sep 17 00:00:00 2001 From: Toby Chui Date: Fri, 23 Jun 2023 23:45:49 +0800 Subject: [PATCH] Added access control bypass for /.well-known router --- src/acme.go | 3 +- src/mod/dynamicproxy/Server.go | 87 +++++++++++++++++++++------------ src/mod/dynamicproxy/special.go | 9 ++-- 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/src/acme.go b/src/acme.go index 31e54fd..d9f0638 100644 --- a/src/acme.go +++ b/src/acme.go @@ -69,7 +69,8 @@ func acmeRegisterSpecialRoutingRule() { } w.Write(resBody) }, - Enabled: true, + Enabled: true, + UseSystemAccessControl: false, }) if err != nil { diff --git a/src/mod/dynamicproxy/Server.go b/src/mod/dynamicproxy/Server.go index d6d3a63..4907ef4 100644 --- a/src/mod/dynamicproxy/Server.go +++ b/src/mod/dynamicproxy/Server.go @@ -23,35 +23,32 @@ import ( func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { /* - General Access Check + Special Routing Rules, bypass most of the limitations */ - //Check if this ip is in blacklist - clientIpAddr := geodb.GetRequesterIP(r) - if h.Parent.Option.GeodbStore.IsBlacklisted(clientIpAddr) { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - w.WriteHeader(http.StatusForbidden) - template, err := os.ReadFile("./web/forbidden.html") - if err != nil { - w.Write([]byte("403 - Forbidden")) - } else { - w.Write(template) + //Check if there are external routing rule matches. + //If yes, route them via external rr + matchedRoutingRule := h.Parent.GetMatchingRoutingRule(r) + if matchedRoutingRule != nil { + //Matching routing rule found. Let the sub-router handle it + if matchedRoutingRule.UseSystemAccessControl { + //This matching rule request system access control. + //check access logic + respWritten := h.handleAccessRouting(w, r) + if respWritten { + return + } } - h.logRequest(r, false, 403, "blacklist", "") + matchedRoutingRule.Route(w, r) return } - //Check if this ip is in whitelist - if !h.Parent.Option.GeodbStore.IsWhitelisted(clientIpAddr) { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - w.WriteHeader(http.StatusForbidden) - template, err := os.ReadFile("./web/forbidden.html") - if err != nil { - w.Write([]byte("403 - Forbidden")) - } else { - w.Write(template) - } - h.logRequest(r, false, 403, "whitelist", "") + /* + General Access Check + */ + + respWritten := h.handleAccessRouting(w, r) + if respWritten { return } @@ -65,15 +62,6 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - //Check if there are external routing rule matches. - //If yes, route them via external rr - matchedRoutingRule := h.Parent.GetMatchingRoutingRule(r) - if matchedRoutingRule != nil { - //Matching routing rule found. Let the sub-router handle it - matchedRoutingRule.Route(w, r) - return - } - //Extract request host to see if it is virtual directory or subdomain domainOnly := r.Host if strings.Contains(r.Host, ":") { @@ -127,3 +115,38 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.proxyRequest(w, r, h.Parent.Root) } } + +// Handle access routing logic. Return true if the request is handled or blocked by the access control logic +// if the return value is false, you can continue process the response writer +func (h *ProxyHandler) handleAccessRouting(w http.ResponseWriter, r *http.Request) bool { + //Check if this ip is in blacklist + clientIpAddr := geodb.GetRequesterIP(r) + if h.Parent.Option.GeodbStore.IsBlacklisted(clientIpAddr) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusForbidden) + template, err := os.ReadFile("./web/forbidden.html") + if err != nil { + w.Write([]byte("403 - Forbidden")) + } else { + w.Write(template) + } + h.logRequest(r, false, 403, "blacklist", "") + return true + } + + //Check if this ip is in whitelist + if !h.Parent.Option.GeodbStore.IsWhitelisted(clientIpAddr) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusForbidden) + template, err := os.ReadFile("./web/forbidden.html") + if err != nil { + w.Write([]byte("403 - Forbidden")) + } else { + w.Write(template) + } + h.logRequest(r, false, 403, "whitelist", "") + return true + } + + return false +} diff --git a/src/mod/dynamicproxy/special.go b/src/mod/dynamicproxy/special.go index 37fe80b..67b3ddc 100644 --- a/src/mod/dynamicproxy/special.go +++ b/src/mod/dynamicproxy/special.go @@ -13,10 +13,11 @@ import ( */ type RoutingRule struct { - ID string - MatchRule func(r *http.Request) bool - RoutingHandler func(http.ResponseWriter, *http.Request) - Enabled bool + ID string //ID of the routing rule + Enabled bool //If the routing rule enabled + UseSystemAccessControl bool //Pass access control check to system white/black list, set this to false to bypass white/black list + MatchRule func(r *http.Request) bool + RoutingHandler func(http.ResponseWriter, *http.Request) } // Router functions