Extract generic trusted proxy handling into xff/ (stdlib only), Echo framework adapter into xff/echo/, and slim xff/fastlyxff/ down to Fastly JSON loading. Key changes: - xff/ uses netip.Prefix for efficient IP matching - Fix XFF extraction to walk right-to-left per MDN spec - Remove echo dependency from core xff package - fastlyxff.New() now returns *xff.TrustedProxies
54 lines
1.3 KiB
Go
54 lines
1.3 KiB
Go
// Package fastlyxff loads Fastly CDN IP ranges and returns a generic
|
|
// [xff.TrustedProxies] for trusted proxy handling.
|
|
//
|
|
// Fastly publishes their edge server IP ranges in a JSON format:
|
|
//
|
|
// {
|
|
// "addresses": ["23.235.32.0/20", "43.249.72.0/22", ...],
|
|
// "ipv6_addresses": ["2a04:4e40::/32", "2a04:4e42::/32", ...]
|
|
// }
|
|
//
|
|
// # Usage
|
|
//
|
|
// tp, err := fastlyxff.New("fastly.json")
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// // Use tp.HTTPMiddleware(), tp.ExtractRealIP(r), etc.
|
|
// // For Echo framework, use the xff/echo package:
|
|
// // opts, err := xffecho.TrustOptions(tp)
|
|
package fastlyxff
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
|
|
"go.ntppool.org/common/xff"
|
|
)
|
|
|
|
// fastlyIPRanges matches the JSON format published by Fastly for their
|
|
// edge server IP ranges.
|
|
type fastlyIPRanges struct {
|
|
IPv4 []string `json:"addresses"`
|
|
IPv6 []string `json:"ipv6_addresses"`
|
|
}
|
|
|
|
// New loads Fastly IP ranges from a JSON file and returns a [xff.TrustedProxies].
|
|
func New(fileName string) (*xff.TrustedProxies, error) {
|
|
b, err := os.ReadFile(fileName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var ranges fastlyIPRanges
|
|
if err := json.Unmarshal(b, &ranges); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cidrs := make([]string, 0, len(ranges.IPv4)+len(ranges.IPv6))
|
|
cidrs = append(cidrs, ranges.IPv4...)
|
|
cidrs = append(cidrs, ranges.IPv6...)
|
|
|
|
return xff.NewFromCIDRs(cidrs)
|
|
}
|