// 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) }