feat: add access policy middleware support cidr block

This commit is contained in:
2024-12-09 18:33:44 +01:00
parent 7e3489e201
commit 89a6f3fffd
3 changed files with 19 additions and 7 deletions

View File

@@ -13,7 +13,7 @@ It supports two actions: `ALLOW` and `DENY`.
### How It Works ### How It Works
1. **Define an action:** Specify whether the middleware should `ALLOW` or `DENY` access. 1. **Define an action:** Specify whether the middleware should `ALLOW` or `DENY` access.
2. **Set sourceRanges:** Provide a list of IP addresses or IP ranges to which the policy applies. 2. **Set sourceRanges:** Provide a list of IP addresses, IP ranges or a CIDR block to which the policy applies.
Requests originating from these sources will be evaluated according to the specified action. Requests originating from these sources will be evaluated according to the specified action.
@@ -28,5 +28,6 @@ middlewares:
action: DENY # Specify either DENY or ALLOW action: DENY # Specify either DENY or ALLOW
sourceRanges: sourceRanges:
- 192.168.1.1 # Single IP address - 192.168.1.1 # Single IP address
- 172.18.0.0-172.18.0.10 # IP range - 10.42.1.1-10.42.1.100 # IP range
- 10.42.1.1/16 # CIDR block
``` ```

View File

@@ -307,10 +307,6 @@ func getAccessPoliciesMiddleware(input interface{}) (AccessPolicyRuleMiddleware,
if !validateCIDR(ip) { if !validateCIDR(ip) {
return AccessPolicyRuleMiddleware{}, fmt.Errorf("invalid cidr address") return AccessPolicyRuleMiddleware{}, fmt.Errorf("invalid cidr address")
} }
if validateCIDR(ip) {
return AccessPolicyRuleMiddleware{}, fmt.Errorf("cidr is not yet supported")
}
} }
} }

View File

@@ -63,13 +63,18 @@ func (access AccessPolicy) AccessPolicyMiddleware(next http.Handler) http.Handle
}) })
} }
// isIPAllowed checks if a client IP matches an entry (range or single IP). // isIPAllowed checks if a client IP matches an entry (range, single IP or CIDR block).
func isIPAllowed(clientIP, entry string) bool { func isIPAllowed(clientIP, entry string) bool {
// Handle IP range
if strings.Contains(entry, "-") { if strings.Contains(entry, "-") {
// Handle IP range // Handle IP range
startIP, endIP, err := parseIPRange(entry) startIP, endIP, err := parseIPRange(entry)
return err == nil && ipInRange(clientIP, startIP, endIP) return err == nil && ipInRange(clientIP, startIP, endIP)
} }
// Handle CIDR
if strings.Contains(entry, "/") {
return ipInCIDR(clientIP, entry)
}
// Handle single IP // Handle single IP
return clientIP == entry return clientIP == entry
} }
@@ -116,3 +121,13 @@ func ipInRange(ipStr, startIP, endIP string) bool {
} }
return true return true
} }
// Check if an IP is within a CIDR block
func ipInCIDR(ipStr, cidr string) bool {
ip := net.ParseIP(ipStr)
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
return false
}
return ipNet.Contains(ip)
}