aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFrancis Lavoie <[email protected]>2024-10-11 17:35:28 -0400
committerFrancis Lavoie <[email protected]>2024-11-04 14:10:51 -0500
commit76ba7ab8af630d3e18c09f5fba1f1308a0bf9aa6 (patch)
tree42fe980c202fbce9cc32fd0610e6b2150c0f4070
parent0515e69adeb6515eedda16f90f663f75e0eeb820 (diff)
downloadcaddy-76ba7ab8af630d3e18c09f5fba1f1308a0bf9aa6.tar.gz
caddy-76ba7ab8af630d3e18c09f5fba1f1308a0bf9aa6.zip
Error in IP matchers on TLS handshake not complete
-rw-r--r--modules/caddyhttp/ip_matchers.go44
1 files changed, 28 insertions, 16 deletions
diff --git a/modules/caddyhttp/ip_matchers.go b/modules/caddyhttp/ip_matchers.go
index dec2f75de..948ee8da5 100644
--- a/modules/caddyhttp/ip_matchers.go
+++ b/modules/caddyhttp/ip_matchers.go
@@ -145,9 +145,20 @@ func (m *MatchRemoteIP) Provision(ctx caddy.Context) error {
// Match returns true if r matches m.
func (m MatchRemoteIP) Match(r *http.Request) bool {
+ matches, err := m.MatchWithError(r)
+ if err != nil {
+ SetVar(r.Context(), MatcherErrorVarKey, err)
+ }
+ return matches
+}
+
+// MatchWithError returns true if r matches m.
+func (m MatchRemoteIP) MatchWithError(r *http.Request) (bool, error) {
+ // if handshake is not finished, we infer 0-RTT that has not verified remote IP; could be spoofed
if r.TLS != nil && !r.TLS.HandshakeComplete {
- return false // if handshake is not finished, we infer 0-RTT that has not verified remote IP; could be spoofed
+ return false, fmt.Errorf("TLS handshake not complete, remote IP cannot be verified")
}
+
address := r.RemoteAddr
clientIP, zoneID, err := parseIPZoneFromString(address)
if err != nil {
@@ -155,7 +166,7 @@ func (m MatchRemoteIP) Match(r *http.Request) bool {
c.Write(zap.Error(err))
}
- return false
+ return false, nil
}
matches, zoneFilter := matchIPByCidrZones(clientIP, zoneID, m.cidrs, m.zones)
if !matches && !zoneFilter {
@@ -163,12 +174,7 @@ func (m MatchRemoteIP) Match(r *http.Request) bool {
c.Write(zap.String("zone", zoneID))
}
}
- return matches
-}
-
-// MatchWithError returns true if r matches m.
-func (m MatchRemoteIP) MatchWithError(r *http.Request) (bool, error) {
- return m.Match(r), nil
+ return matches, nil
}
// CaddyModule returns the Caddy module information.
@@ -243,25 +249,31 @@ func (m *MatchClientIP) Provision(ctx caddy.Context) error {
// Match returns true if r matches m.
func (m MatchClientIP) Match(r *http.Request) bool {
+ matches, err := m.MatchWithError(r)
+ if err != nil {
+ SetVar(r.Context(), MatcherErrorVarKey, err)
+ }
+ return matches
+}
+
+// MatchWithError returns true if r matches m.
+func (m MatchClientIP) MatchWithError(r *http.Request) (bool, error) {
+ // if handshake is not finished, we infer 0-RTT that has not verified remote IP; could be spoofed
if r.TLS != nil && !r.TLS.HandshakeComplete {
- return false // if handshake is not finished, we infer 0-RTT that has not verified remote IP; could be spoofed
+ return false, fmt.Errorf("TLS handshake not complete, remote IP cannot be verified")
}
+
address := GetVar(r.Context(), ClientIPVarKey).(string)
clientIP, zoneID, err := parseIPZoneFromString(address)
if err != nil {
m.logger.Error("getting client IP", zap.Error(err))
- return false
+ return false, nil
}
matches, zoneFilter := matchIPByCidrZones(clientIP, zoneID, m.cidrs, m.zones)
if !matches && !zoneFilter {
m.logger.Debug("zone ID from client IP did not match", zap.String("zone", zoneID))
}
- return matches
-}
-
-// MatchWithError returns true if r matches m.
-func (m MatchClientIP) MatchWithError(r *http.Request) (bool, error) {
- return m.Match(r), nil
+ return matches, nil
}
func provisionCidrsZonesFromRanges(ranges []string) ([]*netip.Prefix, []string, error) {