package httpserver import ( "git.yuntuo.hk/k2safe/orbit/internal/consoleauth" "net/http" "net/netip" "strings" ) // loginRemoteAddress 默认只信任 TCP 对端;仅受信反代可提供 X-Forwarded-For。 // 从右往左剥离可信跳点,遇到首个非可信地址即停止;不接受任意客户端伪造的首项。 func loginRemoteAddress(r *http.Request, store consoleauth.Store) string { peer, err := netip.ParseAddr(remoteAddress(r)) if err != nil { return "" } peer = peer.Unmap() policyStore, ok := store.(interface { LoginPolicy() consoleauth.LoginPolicy }) if !ok { return peer.String() } trusted := policyStore.LoginPolicy().TrustedProxies isTrusted := func(ip netip.Addr) bool { for _, n := range trusted { if n.Contains(ip) { return true } } return false } if !isTrusted(peer) { return peer.String() } raw := strings.Join(r.Header.Values("X-Forwarded-For"), ",") if raw == "" || len(raw) > 2048 { return peer.String() } hops := strings.Split(raw, ",") if len(hops) > 32 { return peer.String() } addresses := make([]netip.Addr, len(hops)) for i, h := range hops { a, e := netip.ParseAddr(strings.TrimSpace(h)) if e != nil { return peer.String() } addresses[i] = a.Unmap() } current := peer for i := len(addresses) - 1; i >= 0 && isTrusted(current); i-- { current = addresses[i] } return current.String() }