mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-26 04:06:38 +00:00
* implement reverse proxy --------- Co-authored-by: Alisdair MacLeod <git@alisdairmacleod.co.uk> Co-authored-by: mlsmaycon <mlsmaycon@gmail.com> Co-authored-by: Eduard Gert <kontakt@eduardgert.de> Co-authored-by: Viktor Liu <viktor@netbird.io> Co-authored-by: Diego Noguês <diego.sure@gmail.com> Co-authored-by: Diego Noguês <49420+diegocn@users.noreply.github.com> Co-authored-by: Bethuel Mmbaga <bethuelmbaga12@gmail.com> Co-authored-by: Zoltan Papp <zoltan.pmail@gmail.com> Co-authored-by: Ashley Mensah <ashleyamo982@gmail.com>
61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package proxy
|
|
|
|
import (
|
|
"net/netip"
|
|
"strings"
|
|
)
|
|
|
|
// IsTrustedProxy checks if the given IP string falls within any of the trusted prefixes.
|
|
func IsTrustedProxy(ipStr string, trusted []netip.Prefix) bool {
|
|
if len(trusted) == 0 {
|
|
return false
|
|
}
|
|
|
|
addr, err := netip.ParseAddr(ipStr)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
for _, prefix := range trusted {
|
|
if prefix.Contains(addr) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ResolveClientIP extracts the real client IP from X-Forwarded-For using the trusted proxy list.
|
|
// It walks the XFF chain right-to-left, skipping IPs that match trusted prefixes.
|
|
// The first untrusted IP is the real client.
|
|
//
|
|
// If the trusted list is empty or remoteAddr is not trusted, it returns the
|
|
// remoteAddr IP directly (ignoring any forwarding headers).
|
|
func ResolveClientIP(remoteAddr, xff string, trusted []netip.Prefix) string {
|
|
remoteIP := extractClientIP(remoteAddr)
|
|
|
|
if len(trusted) == 0 || !IsTrustedProxy(remoteIP, trusted) {
|
|
return remoteIP
|
|
}
|
|
|
|
if xff == "" {
|
|
return remoteIP
|
|
}
|
|
|
|
parts := strings.Split(xff, ",")
|
|
for i := len(parts) - 1; i >= 0; i-- {
|
|
ip := strings.TrimSpace(parts[i])
|
|
if ip == "" {
|
|
continue
|
|
}
|
|
if !IsTrustedProxy(ip, trusted) {
|
|
return ip
|
|
}
|
|
}
|
|
|
|
// All IPs in XFF are trusted; return the leftmost as best guess.
|
|
if first := strings.TrimSpace(parts[0]); first != "" {
|
|
return first
|
|
}
|
|
return remoteIP
|
|
}
|