mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-09-19 18:24:33 +00:00
40 lines
1.2 KiB
Go
40 lines
1.2 KiB
Go
// Copyright 2026 Beacon Contributors
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"net/netip"
|
|
)
|
|
|
|
// TrustedProxyIP accepts X-Real-IP only from a configured direct proxy peer.
|
|
// Run it before the access logger and handlers that use RemoteAddr as a key.
|
|
// All other forwarding headers are ignored, as are invalid/ambiguous values.
|
|
func TrustedProxyIP(proxies []netip.Prefix) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
peer, err := netip.ParseAddrPort(r.RemoteAddr)
|
|
if err == nil {
|
|
for _, proxy := range proxies {
|
|
if !proxy.Contains(peer.Addr().Unmap()) {
|
|
continue
|
|
}
|
|
if values := r.Header.Values("X-Real-IP"); len(values) == 1 {
|
|
if ip, err := netip.ParseAddr(values[0]); err == nil && ip.Zone() == "" {
|
|
r.RemoteAddr = ip.Unmap().String()
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
// Downstream client-IP keys must use the resolved RemoteAddr, not
|
|
// reinterpret forwarding headers (including those from trusted peers).
|
|
r.Header.Del("True-Client-IP")
|
|
r.Header.Del("X-Forwarded-For")
|
|
r.Header.Del("X-Real-IP")
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|